From 136fe58514b51962a04fbc6fdac9f4245f2aacd1 Mon Sep 17 00:00:00 2001 From: dbhart Date: Thu, 17 Aug 2023 14:37:28 -0600 Subject: [PATCH 01/75] initial creation of MSX reaction object The class will be similar to the WaterNetworkModel in terms of its structure and options. --- wntr/reaction/__init__.py | 13 + wntr/reaction/model.py | 1202 ++++++++++++++++++++++++++++++++++ wntr/tests/test_reactions.py | 135 ++++ 3 files changed, 1350 insertions(+) create mode 100644 wntr/reaction/__init__.py create mode 100644 wntr/reaction/model.py create mode 100644 wntr/tests/test_reactions.py diff --git a/wntr/reaction/__init__.py b/wntr/reaction/__init__.py new file mode 100644 index 000000000..3270c825f --- /dev/null +++ b/wntr/reaction/__init__.py @@ -0,0 +1,13 @@ +# -*- coding: utf-8 -*- +"""Contains definitions for water quality chemistry objects and reactions""" + +# Dependencies: +# pyomo.dae +# sympy + +from . import model +from . import io +from . import library +# from . import msx_toolkit +# from . import MSXPY_toolkit +# from . import msx_tools \ No newline at end of file diff --git a/wntr/reaction/model.py b/wntr/reaction/model.py new file mode 100644 index 000000000..912ee584e --- /dev/null +++ b/wntr/reaction/model.py @@ -0,0 +1,1202 @@ +# -*- coding: utf-8 -*- +""" +Water quality reactions base classes + +""" + +import logging +import warnings +from collections.abc import MutableMapping +from dataclasses import dataclass, field +from enum import Enum, IntFlag +from typing import Any, ClassVar, Dict, Hashable, Iterator, List, Set, Tuple, Union + +import sympy +from sympy import Float, Symbol, symbols +from sympy.parsing import parse_expr +from sympy.parsing.sympy_parser import standard_transformations, convert_xor + + +class VarType(IntFlag): + """The type of reaction variable""" + + Bulk = 1 + """A species that reacts with other bulk chemicals""" + Wall = 2 + """A species that reacts with the pipe walls""" + Constant = 4 + """A constant coefficient for use in a reaction expression""" + Parameter = 8 + """A coefficient that has a value dependent on the pipe or tank""" + Term = 16 + """A term that is aliased for ease of writing expressions""" + # Hydraulic = 32 + # """A hydraulic variable - users should not use this""" + + Species = Bulk | Wall + """A reaction species""" + Coeff = Constant | Parameter + """A reaction coefficient""" + + B = Bulk + W = Wall + C = Constant + P = Parameter + T = Term + # H = Hydraulic + # Hyd = Hydraulic + Const = Constant + Param = Parameter + + +class RxnLocation(Enum): + """What type of network component does this reaction occur in""" + + Pipes = 1 + """The expression describes a reaction in pipes""" + Tanks = 2 + """The expression describes a reaction in tanks""" + P = Pipes + T = Tanks + + +class ExprType(Enum): + """The type of reaction expression""" + + Equil = 1 + """An equilibrium reaction, where expression is RHS of: 0 = f(…,Cᵢ,…), {i | i=1..n}""" + Rate = 2 + """A decay rate equation, where expression is RHS of: ∂Cᵢ/∂t = f(…,Cᵢ,…), {i | i=1..n}""" + Formula = 3 + """A formula reaction, where expression is RHS of: Cᵢ = f(…,Cⱼ,…), {j | j=1..n, j≠i}""" + E = Equil + R = Rate + F = Formula + + +class WaterQualityReactionsModel: + """A registry of the reaction variables.""" + + RESERVED_NAMES = ("D", "Q", "U", "Re", "Us", "Ff", "Av", "E", "I", "pi") + """These (case sensitive) names are reserved for hydraulic variables and sympy + physical constants. Note that physical constants E, I, and pi are *not* valid MSX + variables - they are reserved symbols in sympy and so they should not be used + for variable names.""" + + def __init__(self): + self._variables: Dict[str, RxnVariable] = dict() + self._usage: Dict[str, Set[str]] = dict() + self._pipe_reactions: Dict[Hashable, RxnExpression] = dict() + self._tank_reactions: Dict[Hashable, RxnExpression] = dict() + for v in self.RESERVED_NAMES: + self._usage[v] = set() + + @property + def hydraulic_vars(self) -> Dict[str, str]: + """The following are the hydraulic variables usable within expressions and terms. + + D : pipe diameter (feet or meters) + Q : pipe flow rate (flow units) + U : pipe flow velocity (ft/s or m/s) + Re : flow Reynolds number + Us : pipe shear velocity (ft/s or m/s) + Ff : Darcy-Weisbach friction factor + Av : Surface area per unit volume (area-units/L) + """ + return { + "D": "pipe diameter (feet or meters)", + "Q": "pipe flow rate (flow units)", + "U": "pipe flow velocity (ft/s or m/s)", + "Re": "flow Reynolds number", + "Us": "pipe shear velocity (ft/s or m/s)", + "Ff": "Darcy-Weisbach friction factor", + "Av": "Surface area per unit volume (area-units/L)", + } + + def variables(self): + """Generator to iterate over all user defined variables (species, terms, etc). + + Yields + ------ + str, RxnVariable + name and object + + Raises + ------ + StopIteration + """ + for k, v in self._variables.items(): + yield k, v + raise StopIteration + + def species(self): + """Generator to iterate over all species. + + Yields + ------ + str, RxnSpecies + name and object + + Raises + ------ + StopIteration + """ + for k, v in self._variables.items(): + if isinstance(v, RxnSpecies): + yield k, v + raise StopIteration + + def coefficients(self): + """Generator to iterate over all coefficients. + + Yields + ------ + str, RxnCoefficient + name and object + + Raises + ------ + StopIteration + """ + for k, v in self._variables.items(): + if isinstance(v, RxnCoefficient): + yield k, v + raise StopIteration + + def terms(self): + """Generator to iterate over all terms. + + Yields + ------ + str, RxnTerm + name and object + + Raises + ------ + StopIteration + """ + for k, v in self._variables.items(): + if isinstance(v, RxnTerm): + yield k, v + raise StopIteration + + def reactions(self): + """Generator to iterate over all expressions. + + Yields + ------ + RxnExpression + reaction expression object + + Raises + ------ + StopIteration + """ + for v in self._pipe_reactions.values(): + yield v + for v in self._tank_reactions.values(): + yield v + raise StopIteration + + def pipe_reactions(self): + """Generator to iterate over all expressions. + + Yields + ------ + RxnExpression + reaction expression object + + Raises + ------ + StopIteration + """ + for v in self._pipe_reactions.values(): + yield v + raise StopIteration + + def tank_reactions(self): + """Generator to iterate over all expressions. + + Yields + ------ + RxnExpression + reaction expression object + + Raises + ------ + StopIteration + """ + for v in self._tank_reactions.values(): + yield v + raise StopIteration + + @property + def all_symbols(self) -> Set[sympy.Symbol]: + """Set of all symbols defined, including hydraulic variables""" + return set(symbols(" ".join(self._usage.keys()))) + + @property + def variable_names(self) -> Set[str]: + """Set of all user-defined symbols (excludes hydraulic variables)""" + return self._variables.keys() + + def add_variable(self, typ: Union[str, VarType], name: str, *args, note: str = None, **kwargs) -> "RxnVariable": + """Add a new variable to the Reactions object. + + Parameters + ---------- + typ : str or VarType + the type of variable + name : str + the name (symbol) for the variable + note : str, optional + a note or comment describing the variable, by default None + + Returns + ------- + RxnVariable + the new variable + + Raises + ------ + ValueError + - if name already exists, or + - missing or invalid value for :param:`typ` + """ + if name in self._variables.keys(): + raise ValueError("A variable named {} already exists: {}".format(name, self._variables[name])) + if not typ: + raise ValueError("Missing/invalid value for typ, got {}".format(typ)) + if isinstance(typ, str) and len(typ) > 0: + typ = typ[0].upper() + try: + typ = VarType[typ] + except KeyError as k: + raise ValueError("Missing/invalid value for typ, expected VarType but got {}".format(repr(typ))) from k + if typ & VarType.Species: + return self.add_species(typ, name, *args, note=note, **kwargs) + elif typ & VarType.Coeff: + return self.add_coefficient(typ, name, *args, note=note, **kwargs) + elif typ & VarType.Term: + return self.add_term(name, *args, note=note, **kwargs) + raise ValueError("Missing/invalid value for typ, got {}".format(typ)) + + def add_species(self, typ: Union[str, VarType], name: str, unit: str, Atol: float = None, Rtol: float = None, note: str = None) -> "RxnSpecies": + """Add a species to the Reactions object + + Parameters + ---------- + typ : Union[str, VarType] + _description_ + name : str + _description_ + unit : str + _description_ + Atol : float, optional + _description_, by default None + Rtol : float, optional + _description_, by default None + note : str, optional + _description_, by default None + + Returns + ------- + RxnSpecies + _description_ + + Raises + ------ + ValueError + - a variable with the :param:`name` already exists + - an incorrect value for :param:`typ` + """ + if name in self._variables.keys(): + raise ValueError("A variable named {} already exists: {}".format(name, self._variables[name])) + if isinstance(typ, str) and len(typ) > 0: + typ = typ[0].upper() + try: + typ = VarType[typ] + except KeyError as k: + raise ValueError("Missing/invalid value for typ, expected VarType but got {}".format(repr(typ))) from k + if typ & VarType.Bulk: + return self.add_bulk_species(name, unit, Atol, Rtol, note) + elif typ & VarType.Wall: + return self.add_wall_species(name, unit, Atol, Rtol, note) + else: + raise ValueError("typ must be a valid species type but got {}".format(typ)) + + def add_bulk_species(self, name: str, unit: str, Atol: float = None, Rtol: float = None, note: str = None) -> "BulkSpecies": + """_summary_ + + Parameters + ---------- + name : str + _description_ + unit : str + _description_ + Atol : float, optional + _description_, by default None + Rtol : float, optional + _description_, by default None + note : str, optional + _description_, by default None + + Returns + ------- + BulkSpecies + _description_ + + Raises + ------ + ValueError + a variable with the :param:`name` already exists + """ + if name in self._variables.keys(): + raise ValueError("A variable named {} already exists: {}".format(name, self._variables[name])) + new = BulkSpecies(name=name, unit=unit, Atol=Atol, Rtol=Rtol, note=note) + self._variables[name] = new + self._usage[name] = set() + return new + + def add_wall_species(self, name: str, unit: str, Atol: float = None, Rtol: float = None, note: str = None) -> "WallSpecies": + """_summary_ + + Parameters + ---------- + name : str + _description_ + unit : str + _description_ + Atol : float, optional + _description_, by default None + Rtol : float, optional + _description_, by default None + note : str, optional + _description_, by default None + + Returns + ------- + WallSpecies + _description_ + + Raises + ------ + ValueError + a variable with the :param:`name` already exists + """ + if name in self._variables.keys(): + raise ValueError("A variable named {} already exists: {}".format(name, self._variables[name])) + new = WallSpecies(name=name, unit=unit, Atol=Atol, Rtol=Rtol, note=note) + self._variables[name] = new + self._usage[name] = set() + return new + + def add_coefficient( + self, typ: Union[str, VarType], name: str, value: float, note: str = None, pipe_values: Dict[str, float] = None, tank_values: Dict[str, float] = None + ) -> "RxnCoefficient": + """_summary_ + + Parameters + ---------- + typ : Union[str, VarType] + _description_ + name : str + _description_ + value : float + _description_ + note : str, optional + _description_, by default None + pipe_values : Dict[str, float], optional + _description_, by default None + tank_values : Dict[str, float], optional + _description_, by default None + + Returns + ------- + RxnCoefficient + _description_ + + Raises + ------ + ValueError + - a variable with the :param:`name` already exists + - an incorrect value for :param:`typ` + TypeError + value(s) were passed for :param:`pipe_values` or :param:`tank_values` but the :param:`typ` is ``Constant`` + """ + if name in self._variables.keys(): + raise ValueError("A variable named {} already exists: {}".format(name, self._variables[name])) + if isinstance(typ, str) and len(typ) > 0: + typ = typ[0].upper() + try: + typ = VarType[typ] + except KeyError as k: + raise ValueError("Missing/invalid value for typ, expected VarType but got {}".format(repr(typ))) from k + if typ & VarType.Const: + if pipe_values is not None or tank_values is not None: + raise ValueError( + "pipe_values and tank_values must be None for constants but values for {}".format( + ("pipe_values" if pipe_values is not None else "") + + (" and " if pipe_values is not None and tank_values is not None else "") + + ("tank_values" if tank_values is not None else "") + ) + ) + return self.add_constant(name, value, note) + elif typ & VarType.Param: + return self.add_parameter(name, value, note, pipe_values, tank_values) + else: + raise ValueError("typ must be a valid coefficient type but got {}".format(typ)) + + def add_constant(self, name: str, value: float, note: str = None) -> "Constant": + """_summary_ + + Parameters + ---------- + name : str + _description_ + value : float + _description_ + note : str, optional + _description_, by default None + + Returns + ------- + Constant + _description_ + + Raises + ------ + ValueError + a variable with the :param:`name` already exists + """ + if name in self._variables.keys(): + raise ValueError("A variable named {} already exists: {}".format(name, self._variables[name])) + new = Constant(name=name, global_value=value, note=note) + self._variables[name] = new + self._usage[name] = set() + return new + + def add_parameter(self, name: str, value: float, note: str = None, pipe_values: Dict[str, float] = None, tank_values: Dict[str, float] = None) -> "Parameter": + """_summary_ + + Parameters + ---------- + name : str + _description_ + value : float + _description_ + note : str, optional + _description_, by default None + pipe_values : Dict[str, float], optional + _description_, by default None + tank_values : Dict[str, float], optional + _description_, by default None + + Returns + ------- + Parameter + _description_ + + Raises + ------ + ValueError + a variable with the :param:`name` already exists + """ + if name in self._variables.keys(): + raise ValueError("A variable named {} already exists: {}".format(name, self._variables[name])) + new = Parameter(name=name, global_value=value, note=note, pipe_values=pipe_values, tank_values=tank_values) + self._variables[name] = new + self._usage[name] = set() + return new + + def add_term(self, name: str, expr: str, note: str = None) -> "RxnTerm": + """_summary_ + + Parameters + ---------- + name : str + _description_ + expr : str + _description_ + note : str, optional + _description_, by default None + + Returns + ------- + RxnTerm + _description_ + + Raises + ------ + ValueError + a variable with the :param:`name` already exists + NameError + the term uses variable names that are undefined + """ + if name in self._variables.keys(): + raise ValueError("A variable named {} already exists: {}".format(name, self._variables[name])) + expr1 = sympy.parse_expr(expr) + used = expr1.free_symbols + undefined = used - self.all_symbols + if len(undefined) > 0: + raise NameError("Undefined symbol(s) {} in term {}".format(undefined, name)) + new = RxnTerm(name=name, expression=expr, note=note) + self._variables[name] = new + self._usage[name] = set() + for v in used: + self._usage[v].add(name) + return new + + def add_reaction(self, loc: Union[str, RxnLocation], typ: Union[str, ExprType], species: Union[str, 'RxnSpecies'], expression: str, note: str = None) -> "RxnExpression": + """Add a new reaction + + Parameters + ---------- + loc : str or RxnLocation + the location for the reaction: Pipe or Tank + typ : str or ExprType + the type of expression: Rate, Equilibrium or Formula + species : str or RxnSpecies + the species that is being described + expression : str + the actual mathematical expression + note : str, optional + any notes or comments, by default None + + Returns + ------- + RxnExpression + the new expression object + + Raises + ------ + ValueError + an incorrect/invalid value for :param:`loc` + """ + if not loc: + raise ValueError("A valid ExprLocationType must be specified for loc, but got {}".format(repr(loc))) + if isinstance(loc, str) and len(loc) > 0: + loc = loc[0].upper() + try: + loc = RxnLocation[loc] + except KeyError as k: + raise ValueError("Missing/unknown value for loc, expected ExprLocationType but got {}".format(loc)) from k + if loc is RxnLocation.Pipes: + return self.add_pipe_reaction(typ=typ, species=species, expression=expression, note=note) + elif loc is RxnLocation.Tanks: + return self.add_tank_reaction(typ=typ, species=species, expression=expression, note=note) + else: + raise ValueError("Missing/unknown value for loc, expected ExprLocationType but got {}".format(loc)) + + def add_pipe_reaction(self, typ: Union[str, ExprType], species: Union[str, 'RxnSpecies'], expression: str, note: str = None) -> "RxnExpression": + """Add a new pipe reaction to the model. + + Parameters + ---------- + typ : str or ExprType + the type of expression: Rate, Equilibrium or Formula + species : str + the species that is being described + expression : str + the actual mathematical expression + note : str, optional + any notes or comments, by default None + + Returns + ------- + RxnExpression + the new expression object + + Raises + ------ + ValueError + an incorrect/invalid value for :param:`typ` + """ + if species is not None: + species = str(species) + if not typ: + raise ValueError("A valid ExprType must be specified for typ, got {}".format(repr(typ))) + if isinstance(typ, str) and len(typ) > 0: + typ = typ[0].upper() + try: + typ = ExprType[typ] + except KeyError as k: + raise ValueError("Missing/unknown value for typ, expected ExprType but got {}".format(typ)) from k + if typ is ExprType.Equil: + new = Equilibrium(species=species, loc=RxnLocation.Pipes, expression=expression, note=note, _variables=self) + elif typ is ExprType.Rate: + new = Rate(species=species, loc=RxnLocation.Pipes, expression=expression, note=note, _variables=self) + elif typ is ExprType.Formula: + new = Formula(species=species, loc=RxnLocation.Pipes, expression=expression, note=note, _variables=self) + else: + raise ValueError("Unknown value for ExprType, got typ={}".format(typ)) + self._pipe_reactions[(typ.name, species)] = new + return new + + def add_tank_reaction(self, typ: Union[str, ExprType], species: Union[str, 'RxnSpecies'], expression: str, note: str = None) -> "RxnExpression": + """Add a new tank reaction to the model. + + Parameters + ---------- + typ : str or ExprType + the type of expression: Rate, Equilibrium or Formula + species : str + the species that is being described + expression : str + the actual mathematical expression + note : str, optional + any notes or comments, by default None + + Returns + ------- + RxnExpression + the new expression object + + Raises + ------ + ValueError + an incorrect/invalid value for :param:`typ` + """ + if species is not None: + species = str(species) + if not typ: + raise ValueError("A valid ExprType must be specified for typ, got {}".format(repr(typ))) + if isinstance(typ, str) and len(typ) > 0: + typ = typ[0].upper() + try: + typ = ExprType[typ] + except KeyError as k: + raise ValueError("Missing/unknown value for typ, expected ExprType but got {}".format(typ)) from k + if typ is ExprType.Equil: + new = Equilibrium(species=species, loc=RxnLocation.Tanks, expression=expression, note=note, _variables=self) + elif typ is ExprType.Rate: + new = Rate(species=species, loc=RxnLocation.Tanks, expression=expression, note=note, _variables=self) + elif typ is ExprType.Formula: + new = Formula(species=species, loc=RxnLocation.Tanks, expression=expression, note=note, _variables=self) + else: + raise ValueError("Unknown value for ExprType, got typ={}".format(typ)) + self._tank_reactions[(typ.name, species)] = new + return new + + def get_variable(self, name) -> "RxnVariable": + """Get a variable by name. + + Parameters + ---------- + name : str + the name of a defined variable + + Returns + ------- + RxnVariable + the variable requested + + Raises + ------ + KeyError + if a variable with that name does not exist + TypeError + if the variable is one of the :attr:`RESERVED_NAMES` that is not + an object + """ + if name in self.RESERVED_NAMES: + raise TypeError("You cannot request one of the hydraulic variables or reserved sympy names") + try: + return self._variables[name] + except KeyError as e: + raise KeyError("There is no such variable: {}. Remember that variables are case sensitive".format(name)) from e + + def get_reaction(self, loc, typ, species) -> "RxnExpression": + """_summary_ + + Parameters + ---------- + loc : str or RxnLocation + the location (pipe or tank) the reaction occurs + typ : str or ExprType + the type of reaction to get + species : str or RxnSpecies + the species to get the reaction for + + Returns + ------- + RxnExpression + the reaction expression object + + Raises + ------ + TypeError + :param:`loc`, :param:`typ` or :param:`species` is ``None`` + ValueError + - :param:`loc` or :param:`typ` is incorrect/invalid + - :param:`species` is undefined + KeyError + - the requested reaction expression is undefined + """ + if species is not None: + species = str(species) + if not species or species not in self._variables.keys(): + raise TypeError("A valid name must be specified for species, but got {}".format(species)) + if not loc: + raise TypeError("A valid RxnLocation must be specified for loc, but got {}".format(repr(loc))) + if not typ: + raise TypeError("A valid ExprType must be specified for typ, got {}".format(repr(typ))) + if species not in self._variables.keys(): + raise ValueError('Unknown species, {}'.format(species)) + if isinstance(loc, str) and len(loc) > 0: + loc = loc[0].upper() + try: + loc = RxnLocation[loc] + except KeyError as k: + raise ValueError("Missing/unknown value for loc, expected RxnLocation but got {}".format(loc)) from k + if isinstance(typ, str) and len(typ) > 0: + typ = typ[0].upper() + try: + typ = ExprType[typ] + except KeyError as k: + raise ValueError("Missing/unknown value for typ, expected ExprType but got {}".format(typ)) from k + if loc is RxnLocation.Pipes: + return self._pipe_reactions[(typ.name, species)] + elif loc is RxnLocation.Tanks: + return self._tank_reactions[(typ.name, species)] + else: + raise ValueError("Invalid RxnLocation specified, got {}".format(loc)) + + def get_reactions(self, loc: Union[str, RxnLocation] = None, typ: Union[str, ExprType] = None, species: Union[str, "RxnSpecies"] = None) -> List["RxnExpression"]: + """Get a subset of all reactions based on the criteria specified in the parameters (ANDed). + + Parameters + ---------- + loc : str or RxnLocation, optional + limit to pipe or tank reactions, by default None (both pipes and tanks) + typ : str or ExprType, optional + limit to rate, formula, or equilibrium reactions, by default None (all types) + species : str or RxnSpecies, optional + limit to a specific species, by default Non (all species) + + Returns + ------- + list of RxnExpression + reactions that match all the criteria specified + + Raises + ------ + ValueError + - invalid string passed in for :param:`loc` + - invalid string passed in for :param:`typ` + """ + if isinstance(loc, str) and len(loc) > 0: + loc = loc[0].upper() + try: + loc = RxnLocation[loc] + except KeyError as k: + raise ValueError("Missing/unknown value for loc, expected RxnLocation but got {}".format(loc)) from k + if isinstance(typ, str) and len(typ) > 0: + typ = typ[0].upper() + try: + typ = ExprType[typ] + except KeyError as k: + raise ValueError("Missing/unknown value for typ, expected ExprType but got {}".format(typ)) from k + if species is not None: + species = str(species) + reactions = list() + if loc is None or loc == RxnLocation.Pipes: + for k, v in self._pipe_reactions.items(): + if (k[0] == typ or typ is None) and (k[1] == species or species is None): + reactions.append(v) + if loc is None or loc == RxnLocation.Tanks: + for k, v in self._tank_reactions.items(): + if (k[0] == typ or typ is None) and (k[1] == species or species is None): + reactions.append(v) + return reactions + + +@dataclass +class RxnVariable: + """Any variable defined for use in a reaction expression""" + + name: str + """The name (symbol) of the variable""" + typ: ClassVar[VarType] + """The type of variable""" + value: ClassVar[Union[str, float]] + """The value of the variable, with type dependent on the type of variable""" + note = None + """A comment or note attached to the variable""" + + @property + def variable_type(self) -> VarType: + """The type of variable""" + return self.typ + + def get_symbol(self) -> sympy.Symbol: + """Get a sympy Symbol from the name""" + return symbols(self.name) + + def get_value(self, *, pipe=None, tank=None) -> Union[float, str]: + """Get the unit for a species, the value of a constant or parameter, or an expression for a term. + + Parameters + ---------- + pipe : str or Pipe, optional + a pipe or pipe name to use when getting the value, by default None + tank : str or Tank, optional + a tank or tank name to use when getting the value, by default None + + Returns + ------- + float or str + a float or string, depending on the type + + Raises + ------ + NotImplementedError + if a subclass does not implement this function + """ + raise NotImplementedError + + def __post_init__(self): + if self.name in WaterQualityReactionsModel.RESERVED_NAMES: + raise ValueError("the name {} is reserved for a built-in hydraulic variable".format(self.name)) + if not hasattr(self, 'typ'): + raise NotImplementedError('RxnVariable class cannot be instantiated directly') + if not isinstance(self.typ, VarType): + raise ValueError("expected VarType, got {}".format(type(self.typ))) + if self.typ is VarType.Species or self.typ is VarType.Coeff: + raise ValueError("generic {} type is inappropriate".format(self.typ)) + + def _get_tolerances(self) -> str: + return "" + + def to_msx_string(self) -> str: + """Convert to an EPANET-MSX input-file formatted line. + + Returns + ------- + str + the EPANET_MSX input-file formatted text + + Raises + ------ + TypeError + if the type is improper + """ + if self.typ & VarType.Species: + return "{} {} {} {} ;{}".format(self.typ.name.upper(), self.name, self.value, self._get_tolerances(), self.note if self.note else "") + elif self.typ & VarType.Coeff: + return "{} {} {} ;{}".format(self.typ.name.upper(), self.name, self.value, self.note if self.note else "") + elif self.typ & VarType.Term: + return "{} {} ;{}".format(self.name, self.value, self.note if self.note else "") + raise TypeError("typ must be a VarType but got {} - how did you do that???".format(type(self.typ))) + + def __str__(self): + return self.name + + +@dataclass +class RxnSpecies(RxnVariable): + """A water quality species, either biologic or chemical.""" + + unit: str + """The unit for this species' concentration""" + Atol: float = None + """The absolute tolerance to use when solving equations for this species""" + Rtol: float = None + """The relative tolerance to use when solving equations for this species""" + note: str = None + """A note regarding the species""" + + @property + def species_type(self) -> VarType: + """The type of species""" + raise NotImplementedError("subclass of RxnSpecies failed to implement species_type property") + + typ = species_type + + def __post_init__(self): + super().__post_init__() + if not (self.typ & VarType.Species): + raise ValueError("species must be Bulk or Wall type") + if (self.Atol is not None and self.Rtol is None) or (self.Atol is None and self.Rtol is not None): + raise ValueError("Atol and Rtol must both be None or both be > 0") + + @property + def _value(self): + return self.unit + + value = _value + + def get_value(self) -> str: + """Get the unit of the reaction species.""" + return self.value + + def _get_tolerances(self) -> str: + if self.Atol is not None: + return "{} {}".format(self.Atol, self.Rtol) + return "" + + def get_tolerances(self) -> Union[Tuple[float, float], None]: + """Get the tolerances for the species equations. + + Returns + ------- + (float, float) or None + the absolute and relative tolerance + """ + if self.Atol is not None: + return (self.Atol, self.Rtol,) + return None + + def set_tolerances(self, Atol: float, Rtol: float): + """Set the absolute and relative tolerances for the solver for this species. + + Parameters + ---------- + Atol : float + absolute tolerance for the solver + Rtol : float + relative tolerance for the solver + + Raises + ------ + ValueError + if either tolerance is less than or equal to zero + ValueError + if only one tolerance is set + """ + try: + if Atol is None and Rtol is None: + self.clear_tolerances() + elif Atol > 0 and Rtol > 0: + self.Atol = Atol + self.Rtol = Rtol + else: + raise ValueError("both Atol and Rtol must be greater than 0") + except TypeError as e: + raise TypeError("Atol and Rtol must both be None or both be positive real numbers") from e + + def clear_tolerances(self): + """Clear custom tolerances for the species""" + self.Atol = self.Rtol = None + + +class BulkSpecies(RxnSpecies): + """A bulk-reaction species""" + + @property + def species_type(self): + return VarType.Bulk + + typ = species_type + + +class WallSpecies(RxnSpecies): + """A wall-reaction species""" + + @property + def species_type(self): + return VarType.Wall + + typ = species_type + + +@dataclass +class RxnCoefficient(RxnVariable): + """A coefficient used in terms or reaction expressions""" + + global_value: float + """The global (default) value for this coefficient""" + note: str = None + """A note regarding this coefficient""" + pipe_values: Dict[str, float] = field(default_factory=dict, repr=False) + """Values for specific pipes""" + tank_values: Dict[str, float] = field(default_factory=dict, repr=False) + """Values for specific tanks""" + + @property + def coeff_type(self) -> VarType: + """The coefficient type, either constant or parameter. + + Returns + ------- + VarType + the type of coefficient + + Raises + ------ + NotImplementedError + if a subclass failed to overload this property + """ + raise NotImplementedError("subclass of RxnCoefficient failed to implement coeff_type property") + + typ = coeff_type + + @property + def _value(self): + return self.global_value + + value = _value + + def __post_init__(self): + super().__post_init__() + if not (self.typ & VarType.Coeff): + raise ValueError("coefficients must be Constant or Parameter type") + try: + self.global_value = float(self.global_value) + except ValueError as e: + raise ValueError("coefficients must have a real value but got {}".format(self.global_value)) from e + + def get_value(self, *, pipe=None, tank=None) -> str: + if pipe is not None and tank is not None: + raise ValueError("coefficients cannot have both pipe and tank specified") + if self.typ & VarType.Constant: + if pipe is not None or tank is not None: + warnings.warn('constants only have global values, returning the global value', RuntimeWarning) + return self.global_value + if pipe is not None: + return self.pipe_values.get(str(pipe), self.global_value) + else: + return self.tank_values.get(str(tank), self.global_value) + + +class Constant(RxnCoefficient): + """A constant coefficient""" + + def __post_init__(self): + if len(self.pipe_values) > 0 or len(self.tank_values) > 0: + warnings.warn('A Constant cannot have different values for specific pipes or tanks', category=RuntimeWarning) + self.pipe_values = None + self.tank_values = None + super().__post_init__() + + @property + def coeff_type(self): + return VarType.Constant + + typ = coeff_type + + +class Parameter(RxnCoefficient): + """A coefficient that has different values based on a pipe or tank""" + + @property + def coeff_type(self): + return VarType.Parameter + + typ = coeff_type + + +@dataclass +class RxnTerm(RxnVariable): + """An alias for a subexpression for easier use in a reaction expression""" + + expression: str + """A subexpression using species and coefficients""" + note: str = None + """A note or comment about this term""" + + @property + def variable_type(self): + return VarType.Term + + typ = variable_type + + @property + def _value(self): + return self.expression + + value = _value + + +@dataclass +class RxnExpression: + """A reaction expression""" + + species: str + """The species the expression applies to""" + loc: RxnLocation + """Does this reaction occur in pipes or tanks""" + typ: ClassVar[ExprType] + """The left-hand-side of the equation (the type of equation)""" + expression: str + """The right-hand-side of the equation (the expression itself)""" + note: str = None + """A note or comment regarding this expression""" + _variables: WaterQualityReactionsModel = None + """A link to the variable registry for evaluation""" + _transformations: ClassVar[Tuple] = standard_transformations + (convert_xor,) + """Expression transformations""" + + def link_variables(self, variables: WaterQualityReactionsModel): + if variables is not None: + self._variables = variables + self.validate() + + def validate(self): + """Validate the expression by checking variables are defined. + + Returns + ------- + sympy expression + _description_ + + Raises + ------ + ValueError + _description_ + RuntimeError + _description_ + """ + if self._variables is None: + raise ValueError("No variables have been linked to this RxnExpression") + expr = sympy.parse_expr(self.expression, transformations=self._transformations) + expr_vars = expr.free_symbols + missing = expr_vars - self._variables.all_symbols + if len(missing) > 0: + raise RuntimeError("Validation failed: the following symbols are undefined: {}".format(missing)) + return expr + + @property + def expression_type(self) -> ExprType: + """The type of expression""" + raise NotImplementedError("subclass of RxnExpression does not define the expression type") + + def to_msx_string(self) -> str: + """Get the expression as an EPANET-MSX input-file style string. + + Returns + ------- + str + the expression for use in an EPANET-MSX input file + """ + return "{} {} {} ;{}".format(self.typ.name.upper(), self.species, self.expression, self.note if self.note else "") + + +class Equilibrium(RxnExpression): + """An equilibrium expression, where the evaluated expression should equal 0.""" + + @property + def expression_type(self): + return ExprType.Equil + + typ = expression_type + + +class Rate(RxnExpression): + """A decay rate reaction, where the expression is the change in concentration per time for a specific species.""" + + @property + def expression_type(self): + return ExprType.Rate + + typ = expression_type + + +class Formula(RxnExpression): + """A formula for the concentration of a species based solely on the values of the other species.""" + + @property + def expression_type(self): + return ExprType.Formula + + typ = expression_type diff --git a/wntr/tests/test_reactions.py b/wntr/tests/test_reactions.py new file mode 100644 index 000000000..807599128 --- /dev/null +++ b/wntr/tests/test_reactions.py @@ -0,0 +1,135 @@ +import unittest +import warnings +from os.path import abspath, dirname, join + +import numpy as np +import pandas as pd +import wntr +import wntr.reaction +import sympy + +testdir = dirname(abspath(str(__file__))) +test_network_dir = join(testdir, "networks_for_testing") +test_data_dir = join(testdir, "data_for_testing") +ex_datadir = join(testdir, "..", "..", "examples", "networks") + +class Test(unittest.TestCase): + @classmethod + def setUpClass(self): + pass + + @classmethod + def tearDownClass(self): + pass + + def test_RxnVariable_reserved_name_exception(self): + self.assertRaises(ValueError, wntr.reaction.model.RxnVariable, 'I') + self.assertRaises(ValueError, wntr.reaction.model.RxnSpecies, 'Ff', 'mg') + self.assertRaises(ValueError, wntr.reaction.model.BulkSpecies, 'D', 'mg') + self.assertRaises(ValueError, wntr.reaction.model.WallSpecies, 'Q', 'mg') + self.assertRaises(ValueError, wntr.reaction.model.RxnCoefficient, 'Re', 0.52) + + def test_RxnVariable_direct_instantiation_exceptions(self): + self.assertRaises(NotImplementedError, wntr.reaction.model.RxnVariable, 'Test') + self.assertRaises(NotImplementedError, wntr.reaction.model.RxnSpecies, 'Test', 'mg/L') + self.assertRaises(NotImplementedError, wntr.reaction.model.RxnCoefficient, 'Test', 0.524) + + def test_RxnVariable_symbols_and_sympy(self): + species1 = wntr.reaction.model.BulkSpecies('Cl', 'mg') + symbol1 = sympy.symbols('Cl') + self.assertEqual(species1.get_symbol(), symbol1) + + const1 = wntr.reaction.model.Constant('Kb', 0.482) + symbol2 = sympy.symbols('Kb') + self.assertEqual(const1.get_symbol(), symbol2) + + def test_RxnVariable_values(self): + species1 = wntr.reaction.model.BulkSpecies('Cl', 'mg') + self.assertEqual(species1.get_value(), species1.value) + self.assertRaises(TypeError, species1.get_value, pipe='blah') + const1 = wntr.reaction.model.Constant('Kb', 0.482, note='test') + self.assertEqual(const1.get_value(), const1.value) + + def test_RxnVariable_string_functions(self): + species1 = wntr.reaction.model.BulkSpecies('Cl', 'mg') + self.assertEqual(str(species1), 'Cl') + self.assertEqual(species1.to_msx_string(), 'BULK Cl mg ;') + species2 = wntr.reaction.model.WallSpecies('Cl', 'mg', 0.01, 0.0001, note='Testing stuff') + self.assertEqual(species2.to_msx_string(), 'WALL Cl mg 0.01 0.0001 ;Testing stuff') + + def test_RxnSpecies_tolerances(self): + #"""RxnSpecies(*s) tolerance settings""" + species1 = wntr.reaction.model.BulkSpecies('Cl', 'mg') + species2 = wntr.reaction.model.WallSpecies('Cl', 'mg', 0.01, 0.0001, note='Testing stuff') + self.assertIsNone(species1.get_tolerances()) + self.assertIsNotNone(species2.get_tolerances()) + self.assertTupleEqual(species2.get_tolerances(), (0.01, 0.0001)) + self.assertRaises(TypeError, species1.set_tolerances, None, 0.0001) + self.assertRaises(ValueError, species1.set_tolerances, -0.51, 0.01) + self.assertRaises(ValueError, species1.set_tolerances, 0.0, 0.0) + species1.set_tolerances(0.01, 0.0001) + self.assertEqual(species1.Atol, 0.01) + self.assertEqual(species1.Rtol, 0.0001) + species1.set_tolerances(None, None) + self.assertIsNone(species1.Atol) + self.assertIsNone(species1.Rtol) + species2.clear_tolerances() + self.assertIsNone(species1.Atol) + self.assertIsNone(species1.Rtol) + self.assertIsNone(species2.get_tolerances()) + + def test_BulkSpecies_creation(self): + #"""BlukSpecies object creation (direct instantiation)""" + self.assertRaises(TypeError, wntr.reaction.model.BulkSpecies, 'I') + self.assertRaises(ValueError, wntr.reaction.model.BulkSpecies, 'I', 'mg') + self.assertRaises(ValueError, wntr.reaction.model.BulkSpecies, 'Cl', 'mg', 0.01) + self.assertRaises(ValueError, wntr.reaction.model.BulkSpecies, 'Cl', 'mg', None, 0.01) + species = wntr.reaction.model.BulkSpecies('Cl', 'mg') + self.assertEqual(species.name, 'Cl') + self.assertEqual(species.value, 'mg') + self.assertEqual(species.value, species.unit) + self.assertEqual(species.species_type, wntr.reaction.model.VarType.Bulk) + self.assertIsNone(species.Atol) + self.assertIsNone(species.Rtol) + self.assertIsNone(species.note) + species = wntr.reaction.model.BulkSpecies('Cl', 'mg', 0.01, 0.0001, note='Testing stuff') + self.assertEqual(species.variable_type, wntr.reaction.model.VarType.Bulk) + self.assertEqual(species.name, 'Cl') + self.assertEqual(species.value, 'mg') + self.assertEqual(species.Atol, 0.01) + self.assertEqual(species.Rtol, 0.0001) + self.assertEqual(species.note, 'Testing stuff') + + def test_WallSpecies_creation(self): + #"""WallSpecies object creation (direct instantiation)""" + self.assertRaises(TypeError, wntr.reaction.model.WallSpecies, 'I') + self.assertRaises(ValueError, wntr.reaction.model.WallSpecies, 'I', 'mg') + self.assertRaises(ValueError, wntr.reaction.model.WallSpecies, 'Cl', 'mg', 0.01) + self.assertRaises(ValueError, wntr.reaction.model.WallSpecies, 'Cl', 'mg', None, 0.01) + species = wntr.reaction.model.WallSpecies('Cl', 'mg') + self.assertEqual(species.name, 'Cl') + self.assertEqual(species.value, 'mg') + self.assertEqual(species.value, species.unit) + self.assertEqual(species.species_type, wntr.reaction.model.VarType.Wall) + self.assertIsNone(species.Atol) + self.assertIsNone(species.Rtol) + self.assertIsNone(species.note) + species = wntr.reaction.model.WallSpecies('Cl', 'mg', 0.01, 0.0001, note='Testing stuff') + self.assertEqual(species.variable_type, wntr.reaction.model.VarType.Wall) + self.assertEqual(species.name, 'Cl') + self.assertEqual(species.value, 'mg') + self.assertEqual(species.Atol, 0.01) + self.assertEqual(species.Rtol, 0.0001) + self.assertEqual(species.note, 'Testing stuff') + + def test_Constant_creation(self): + self.assertRaises(TypeError, wntr.reaction.model.Constant, 'Re') + self.assertRaises(ValueError, wntr.reaction.model.Constant, 'Re', 2.48) + const1 = wntr.reaction.model.Constant('Kb', 0.482, note='test') + # FIXME: Find a way to suppress warning printing + # self.assertWarns(RuntimeWarning, wntr.reaction.model.Constant, 'Kb1', 0.83, pipe_values={'a',1}) + self.assertEqual(const1.name, 'Kb') + self.assertEqual(const1.global_value, 0.482) + self.assertEqual(const1.value, const1.global_value) + self.assertEqual(const1.coeff_type, wntr.reaction.model.VarType.Constant) + self.assertEqual(const1.note, 'test') From 173e4b9ff88fd359e75d35b02fc6c3a43d49d89d Mon Sep 17 00:00:00 2001 From: dbhart Date: Fri, 18 Aug 2023 08:40:14 -0600 Subject: [PATCH 02/75] update requirements so that reactions test with sympy --- requirements.txt | 1 + wntr/reaction/model.py | 77 +++++++++++----- wntr/tests/test_reactions.py | 167 ++++++++++++++++++++++++++++++++++- 3 files changed, 224 insertions(+), 21 deletions(-) diff --git a/requirements.txt b/requirements.txt index 77fd539c5..ee2a94f43 100644 --- a/requirements.txt +++ b/requirements.txt @@ -12,6 +12,7 @@ utm openpyxl geopandas; sys_platform == "darwin" or sys_platform == "linux" rtree; sys_platform == "darwin" or sys_platform == "linux" +sympy # Documentation sphinx diff --git a/wntr/reaction/model.py b/wntr/reaction/model.py index 912ee584e..fc95b687d 100644 --- a/wntr/reaction/model.py +++ b/wntr/reaction/model.py @@ -7,7 +7,7 @@ import logging import warnings from collections.abc import MutableMapping -from dataclasses import dataclass, field +from dataclasses import InitVar, dataclass, field from enum import Enum, IntFlag from typing import Any, ClassVar, Dict, Hashable, Iterator, List, Set, Tuple, Union @@ -113,6 +113,11 @@ def hydraulic_vars(self) -> Dict[str, str]: "Av": "Surface area per unit volume (area-units/L)", } + @property + def vars(self): + """access to variables directly as keyed items""" + return self._variables + def variables(self): """Generator to iterate over all user defined variables (species, terms, etc). @@ -318,12 +323,12 @@ def add_species(self, typ: Union[str, VarType], name: str, unit: str, Atol: floa typ = VarType[typ] except KeyError as k: raise ValueError("Missing/invalid value for typ, expected VarType but got {}".format(repr(typ))) from k - if typ & VarType.Bulk: + if typ & VarType.Bulk and not typ is VarType.Species: return self.add_bulk_species(name, unit, Atol, Rtol, note) - elif typ & VarType.Wall: + elif typ & VarType.Wall and not typ is VarType.Species: return self.add_wall_species(name, unit, Atol, Rtol, note) else: - raise ValueError("typ must be a valid species type but got {}".format(typ)) + raise ValueError("typ must be a valid species subtype but got {}".format(typ)) def add_bulk_species(self, name: str, unit: str, Atol: float = None, Rtol: float = None, note: str = None) -> "BulkSpecies": """_summary_ @@ -432,7 +437,7 @@ def add_coefficient( typ = VarType[typ] except KeyError as k: raise ValueError("Missing/invalid value for typ, expected VarType but got {}".format(repr(typ))) from k - if typ & VarType.Const: + if typ & VarType.Const and not typ is VarType.Coeff: if pipe_values is not None or tank_values is not None: raise ValueError( "pipe_values and tank_values must be None for constants but values for {}".format( @@ -442,10 +447,10 @@ def add_coefficient( ) ) return self.add_constant(name, value, note) - elif typ & VarType.Param: + elif typ & VarType.Param and not typ is VarType.Coeff: return self.add_parameter(name, value, note, pipe_values, tank_values) else: - raise ValueError("typ must be a valid coefficient type but got {}".format(typ)) + raise ValueError("typ must be a valid coefficient subtype but got {}".format(typ)) def add_constant(self, name: str, value: float, note: str = None) -> "Constant": """_summary_ @@ -535,7 +540,7 @@ def add_term(self, name: str, expr: str, note: str = None) -> "RxnTerm": """ if name in self._variables.keys(): raise ValueError("A variable named {} already exists: {}".format(name, self._variables[name])) - expr1 = sympy.parse_expr(expr) + expr1 = sympy.parse_expr(expr, transformations=standard_transformations + (convert_xor,)) used = expr1.free_symbols undefined = used - self.all_symbols if len(undefined) > 0: @@ -544,7 +549,7 @@ def add_term(self, name: str, expr: str, note: str = None) -> "RxnTerm": self._variables[name] = new self._usage[name] = set() for v in used: - self._usage[v].add(name) + self._usage[str(v)].add(name) return new def add_reaction(self, loc: Union[str, RxnLocation], typ: Union[str, ExprType], species: Union[str, 'RxnSpecies'], expression: str, note: str = None) -> "RxnExpression": @@ -631,6 +636,10 @@ def add_pipe_reaction(self, typ: Union[str, ExprType], species: Union[str, 'RxnS else: raise ValueError("Unknown value for ExprType, got typ={}".format(typ)) self._pipe_reactions[(typ.name, species)] = new + expr = new.validate() + used = expr.free_symbols + for v in used: + self._usage[str(v)].add(('pipes', typ.name, species)) return new def add_tank_reaction(self, typ: Union[str, ExprType], species: Union[str, 'RxnSpecies'], expression: str, note: str = None) -> "RxnExpression": @@ -676,6 +685,10 @@ def add_tank_reaction(self, typ: Union[str, ExprType], species: Union[str, 'RxnS else: raise ValueError("Unknown value for ExprType, got typ={}".format(typ)) self._tank_reactions[(typ.name, species)] = new + expr = new.validate() + used = expr.free_symbols + for v in used: + self._usage[str(v)].add(('pipes', typ.name, species)) return new def get_variable(self, name) -> "RxnVariable": @@ -1008,9 +1021,9 @@ class RxnCoefficient(RxnVariable): """The global (default) value for this coefficient""" note: str = None """A note regarding this coefficient""" - pipe_values: Dict[str, float] = field(default_factory=dict, repr=False) + _pipe_values: Dict[str, float] = field(repr=False, init=False, default_factory=dict) """Values for specific pipes""" - tank_values: Dict[str, float] = field(default_factory=dict, repr=False) + _tank_values: Dict[str, float] = field(repr=False, init=False, default_factory=dict) """Values for specific tanks""" @property @@ -1061,13 +1074,6 @@ def get_value(self, *, pipe=None, tank=None) -> str: class Constant(RxnCoefficient): """A constant coefficient""" - - def __post_init__(self): - if len(self.pipe_values) > 0 or len(self.tank_values) > 0: - warnings.warn('A Constant cannot have different values for specific pipes or tanks', category=RuntimeWarning) - self.pipe_values = None - self.tank_values = None - super().__post_init__() @property def coeff_type(self): @@ -1075,10 +1081,34 @@ def coeff_type(self): typ = coeff_type - +@dataclass class Parameter(RxnCoefficient): """A coefficient that has different values based on a pipe or tank""" + pipe_values: InitVar[Dict[str, float]] = None + """Values for specific pipes""" + tank_values: InitVar[Dict[str, float]] = None + """Values for specific tanks""" + + def __post_init__(self, pipe_values_, tank_values_): + super().__post_init__() + if self._pipe_values is None: + self._pipe_values = dict() + if self._tank_values is None: + self._tank_values = dict() + if isinstance(pipe_values_, dict): + self._pipe_values.update(pipe_values_) + if isinstance(tank_values_ , dict): + self._tank_values.update(tank_values_) + + @property + def pipe_values(self): + return self._pipe_values + + @property + def tank_values(self): + return self._tank_values + @property def coeff_type(self): return VarType.Parameter @@ -1086,6 +1116,7 @@ def coeff_type(self): typ = coeff_type + @dataclass class RxnTerm(RxnVariable): """An alias for a subexpression for easier use in a reaction expression""" @@ -1122,11 +1153,17 @@ class RxnExpression: """The right-hand-side of the equation (the expression itself)""" note: str = None """A note or comment regarding this expression""" - _variables: WaterQualityReactionsModel = None + _variables: WaterQualityReactionsModel = field(compare=False, default=None) """A link to the variable registry for evaluation""" _transformations: ClassVar[Tuple] = standard_transformations + (convert_xor,) """Expression transformations""" + def __post_init__(self): + if not isinstance(self.loc, (RxnLocation, str)): + raise TypeError('loc must be a str or a RxnLocation') + if not isinstance(self.expression_type, ExprType): + raise TypeError('expression type must be an ExprType, got {}'.format(repr(self.expression_type))) + def link_variables(self, variables: WaterQualityReactionsModel): if variables is not None: self._variables = variables diff --git a/wntr/tests/test_reactions.py b/wntr/tests/test_reactions.py index 807599128..12c5df470 100644 --- a/wntr/tests/test_reactions.py +++ b/wntr/tests/test_reactions.py @@ -43,19 +43,47 @@ def test_RxnVariable_symbols_and_sympy(self): symbol2 = sympy.symbols('Kb') self.assertEqual(const1.get_symbol(), symbol2) + param1 = wntr.reaction.model.Constant('Ka', 0.482) + symbol3 = sympy.symbols('Ka') + self.assertEqual(param1.get_symbol(), symbol3) + + term1 = wntr.reaction.model.RxnTerm('T0', '-3.2 * Kb * Cl^2', note='bar') + symbol4 = sympy.symbols('T0') + self.assertEqual(term1.get_symbol(), symbol4) + + def test_RxnVariable_values(self): species1 = wntr.reaction.model.BulkSpecies('Cl', 'mg') self.assertEqual(species1.get_value(), species1.value) self.assertRaises(TypeError, species1.get_value, pipe='blah') const1 = wntr.reaction.model.Constant('Kb', 0.482, note='test') self.assertEqual(const1.get_value(), const1.value) + test_pipe_dict = {'PIPE': 0.38} + test_tank_dict = {'TANK': 222.23} + param2 = wntr.reaction.model.Parameter('Kb', 0.482, note='test', pipe_values=test_pipe_dict, tank_values=test_tank_dict) + self.assertEqual(param2.get_value(), param2.global_value) + self.assertEqual(param2.get_value(pipe='PIPE'), test_pipe_dict['PIPE']) + self.assertEqual(param2.get_value(pipe='FOO'), param2.global_value) + self.assertEqual(param2.get_value(tank='TANK'), test_tank_dict['TANK']) + self.assertRaises(ValueError, param2.get_value, pipe='PIPE', tank='TANK') + def test_RxnVariable_string_functions(self): species1 = wntr.reaction.model.BulkSpecies('Cl', 'mg') + species2 = wntr.reaction.model.WallSpecies('Cl', 'mg', 0.01, 0.0001, note='Testing stuff') + const1 = wntr.reaction.model.Constant('Kb', 0.482) + param1 = wntr.reaction.model.Parameter('Ka', 0.482, note='foo') + term1 = wntr.reaction.model.RxnTerm('T0', '-3.2 * Kb * Cl^2', note='bar') + self.assertEqual(str(species1), 'Cl') self.assertEqual(species1.to_msx_string(), 'BULK Cl mg ;') - species2 = wntr.reaction.model.WallSpecies('Cl', 'mg', 0.01, 0.0001, note='Testing stuff') self.assertEqual(species2.to_msx_string(), 'WALL Cl mg 0.01 0.0001 ;Testing stuff') + self.assertEqual(str(const1), 'Kb') + self.assertEqual(str(param1), 'Ka') + self.assertEqual(const1.to_msx_string(), 'CONSTANT Kb 0.482 ;') + self.assertEqual(param1.to_msx_string(), 'PARAMETER Ka 0.482 ;foo') + self.assertEqual(str(term1), 'T0') + self.assertEqual(term1.to_msx_string(), 'T0 -3.2 * Kb * Cl^2 ;bar') def test_RxnSpecies_tolerances(self): #"""RxnSpecies(*s) tolerance settings""" @@ -133,3 +161,140 @@ def test_Constant_creation(self): self.assertEqual(const1.value, const1.global_value) self.assertEqual(const1.coeff_type, wntr.reaction.model.VarType.Constant) self.assertEqual(const1.note, 'test') + + def test_Parameter_creation(self): + self.assertRaises(TypeError, wntr.reaction.model.Parameter, 'Re') + self.assertRaises(ValueError, wntr.reaction.model.Parameter, 'Re', 2.48) + param1 = wntr.reaction.model.Parameter('Kb', 0.482, note='test') + self.assertEqual(param1.name, 'Kb') + self.assertEqual(param1.global_value, 0.482) + self.assertEqual(param1.value, param1.global_value) + self.assertEqual(param1.coeff_type, wntr.reaction.model.VarType.Parameter) + self.assertEqual(param1.note, 'test') + test_pipe_dict = {'PIPE': 0.38} + test_tank_dict = {'TANK': 222.23} + param2 = wntr.reaction.model.Parameter('Kb', 0.482, note='test', pipe_values=test_pipe_dict, tank_values=test_tank_dict) + self.assertDictEqual(param2.pipe_values, test_pipe_dict) + self.assertDictEqual(param2.tank_values, test_tank_dict) + + def test_RxnTerm_creation(self): + self.assertRaises(TypeError, wntr.reaction.model.RxnTerm, 'Re') + self.assertRaises(ValueError, wntr.reaction.model.RxnTerm, 'Re', '1.0*Re') + term1 = wntr.reaction.model.RxnTerm('T0', '-3.2 * Kb * Cl^2', note='bar') + self.assertEqual(term1.name, 'T0') + self.assertEqual(term1.expression, '-3.2 * Kb * Cl^2') + self.assertEqual(term1.variable_type, wntr.reaction.model.VarType.Term) + self.assertEqual(term1.note, 'bar') + self.assertEqual(term1.value, term1.expression) + + def test_RxnExpression_direct_instantiation_exceptions(self): + self.assertRaises(TypeError, wntr.reaction.model.RxnExpression, 'Cl', wntr.reaction.model.RxnLocation.Pipes) + self.assertRaises(NotImplementedError, wntr.reaction.model.RxnExpression, 'Cl', wntr.reaction.model.RxnLocation.Pipes, '-Ka + Kb * Cl + T0') + self.assertRaises(TypeError, wntr.reaction.model.RxnExpression, 'Cl') + self.assertRaises(TypeError, wntr.reaction.model.RxnExpression, 'Cl', 39) + self.assertRaises(TypeError, wntr.reaction.model.RxnExpression, 'Cl', 39, '-Ka + Kb * Cl + T0') + + def test_RxnExpression_strings(self): + equil1 = wntr.reaction.model.Equilibrium( 'Cl', wntr.reaction.model.RxnLocation.Pipes, '-Ka + Kb * Cl + T0') + rate1 = wntr.reaction.model.Rate( 'Cl', wntr.reaction.model.RxnLocation.Tanks, '-Ka + Kb * Cl + T0', note='Foo Bar') + formula1 = wntr.reaction.model.Formula( 'Cl', wntr.reaction.model.RxnLocation.Pipes, '-Ka + Kb * Cl + T0') + self.assertEqual(equil1.to_msx_string(), 'EQUIL Cl -Ka + Kb * Cl + T0 ;') + self.assertEqual(rate1.to_msx_string(), 'RATE Cl -Ka + Kb * Cl + T0 ;Foo Bar') + self.assertEqual(formula1.to_msx_string(), 'FORMULA Cl -Ka + Kb * Cl + T0 ;') + + def test_Equilibrium_creation(self): + equil1 = wntr.reaction.model.Equilibrium( 'Cl', wntr.reaction.model.RxnLocation.Pipes, '-Ka + Kb * Cl + T0') + self.assertEqual(equil1.species, 'Cl') + self.assertEqual(equil1.expression, '-Ka + Kb * Cl + T0') + self.assertEqual(equil1.expression_type, wntr.reaction.model.ExprType.Equil) + + def test_Rate_creation(self): + rate1 = wntr.reaction.model.Rate( 'Cl', wntr.reaction.model.RxnLocation.Tanks, '-Ka + Kb * Cl + T0', note='Foo Bar') + self.assertEqual(rate1.species, 'Cl') + self.assertEqual(rate1.expression, '-Ka + Kb * Cl + T0') + self.assertEqual(rate1.expression_type, wntr.reaction.model.ExprType.Rate) + self.assertEqual(rate1.note, 'Foo Bar') + + def test_Formula_creation(self): + formula1 = wntr.reaction.model.Formula( 'Cl', wntr.reaction.model.RxnLocation.Pipes, '-Ka + Kb * Cl + T0') + self.assertEqual(formula1.species, 'Cl') + self.assertEqual(formula1.expression, '-Ka + Kb * Cl + T0') + self.assertEqual(formula1.expression_type, wntr.reaction.model.ExprType.Formula) + + def test_WaterQualityReactionsModel_creation_specific_everything(self): + rxn_model1 = wntr.reaction.model.WaterQualityReactionsModel() + bulk1 = wntr.reaction.model.BulkSpecies('Cl', 'mg') + wall1 = wntr.reaction.model.WallSpecies('ClOH', 'mg', 0.01, 0.0001, note='Testing stuff') + const1 = wntr.reaction.model.Constant('Kb', 0.482) + param1 = wntr.reaction.model.Parameter('Ka', 0.482, note='foo') + term1 = wntr.reaction.model.RxnTerm('T0', '-3.2 * Kb * Cl^2', note='bar') + equil1 = wntr.reaction.model.Equilibrium( 'Cl', wntr.reaction.model.RxnLocation.Pipes, '-Ka + Kb * Cl + T0') + rate1 = wntr.reaction.model.Rate( 'Cl', wntr.reaction.model.RxnLocation.Tanks, '-Ka + Kb * Cl + T0', note='Foo Bar') + formula1 = wntr.reaction.model.Formula( 'ClOH', wntr.reaction.model.RxnLocation.Pipes, '-Ka + Kb * Cl + T0') + + bulk2 = rxn_model1.add_bulk_species('Cl', 'mg') + wall2 = rxn_model1.add_wall_species('ClOH', 'mg', 0.01, 0.0001, note='Testing stuff') + const2 = rxn_model1.add_constant('Kb', 0.482) + param2 = rxn_model1.add_parameter('Ka', 0.482, note='foo') + term2 = rxn_model1.add_term('T0', '-3.2 * Kb * Cl^2', note='bar') + equil2 = rxn_model1.add_pipe_reaction('equil', 'Cl', '-Ka + Kb * Cl + T0') + rate2 = rxn_model1.add_tank_reaction(wntr.reaction.model.ExprType.Rate, 'Cl', '-Ka + Kb * Cl + T0', note='Foo Bar') + formula2 = rxn_model1.add_reaction('pipes', 'formula', 'ClOH', '-Ka + Kb * Cl + T0') + self.assertEqual(bulk1, bulk2) + self.assertEqual(wall1, wall2) + self.assertEqual(const1, const2) + self.assertEqual(param1, param2) + self.assertEqual(term1, term2) + self.assertEqual(equil1, equil2) + self.assertEqual(rate1, rate2) + self.assertEqual(formula1, formula2) + + def test_WaterQualityReactionsModel_creation_generic_species_coeffs(self): + bulk1 = wntr.reaction.model.BulkSpecies('Cl', 'mg') + wall1 = wntr.reaction.model.WallSpecies('ClOH', 'mg', 0.01, 0.0001, note='Testing stuff') + const1 = wntr.reaction.model.Constant('Kb', 0.482) + param1 = wntr.reaction.model.Parameter('Ka', 0.482, note='foo') + term1 = wntr.reaction.model.RxnTerm('T0', '-3.2 * Kb * Cl^2', note='bar') + + rxn_model2 = wntr.reaction.model.WaterQualityReactionsModel() + + self.assertRaises(ValueError, rxn_model2.add_species, wntr.reaction.model.VarType.Species, 'Cl', 'mg') + self.assertRaises(TypeError, rxn_model2.add_coefficient, None, 'Kb', 0.482) + self.assertRaises(ValueError, rxn_model2.add_coefficient, 'Wall', 'Kb', 0.482) + + bulk3 = rxn_model2.add_species('Bulk', 'Cl', 'mg') + wall3 = rxn_model2.add_species(wntr.reaction.model.VarType.Wall, 'ClOH', 'mg', 0.01, 0.0001, note='Testing stuff') + const3 = rxn_model2.add_coefficient('Consolation', 'Kb', 0.482) + param3 = rxn_model2.add_coefficient(wntr.reaction.model.VarType.P, 'Ka', 0.482, note='foo') + + self.assertEqual(bulk3, bulk1) + self.assertEqual(wall3, wall1) + self.assertEqual(const3, const1) + self.assertEqual(param3, param1) + + def test_WaterQualityReactionsModel_creation_generic_variables_reactions(self): + bulk1 = wntr.reaction.model.BulkSpecies('Cl', 'mg') + wall1 = wntr.reaction.model.WallSpecies('ClOH', 'mg', 0.01, 0.0001, note='Testing stuff') + const1 = wntr.reaction.model.Constant('Kb', 0.482) + param1 = wntr.reaction.model.Parameter('Ka', 0.482, note='foo') + term1 = wntr.reaction.model.RxnTerm('T0', '-3.2 * Kb * Cl^2', note='bar') + + rxn_model2 = wntr.reaction.model.WaterQualityReactionsModel() + + self.assertRaises(ValueError, rxn_model2.add_variable, wntr.reaction.model.VarType.Species, 'Cl', 'mg') + self.assertRaises(ValueError, rxn_model2.add_variable, None, 'Kb', 0.482) + + bulk3 = rxn_model2.add_variable('Bulk', 'Cl', 'mg') + wall3 = rxn_model2.add_variable(wntr.reaction.model.VarType.Wall, 'ClOH', 'mg', 0.01, 0.0001, note='Testing stuff') + const3 = rxn_model2.add_variable('Consolation', 'Kb', 0.482) + param3 = rxn_model2.add_variable(wntr.reaction.model.VarType.P, 'Ka', 0.482, note='foo') + term3 = rxn_model2.add_variable('tErM', 'T0', '-3.2 * Kb * Cl^2', note='bar') + + self.assertEqual(bulk3, bulk1) + self.assertEqual(wall3, wall1) + self.assertEqual(const3, const1) + self.assertEqual(param3, param1) + self.assertEqual(term3, term1) + +if __name__ == "__main__": + unittest.main(verbosity=2) From a47305d064c605b2cd48f4fb319c8cccdec9eba9 Mon Sep 17 00:00:00 2001 From: dbhart Date: Fri, 18 Aug 2023 08:47:44 -0600 Subject: [PATCH 03/75] Importing module before it existed, oops --- wntr/reaction/__init__.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/wntr/reaction/__init__.py b/wntr/reaction/__init__.py index 3270c825f..d57287b5a 100644 --- a/wntr/reaction/__init__.py +++ b/wntr/reaction/__init__.py @@ -6,8 +6,7 @@ # sympy from . import model -from . import io -from . import library +# from . import library # from . import msx_toolkit # from . import MSXPY_toolkit # from . import msx_tools \ No newline at end of file From 5431a8494a6fc20d2a08a3ed4b83a48a90674adf Mon Sep 17 00:00:00 2001 From: dbhart Date: Fri, 18 Aug 2023 09:07:26 -0600 Subject: [PATCH 04/75] Documentation updates --- wntr/reaction/model.py | 122 ++++++++++++++++++++--------------------- 1 file changed, 61 insertions(+), 61 deletions(-) diff --git a/wntr/reaction/model.py b/wntr/reaction/model.py index fc95b687d..4f6c749fa 100644 --- a/wntr/reaction/model.py +++ b/wntr/reaction/model.py @@ -64,11 +64,11 @@ class ExprType(Enum): """The type of reaction expression""" Equil = 1 - """An equilibrium reaction, where expression is RHS of: 0 = f(…,Cᵢ,…), {i | i=1..n}""" + """An equilibrium reaction, where expression is RHS of: 0 = f(…,Cᵢ,…), {species i | i=1..n}""" Rate = 2 - """A decay rate equation, where expression is RHS of: ∂Cᵢ/∂t = f(…,Cᵢ,…), {i | i=1..n}""" + """A decay rate equation, where expression is RHS of: ∂Cᵢ/∂t = f(…,Cᵢ,…), {species i | i=1..n} """ Formula = 3 - """A formula reaction, where expression is RHS of: Cᵢ = f(…,Cⱼ,…), {j | j=1..n, j≠i}""" + """A formula reaction, where expression is RHS of: Cᵢ = f(…,Cⱼ,…), {species i, j | j=1..n, j≠i}""" E = Equil R = Rate F = Formula @@ -291,23 +291,23 @@ def add_species(self, typ: Union[str, VarType], name: str, unit: str, Atol: floa Parameters ---------- - typ : Union[str, VarType] - _description_ + typ : str or VarType, {'Bulk', 'Wall'} + the type of species name : str - _description_ + the species name/expression symbol unit : str - _description_ + the unit for this species Atol : float, optional - _description_, by default None + the absolute solver tolerance, by default None Rtol : float, optional - _description_, by default None + the relative solver tolerance, by default None note : str, optional - _description_, by default None + comments about the species, by default None Returns ------- - RxnSpecies - _description_ + BulkSpecies or WallSpecies + a new species object Raises ------ @@ -331,25 +331,25 @@ def add_species(self, typ: Union[str, VarType], name: str, unit: str, Atol: floa raise ValueError("typ must be a valid species subtype but got {}".format(typ)) def add_bulk_species(self, name: str, unit: str, Atol: float = None, Rtol: float = None, note: str = None) -> "BulkSpecies": - """_summary_ + """Add a new bulk species to the reaction model Parameters ---------- name : str - _description_ + the species name/expression symbol unit : str - _description_ + the unit for this species Atol : float, optional - _description_, by default None + the absolute solver tolerance, by default None Rtol : float, optional - _description_, by default None + the relative solver tolerance, by default None note : str, optional - _description_, by default None + comments about the species, by default None Returns ------- BulkSpecies - _description_ + new species object Raises ------ @@ -364,25 +364,25 @@ def add_bulk_species(self, name: str, unit: str, Atol: float = None, Rtol: float return new def add_wall_species(self, name: str, unit: str, Atol: float = None, Rtol: float = None, note: str = None) -> "WallSpecies": - """_summary_ + """Add a new wall species to the model. Parameters ---------- name : str - _description_ + the species name/expression symbol unit : str - _description_ + the unit for this species Atol : float, optional - _description_, by default None + the absolute solver tolerance, by default None Rtol : float, optional - _description_, by default None + the relative solver tolerance, by default None note : str, optional - _description_, by default None + comments about the species, by default None Returns ------- WallSpecies - _description_ + new species object Raises ------ @@ -399,27 +399,27 @@ def add_wall_species(self, name: str, unit: str, Atol: float = None, Rtol: float def add_coefficient( self, typ: Union[str, VarType], name: str, value: float, note: str = None, pipe_values: Dict[str, float] = None, tank_values: Dict[str, float] = None ) -> "RxnCoefficient": - """_summary_ + """Add a new coefficient (constant or parameter) to the model. Parameters ---------- - typ : Union[str, VarType] - _description_ + typ : str or VarType, {'Constant', 'Parameter'} + the coefficient type name : str - _description_ - value : float - _description_ + the coefficient name (and expression symbol) + unit : str + the value of this coefficient note : str, optional - _description_, by default None - pipe_values : Dict[str, float], optional - _description_, by default None - tank_values : Dict[str, float], optional - _description_, by default None - + comments about the species, by default None + pipe_values : dict[str, float], optional + a (partial) dictionary of specific values for the coefficient based on pipe, be default None + tank_values : dict[str, float], optional + a (partial) dictionary of specific values for the coefficient based on tank, be default None + Returns ------- - RxnCoefficient - _description_ + Constant or Parameter + the new coefficient object Raises ------ @@ -453,21 +453,21 @@ def add_coefficient( raise ValueError("typ must be a valid coefficient subtype but got {}".format(typ)) def add_constant(self, name: str, value: float, note: str = None) -> "Constant": - """_summary_ + """Add a new constant coefficient to the model. Parameters ---------- name : str - _description_ - value : float - _description_ + the coefficient name (and expression symbol) + unit : str + the value of this coefficient note : str, optional - _description_, by default None + comments about the species, by default None Returns ------- Constant - _description_ + the new coefficient object Raises ------ @@ -482,25 +482,25 @@ def add_constant(self, name: str, value: float, note: str = None) -> "Constant": return new def add_parameter(self, name: str, value: float, note: str = None, pipe_values: Dict[str, float] = None, tank_values: Dict[str, float] = None) -> "Parameter": - """_summary_ + """A parameterized coefficient with a global value and additional values based on pipe or tank. Parameters ---------- name : str - _description_ - value : float - _description_ + the coefficient name (and expression symbol) + unit : str + the value of this coefficient note : str, optional - _description_, by default None - pipe_values : Dict[str, float], optional - _description_, by default None - tank_values : Dict[str, float], optional - _description_, by default None + comments about the species, by default None + pipe_values : dict[str, float], optional + a (partial) dictionary of specific values for the coefficient based on pipe, be default None + tank_values : dict[str, float], optional + a (partial) dictionary of specific values for the coefficient based on tank, be default None Returns ------- Parameter - _description_ + the new coefficient object Raises ------ @@ -515,21 +515,21 @@ def add_parameter(self, name: str, value: float, note: str = None, pipe_values: return new def add_term(self, name: str, expr: str, note: str = None) -> "RxnTerm": - """_summary_ + """A new shortcut term for use in equations. Parameters ---------- name : str - _description_ + the name and symbol for the term expr : str - _description_ + the expression note : str, optional - _description_, by default None + a comment or note about the term, by default None Returns ------- RxnTerm - _description_ + the new term object Raises ------ From 4ae43dbc9e99d061c199b8f151be054d5d0244f4 Mon Sep 17 00:00:00 2001 From: dbhart Date: Fri, 25 Aug 2023 12:20:30 -0600 Subject: [PATCH 05/75] Code updates for MSX utilities --- wntr/reaction/io.py | 31 + wntr/reaction/model.py | 1271 ++-------------------------------- wntr/reaction/options.py | 246 +++++++ wntr/reaction/toolkitmsx.py | 596 ++++++++++++++++ wntr/tests/test_reactions.py | 334 ++++----- 5 files changed, 1099 insertions(+), 1379 deletions(-) create mode 100644 wntr/reaction/io.py create mode 100644 wntr/reaction/options.py create mode 100644 wntr/reaction/toolkitmsx.py diff --git a/wntr/reaction/io.py b/wntr/reaction/io.py new file mode 100644 index 000000000..54e6a77a6 --- /dev/null +++ b/wntr/reaction/io.py @@ -0,0 +1,31 @@ +# coding: utf-8 + +import sys +import logging + +sys_default_enc = sys.getdefaultencoding() + + +logger = logging.getLogger(__name__) + + +class MsxFile(object): + + def __init__(self): + pass + + def read(self, msx_file, rxn_model=None): + pass + + def write(self, filename, rxn_model): + pass + + + +class MsxBinFile(object): + def __init__(self): + pass + + def read(self, filename): + pass + diff --git a/wntr/reaction/model.py b/wntr/reaction/model.py index 4f6c749fa..749053389 100644 --- a/wntr/reaction/model.py +++ b/wntr/reaction/model.py @@ -7,1233 +7,80 @@ import logging import warnings from collections.abc import MutableMapping -from dataclasses import InitVar, dataclass, field +from dataclasses import InitVar, dataclass, field, asdict from enum import Enum, IntFlag -from typing import Any, ClassVar, Dict, Hashable, Iterator, List, Set, Tuple, Union +from typing import Any, ClassVar, Dict, Generator, Hashable, Iterator, List, Set, Tuple, Union import sympy -from sympy import Float, Symbol, symbols +from sympy import Float, Symbol, symbols, init_printing from sympy.parsing import parse_expr from sympy.parsing.sympy_parser import standard_transformations, convert_xor +from wntr.network.model import WaterNetworkModel +from .base import ReactionDynamics, ReactionVariable +from .variables import InternalVariable +from .options import RxnOptions +from .base import DynamicsRegistry, VariableRegistry, RxnExprType, RxnLocType, RxnVarType, DisjointMapping, RESERVED_NAMES, SYMPY_RESERVED -class VarType(IntFlag): - """The type of reaction variable""" +class MultispeciesWaterQualityModel(DynamicsRegistry, VariableRegistry): - Bulk = 1 - """A species that reacts with other bulk chemicals""" - Wall = 2 - """A species that reacts with the pipe walls""" - Constant = 4 - """A constant coefficient for use in a reaction expression""" - Parameter = 8 - """A coefficient that has a value dependent on the pipe or tank""" - Term = 16 - """A term that is aliased for ease of writing expressions""" - # Hydraulic = 32 - # """A hydraulic variable - users should not use this""" + def __init__(self, title: str = None, desc: str = None, allow_sympy_reserved=False): + self.title: str = title + self.desc: str = desc + self.options = RxnOptions() + self._wn: WaterNetworkModel = None - Species = Bulk | Wall - """A reaction species""" - Coeff = Constant | Parameter - """A reaction coefficient""" + self._variables: Dict[str, ReactionVariable] = dict() + self._species = DisjointMapping(self._variables) + self._coeff = DisjointMapping(self._variables) + self._terms = DisjointMapping(self._variables) - B = Bulk - W = Wall - C = Constant - P = Parameter - T = Term - # H = Hydraulic - # Hyd = Hydraulic - Const = Constant - Param = Parameter + self._dynamics: Dict[str, ReactionDynamics] = dict() + self._pipe_dynamics = DisjointMapping(self._dynamics) + self._tank_dynamics = DisjointMapping(self._dynamics) + for name in RESERVED_NAMES: + self._variables[name] = InternalVariable(name) + if not allow_sympy_reserved: + for name in SYMPY_RESERVED: + self._variables[name] = InternalVariable(name) -class RxnLocation(Enum): - """What type of network component does this reaction occur in""" + def link_water_network_model(self, wn: WaterNetworkModel): + self._wn = wn - Pipes = 1 - """The expression describes a reaction in pipes""" - Tanks = 2 - """The expression describes a reaction in tanks""" - P = Pipes - T = Tanks - - -class ExprType(Enum): - """The type of reaction expression""" - - Equil = 1 - """An equilibrium reaction, where expression is RHS of: 0 = f(…,Cᵢ,…), {species i | i=1..n}""" - Rate = 2 - """A decay rate equation, where expression is RHS of: ∂Cᵢ/∂t = f(…,Cᵢ,…), {species i | i=1..n} """ - Formula = 3 - """A formula reaction, where expression is RHS of: Cᵢ = f(…,Cⱼ,…), {species i, j | j=1..n, j≠i}""" - E = Equil - R = Rate - F = Formula - - -class WaterQualityReactionsModel: - """A registry of the reaction variables.""" - - RESERVED_NAMES = ("D", "Q", "U", "Re", "Us", "Ff", "Av", "E", "I", "pi") - """These (case sensitive) names are reserved for hydraulic variables and sympy - physical constants. Note that physical constants E, I, and pi are *not* valid MSX - variables - they are reserved symbols in sympy and so they should not be used - for variable names.""" - - def __init__(self): - self._variables: Dict[str, RxnVariable] = dict() - self._usage: Dict[str, Set[str]] = dict() - self._pipe_reactions: Dict[Hashable, RxnExpression] = dict() - self._tank_reactions: Dict[Hashable, RxnExpression] = dict() - for v in self.RESERVED_NAMES: - self._usage[v] = set() - - @property - def hydraulic_vars(self) -> Dict[str, str]: - """The following are the hydraulic variables usable within expressions and terms. - - D : pipe diameter (feet or meters) - Q : pipe flow rate (flow units) - U : pipe flow velocity (ft/s or m/s) - Re : flow Reynolds number - Us : pipe shear velocity (ft/s or m/s) - Ff : Darcy-Weisbach friction factor - Av : Surface area per unit volume (area-units/L) - """ - return { - "D": "pipe diameter (feet or meters)", - "Q": "pipe flow rate (flow units)", - "U": "pipe flow velocity (ft/s or m/s)", - "Re": "flow Reynolds number", - "Us": "pipe shear velocity (ft/s or m/s)", - "Ff": "Darcy-Weisbach friction factor", - "Av": "Surface area per unit volume (area-units/L)", - } - - @property - def vars(self): - """access to variables directly as keyed items""" - return self._variables - - def variables(self): - """Generator to iterate over all user defined variables (species, terms, etc). - - Yields - ------ - str, RxnVariable - name and object - - Raises - ------ - StopIteration - """ + def variables(self, var_type=None): + var_type = RxnVarType.make(var_type) for k, v in self._variables.items(): + if var_type is not None and v.var_type != var_type: + continue yield k, v - raise StopIteration - - def species(self): - """Generator to iterate over all species. - - Yields - ------ - str, RxnSpecies - name and object - - Raises - ------ - StopIteration - """ - for k, v in self._variables.items(): - if isinstance(v, RxnSpecies): - yield k, v - raise StopIteration - - def coefficients(self): - """Generator to iterate over all coefficients. - - Yields - ------ - str, RxnCoefficient - name and object - - Raises - ------ - StopIteration - """ - for k, v in self._variables.items(): - if isinstance(v, RxnCoefficient): - yield k, v - raise StopIteration - - def terms(self): - """Generator to iterate over all terms. - - Yields - ------ - str, RxnTerm - name and object - - Raises - ------ - StopIteration - """ - for k, v in self._variables.items(): - if isinstance(v, RxnTerm): - yield k, v - raise StopIteration - - def reactions(self): - """Generator to iterate over all expressions. - - Yields - ------ - RxnExpression - reaction expression object - - Raises - ------ - StopIteration - """ - for v in self._pipe_reactions.values(): - yield v - for v in self._tank_reactions.values(): - yield v - raise StopIteration - - def pipe_reactions(self): - """Generator to iterate over all expressions. - - Yields - ------ - RxnExpression - reaction expression object - - Raises - ------ - StopIteration - """ - for v in self._pipe_reactions.values(): - yield v - raise StopIteration - - def tank_reactions(self): - """Generator to iterate over all expressions. - - Yields - ------ - RxnExpression - reaction expression object - - Raises - ------ - StopIteration - """ - for v in self._tank_reactions.values(): - yield v - raise StopIteration - - @property - def all_symbols(self) -> Set[sympy.Symbol]: - """Set of all symbols defined, including hydraulic variables""" - return set(symbols(" ".join(self._usage.keys()))) - - @property - def variable_names(self) -> Set[str]: - """Set of all user-defined symbols (excludes hydraulic variables)""" - return self._variables.keys() - - def add_variable(self, typ: Union[str, VarType], name: str, *args, note: str = None, **kwargs) -> "RxnVariable": - """Add a new variable to the Reactions object. - - Parameters - ---------- - typ : str or VarType - the type of variable - name : str - the name (symbol) for the variable - note : str, optional - a note or comment describing the variable, by default None - - Returns - ------- - RxnVariable - the new variable - - Raises - ------ - ValueError - - if name already exists, or - - missing or invalid value for :param:`typ` - """ - if name in self._variables.keys(): - raise ValueError("A variable named {} already exists: {}".format(name, self._variables[name])) - if not typ: - raise ValueError("Missing/invalid value for typ, got {}".format(typ)) - if isinstance(typ, str) and len(typ) > 0: - typ = typ[0].upper() - try: - typ = VarType[typ] - except KeyError as k: - raise ValueError("Missing/invalid value for typ, expected VarType but got {}".format(repr(typ))) from k - if typ & VarType.Species: - return self.add_species(typ, name, *args, note=note, **kwargs) - elif typ & VarType.Coeff: - return self.add_coefficient(typ, name, *args, note=note, **kwargs) - elif typ & VarType.Term: - return self.add_term(name, *args, note=note, **kwargs) - raise ValueError("Missing/invalid value for typ, got {}".format(typ)) - - def add_species(self, typ: Union[str, VarType], name: str, unit: str, Atol: float = None, Rtol: float = None, note: str = None) -> "RxnSpecies": - """Add a species to the Reactions object - - Parameters - ---------- - typ : str or VarType, {'Bulk', 'Wall'} - the type of species - name : str - the species name/expression symbol - unit : str - the unit for this species - Atol : float, optional - the absolute solver tolerance, by default None - Rtol : float, optional - the relative solver tolerance, by default None - note : str, optional - comments about the species, by default None - - Returns - ------- - BulkSpecies or WallSpecies - a new species object - - Raises - ------ - ValueError - - a variable with the :param:`name` already exists - - an incorrect value for :param:`typ` - """ - if name in self._variables.keys(): - raise ValueError("A variable named {} already exists: {}".format(name, self._variables[name])) - if isinstance(typ, str) and len(typ) > 0: - typ = typ[0].upper() - try: - typ = VarType[typ] - except KeyError as k: - raise ValueError("Missing/invalid value for typ, expected VarType but got {}".format(repr(typ))) from k - if typ & VarType.Bulk and not typ is VarType.Species: - return self.add_bulk_species(name, unit, Atol, Rtol, note) - elif typ & VarType.Wall and not typ is VarType.Species: - return self.add_wall_species(name, unit, Atol, Rtol, note) - else: - raise ValueError("typ must be a valid species subtype but got {}".format(typ)) - - def add_bulk_species(self, name: str, unit: str, Atol: float = None, Rtol: float = None, note: str = None) -> "BulkSpecies": - """Add a new bulk species to the reaction model - - Parameters - ---------- - name : str - the species name/expression symbol - unit : str - the unit for this species - Atol : float, optional - the absolute solver tolerance, by default None - Rtol : float, optional - the relative solver tolerance, by default None - note : str, optional - comments about the species, by default None - - Returns - ------- - BulkSpecies - new species object - - Raises - ------ - ValueError - a variable with the :param:`name` already exists - """ - if name in self._variables.keys(): - raise ValueError("A variable named {} already exists: {}".format(name, self._variables[name])) - new = BulkSpecies(name=name, unit=unit, Atol=Atol, Rtol=Rtol, note=note) - self._variables[name] = new - self._usage[name] = set() - return new - - def add_wall_species(self, name: str, unit: str, Atol: float = None, Rtol: float = None, note: str = None) -> "WallSpecies": - """Add a new wall species to the model. - - Parameters - ---------- - name : str - the species name/expression symbol - unit : str - the unit for this species - Atol : float, optional - the absolute solver tolerance, by default None - Rtol : float, optional - the relative solver tolerance, by default None - note : str, optional - comments about the species, by default None - - Returns - ------- - WallSpecies - new species object - - Raises - ------ - ValueError - a variable with the :param:`name` already exists - """ - if name in self._variables.keys(): - raise ValueError("A variable named {} already exists: {}".format(name, self._variables[name])) - new = WallSpecies(name=name, unit=unit, Atol=Atol, Rtol=Rtol, note=note) - self._variables[name] = new - self._usage[name] = set() - return new - - def add_coefficient( - self, typ: Union[str, VarType], name: str, value: float, note: str = None, pipe_values: Dict[str, float] = None, tank_values: Dict[str, float] = None - ) -> "RxnCoefficient": - """Add a new coefficient (constant or parameter) to the model. - - Parameters - ---------- - typ : str or VarType, {'Constant', 'Parameter'} - the coefficient type - name : str - the coefficient name (and expression symbol) - unit : str - the value of this coefficient - note : str, optional - comments about the species, by default None - pipe_values : dict[str, float], optional - a (partial) dictionary of specific values for the coefficient based on pipe, be default None - tank_values : dict[str, float], optional - a (partial) dictionary of specific values for the coefficient based on tank, be default None - - Returns - ------- - Constant or Parameter - the new coefficient object - - Raises - ------ - ValueError - - a variable with the :param:`name` already exists - - an incorrect value for :param:`typ` - TypeError - value(s) were passed for :param:`pipe_values` or :param:`tank_values` but the :param:`typ` is ``Constant`` - """ - if name in self._variables.keys(): - raise ValueError("A variable named {} already exists: {}".format(name, self._variables[name])) - if isinstance(typ, str) and len(typ) > 0: - typ = typ[0].upper() - try: - typ = VarType[typ] - except KeyError as k: - raise ValueError("Missing/invalid value for typ, expected VarType but got {}".format(repr(typ))) from k - if typ & VarType.Const and not typ is VarType.Coeff: - if pipe_values is not None or tank_values is not None: - raise ValueError( - "pipe_values and tank_values must be None for constants but values for {}".format( - ("pipe_values" if pipe_values is not None else "") - + (" and " if pipe_values is not None and tank_values is not None else "") - + ("tank_values" if tank_values is not None else "") - ) - ) - return self.add_constant(name, value, note) - elif typ & VarType.Param and not typ is VarType.Coeff: - return self.add_parameter(name, value, note, pipe_values, tank_values) - else: - raise ValueError("typ must be a valid coefficient subtype but got {}".format(typ)) - - def add_constant(self, name: str, value: float, note: str = None) -> "Constant": - """Add a new constant coefficient to the model. - - Parameters - ---------- - name : str - the coefficient name (and expression symbol) - unit : str - the value of this coefficient - note : str, optional - comments about the species, by default None - - Returns - ------- - Constant - the new coefficient object - - Raises - ------ - ValueError - a variable with the :param:`name` already exists - """ - if name in self._variables.keys(): - raise ValueError("A variable named {} already exists: {}".format(name, self._variables[name])) - new = Constant(name=name, global_value=value, note=note) - self._variables[name] = new - self._usage[name] = set() - return new - - def add_parameter(self, name: str, value: float, note: str = None, pipe_values: Dict[str, float] = None, tank_values: Dict[str, float] = None) -> "Parameter": - """A parameterized coefficient with a global value and additional values based on pipe or tank. - - Parameters - ---------- - name : str - the coefficient name (and expression symbol) - unit : str - the value of this coefficient - note : str, optional - comments about the species, by default None - pipe_values : dict[str, float], optional - a (partial) dictionary of specific values for the coefficient based on pipe, be default None - tank_values : dict[str, float], optional - a (partial) dictionary of specific values for the coefficient based on tank, be default None - - Returns - ------- - Parameter - the new coefficient object - - Raises - ------ - ValueError - a variable with the :param:`name` already exists - """ - if name in self._variables.keys(): - raise ValueError("A variable named {} already exists: {}".format(name, self._variables[name])) - new = Parameter(name=name, global_value=value, note=note, pipe_values=pipe_values, tank_values=tank_values) - self._variables[name] = new - self._usage[name] = set() - return new - - def add_term(self, name: str, expr: str, note: str = None) -> "RxnTerm": - """A new shortcut term for use in equations. - - Parameters - ---------- - name : str - the name and symbol for the term - expr : str - the expression - note : str, optional - a comment or note about the term, by default None - - Returns - ------- - RxnTerm - the new term object - - Raises - ------ - ValueError - a variable with the :param:`name` already exists - NameError - the term uses variable names that are undefined - """ - if name in self._variables.keys(): - raise ValueError("A variable named {} already exists: {}".format(name, self._variables[name])) - expr1 = sympy.parse_expr(expr, transformations=standard_transformations + (convert_xor,)) - used = expr1.free_symbols - undefined = used - self.all_symbols - if len(undefined) > 0: - raise NameError("Undefined symbol(s) {} in term {}".format(undefined, name)) - new = RxnTerm(name=name, expression=expr, note=note) - self._variables[name] = new - self._usage[name] = set() - for v in used: - self._usage[str(v)].add(name) - return new - - def add_reaction(self, loc: Union[str, RxnLocation], typ: Union[str, ExprType], species: Union[str, 'RxnSpecies'], expression: str, note: str = None) -> "RxnExpression": - """Add a new reaction - - Parameters - ---------- - loc : str or RxnLocation - the location for the reaction: Pipe or Tank - typ : str or ExprType - the type of expression: Rate, Equilibrium or Formula - species : str or RxnSpecies - the species that is being described - expression : str - the actual mathematical expression - note : str, optional - any notes or comments, by default None - - Returns - ------- - RxnExpression - the new expression object - - Raises - ------ - ValueError - an incorrect/invalid value for :param:`loc` - """ - if not loc: - raise ValueError("A valid ExprLocationType must be specified for loc, but got {}".format(repr(loc))) - if isinstance(loc, str) and len(loc) > 0: - loc = loc[0].upper() - try: - loc = RxnLocation[loc] - except KeyError as k: - raise ValueError("Missing/unknown value for loc, expected ExprLocationType but got {}".format(loc)) from k - if loc is RxnLocation.Pipes: - return self.add_pipe_reaction(typ=typ, species=species, expression=expression, note=note) - elif loc is RxnLocation.Tanks: - return self.add_tank_reaction(typ=typ, species=species, expression=expression, note=note) - else: - raise ValueError("Missing/unknown value for loc, expected ExprLocationType but got {}".format(loc)) - - def add_pipe_reaction(self, typ: Union[str, ExprType], species: Union[str, 'RxnSpecies'], expression: str, note: str = None) -> "RxnExpression": - """Add a new pipe reaction to the model. - - Parameters - ---------- - typ : str or ExprType - the type of expression: Rate, Equilibrium or Formula - species : str - the species that is being described - expression : str - the actual mathematical expression - note : str, optional - any notes or comments, by default None - - Returns - ------- - RxnExpression - the new expression object - - Raises - ------ - ValueError - an incorrect/invalid value for :param:`typ` - """ - if species is not None: - species = str(species) - if not typ: - raise ValueError("A valid ExprType must be specified for typ, got {}".format(repr(typ))) - if isinstance(typ, str) and len(typ) > 0: - typ = typ[0].upper() - try: - typ = ExprType[typ] - except KeyError as k: - raise ValueError("Missing/unknown value for typ, expected ExprType but got {}".format(typ)) from k - if typ is ExprType.Equil: - new = Equilibrium(species=species, loc=RxnLocation.Pipes, expression=expression, note=note, _variables=self) - elif typ is ExprType.Rate: - new = Rate(species=species, loc=RxnLocation.Pipes, expression=expression, note=note, _variables=self) - elif typ is ExprType.Formula: - new = Formula(species=species, loc=RxnLocation.Pipes, expression=expression, note=note, _variables=self) - else: - raise ValueError("Unknown value for ExprType, got typ={}".format(typ)) - self._pipe_reactions[(typ.name, species)] = new - expr = new.validate() - used = expr.free_symbols - for v in used: - self._usage[str(v)].add(('pipes', typ.name, species)) - return new - - def add_tank_reaction(self, typ: Union[str, ExprType], species: Union[str, 'RxnSpecies'], expression: str, note: str = None) -> "RxnExpression": - """Add a new tank reaction to the model. - - Parameters - ---------- - typ : str or ExprType - the type of expression: Rate, Equilibrium or Formula - species : str - the species that is being described - expression : str - the actual mathematical expression - note : str, optional - any notes or comments, by default None - - Returns - ------- - RxnExpression - the new expression object - - Raises - ------ - ValueError - an incorrect/invalid value for :param:`typ` - """ - if species is not None: - species = str(species) - if not typ: - raise ValueError("A valid ExprType must be specified for typ, got {}".format(repr(typ))) - if isinstance(typ, str) and len(typ) > 0: - typ = typ[0].upper() - try: - typ = ExprType[typ] - except KeyError as k: - raise ValueError("Missing/unknown value for typ, expected ExprType but got {}".format(typ)) from k - if typ is ExprType.Equil: - new = Equilibrium(species=species, loc=RxnLocation.Tanks, expression=expression, note=note, _variables=self) - elif typ is ExprType.Rate: - new = Rate(species=species, loc=RxnLocation.Tanks, expression=expression, note=note, _variables=self) - elif typ is ExprType.Formula: - new = Formula(species=species, loc=RxnLocation.Tanks, expression=expression, note=note, _variables=self) - else: - raise ValueError("Unknown value for ExprType, got typ={}".format(typ)) - self._tank_reactions[(typ.name, species)] = new - expr = new.validate() - used = expr.free_symbols - for v in used: - self._usage[str(v)].add(('pipes', typ.name, species)) - return new - - def get_variable(self, name) -> "RxnVariable": - """Get a variable by name. - - Parameters - ---------- - name : str - the name of a defined variable - - Returns - ------- - RxnVariable - the variable requested - - Raises - ------ - KeyError - if a variable with that name does not exist - TypeError - if the variable is one of the :attr:`RESERVED_NAMES` that is not - an object - """ - if name in self.RESERVED_NAMES: - raise TypeError("You cannot request one of the hydraulic variables or reserved sympy names") - try: - return self._variables[name] - except KeyError as e: - raise KeyError("There is no such variable: {}. Remember that variables are case sensitive".format(name)) from e - - def get_reaction(self, loc, typ, species) -> "RxnExpression": - """_summary_ - - Parameters - ---------- - loc : str or RxnLocation - the location (pipe or tank) the reaction occurs - typ : str or ExprType - the type of reaction to get - species : str or RxnSpecies - the species to get the reaction for - - Returns - ------- - RxnExpression - the reaction expression object - - Raises - ------ - TypeError - :param:`loc`, :param:`typ` or :param:`species` is ``None`` - ValueError - - :param:`loc` or :param:`typ` is incorrect/invalid - - :param:`species` is undefined - KeyError - - the requested reaction expression is undefined - """ - if species is not None: - species = str(species) - if not species or species not in self._variables.keys(): - raise TypeError("A valid name must be specified for species, but got {}".format(species)) - if not loc: - raise TypeError("A valid RxnLocation must be specified for loc, but got {}".format(repr(loc))) - if not typ: - raise TypeError("A valid ExprType must be specified for typ, got {}".format(repr(typ))) - if species not in self._variables.keys(): - raise ValueError('Unknown species, {}'.format(species)) - if isinstance(loc, str) and len(loc) > 0: - loc = loc[0].upper() - try: - loc = RxnLocation[loc] - except KeyError as k: - raise ValueError("Missing/unknown value for loc, expected RxnLocation but got {}".format(loc)) from k - if isinstance(typ, str) and len(typ) > 0: - typ = typ[0].upper() - try: - typ = ExprType[typ] - except KeyError as k: - raise ValueError("Missing/unknown value for typ, expected ExprType but got {}".format(typ)) from k - if loc is RxnLocation.Pipes: - return self._pipe_reactions[(typ.name, species)] - elif loc is RxnLocation.Tanks: - return self._tank_reactions[(typ.name, species)] - else: - raise ValueError("Invalid RxnLocation specified, got {}".format(loc)) - - def get_reactions(self, loc: Union[str, RxnLocation] = None, typ: Union[str, ExprType] = None, species: Union[str, "RxnSpecies"] = None) -> List["RxnExpression"]: - """Get a subset of all reactions based on the criteria specified in the parameters (ANDed). - - Parameters - ---------- - loc : str or RxnLocation, optional - limit to pipe or tank reactions, by default None (both pipes and tanks) - typ : str or ExprType, optional - limit to rate, formula, or equilibrium reactions, by default None (all types) - species : str or RxnSpecies, optional - limit to a specific species, by default Non (all species) - - Returns - ------- - list of RxnExpression - reactions that match all the criteria specified - - Raises - ------ - ValueError - - invalid string passed in for :param:`loc` - - invalid string passed in for :param:`typ` - """ - if isinstance(loc, str) and len(loc) > 0: - loc = loc[0].upper() - try: - loc = RxnLocation[loc] - except KeyError as k: - raise ValueError("Missing/unknown value for loc, expected RxnLocation but got {}".format(loc)) from k - if isinstance(typ, str) and len(typ) > 0: - typ = typ[0].upper() - try: - typ = ExprType[typ] - except KeyError as k: - raise ValueError("Missing/unknown value for typ, expected ExprType but got {}".format(typ)) from k - if species is not None: - species = str(species) - reactions = list() - if loc is None or loc == RxnLocation.Pipes: - for k, v in self._pipe_reactions.items(): - if (k[0] == typ or typ is None) and (k[1] == species or species is None): - reactions.append(v) - if loc is None or loc == RxnLocation.Tanks: - for k, v in self._tank_reactions.items(): - if (k[0] == typ or typ is None) and (k[1] == species or species is None): - reactions.append(v) - return reactions - -@dataclass -class RxnVariable: - """Any variable defined for use in a reaction expression""" - - name: str - """The name (symbol) of the variable""" - typ: ClassVar[VarType] - """The type of variable""" - value: ClassVar[Union[str, float]] - """The value of the variable, with type dependent on the type of variable""" - note = None - """A comment or note attached to the variable""" - - @property - def variable_type(self) -> VarType: - """The type of variable""" - return self.typ - - def get_symbol(self) -> sympy.Symbol: - """Get a sympy Symbol from the name""" - return symbols(self.name) - - def get_value(self, *, pipe=None, tank=None) -> Union[float, str]: - """Get the unit for a species, the value of a constant or parameter, or an expression for a term. - - Parameters - ---------- - pipe : str or Pipe, optional - a pipe or pipe name to use when getting the value, by default None - tank : str or Tank, optional - a tank or tank name to use when getting the value, by default None - - Returns - ------- - float or str - a float or string, depending on the type - - Raises - ------ - NotImplementedError - if a subclass does not implement this function - """ - raise NotImplementedError - - def __post_init__(self): - if self.name in WaterQualityReactionsModel.RESERVED_NAMES: - raise ValueError("the name {} is reserved for a built-in hydraulic variable".format(self.name)) - if not hasattr(self, 'typ'): - raise NotImplementedError('RxnVariable class cannot be instantiated directly') - if not isinstance(self.typ, VarType): - raise ValueError("expected VarType, got {}".format(type(self.typ))) - if self.typ is VarType.Species or self.typ is VarType.Coeff: - raise ValueError("generic {} type is inappropriate".format(self.typ)) - - def _get_tolerances(self) -> str: - return "" - - def to_msx_string(self) -> str: - """Convert to an EPANET-MSX input-file formatted line. - - Returns - ------- - str - the EPANET_MSX input-file formatted text - - Raises - ------ - TypeError - if the type is improper - """ - if self.typ & VarType.Species: - return "{} {} {} {} ;{}".format(self.typ.name.upper(), self.name, self.value, self._get_tolerances(), self.note if self.note else "") - elif self.typ & VarType.Coeff: - return "{} {} {} ;{}".format(self.typ.name.upper(), self.name, self.value, self.note if self.note else "") - elif self.typ & VarType.Term: - return "{} {} ;{}".format(self.name, self.value, self.note if self.note else "") - raise TypeError("typ must be a VarType but got {} - how did you do that???".format(type(self.typ))) - - def __str__(self): - return self.name - - -@dataclass -class RxnSpecies(RxnVariable): - """A water quality species, either biologic or chemical.""" - - unit: str - """The unit for this species' concentration""" - Atol: float = None - """The absolute tolerance to use when solving equations for this species""" - Rtol: float = None - """The relative tolerance to use when solving equations for this species""" - note: str = None - """A note regarding the species""" - - @property - def species_type(self) -> VarType: - """The type of species""" - raise NotImplementedError("subclass of RxnSpecies failed to implement species_type property") - - typ = species_type - - def __post_init__(self): - super().__post_init__() - if not (self.typ & VarType.Species): - raise ValueError("species must be Bulk or Wall type") - if (self.Atol is not None and self.Rtol is None) or (self.Atol is None and self.Rtol is not None): - raise ValueError("Atol and Rtol must both be None or both be > 0") - - @property - def _value(self): - return self.unit - - value = _value - - def get_value(self) -> str: - """Get the unit of the reaction species.""" - return self.value - - def _get_tolerances(self) -> str: - if self.Atol is not None: - return "{} {}".format(self.Atol, self.Rtol) - return "" - - def get_tolerances(self) -> Union[Tuple[float, float], None]: - """Get the tolerances for the species equations. - - Returns - ------- - (float, float) or None - the absolute and relative tolerance - """ - if self.Atol is not None: - return (self.Atol, self.Rtol,) - return None - - def set_tolerances(self, Atol: float, Rtol: float): - """Set the absolute and relative tolerances for the solver for this species. - - Parameters - ---------- - Atol : float - absolute tolerance for the solver - Rtol : float - relative tolerance for the solver - - Raises - ------ - ValueError - if either tolerance is less than or equal to zero - ValueError - if only one tolerance is set - """ - try: - if Atol is None and Rtol is None: - self.clear_tolerances() - elif Atol > 0 and Rtol > 0: - self.Atol = Atol - self.Rtol = Rtol - else: - raise ValueError("both Atol and Rtol must be greater than 0") - except TypeError as e: - raise TypeError("Atol and Rtol must both be None or both be positive real numbers") from e - - def clear_tolerances(self): - """Clear custom tolerances for the species""" - self.Atol = self.Rtol = None - - -class BulkSpecies(RxnSpecies): - """A bulk-reaction species""" - - @property - def species_type(self): - return VarType.Bulk - - typ = species_type - - -class WallSpecies(RxnSpecies): - """A wall-reaction species""" - - @property - def species_type(self): - return VarType.Wall - - typ = species_type - - -@dataclass -class RxnCoefficient(RxnVariable): - """A coefficient used in terms or reaction expressions""" - - global_value: float - """The global (default) value for this coefficient""" - note: str = None - """A note regarding this coefficient""" - _pipe_values: Dict[str, float] = field(repr=False, init=False, default_factory=dict) - """Values for specific pipes""" - _tank_values: Dict[str, float] = field(repr=False, init=False, default_factory=dict) - """Values for specific tanks""" - - @property - def coeff_type(self) -> VarType: - """The coefficient type, either constant or parameter. - - Returns - ------- - VarType - the type of coefficient - - Raises - ------ - NotImplementedError - if a subclass failed to overload this property - """ - raise NotImplementedError("subclass of RxnCoefficient failed to implement coeff_type property") - - typ = coeff_type - - @property - def _value(self): - return self.global_value - - value = _value - - def __post_init__(self): - super().__post_init__() - if not (self.typ & VarType.Coeff): - raise ValueError("coefficients must be Constant or Parameter type") - try: - self.global_value = float(self.global_value) - except ValueError as e: - raise ValueError("coefficients must have a real value but got {}".format(self.global_value)) from e - - def get_value(self, *, pipe=None, tank=None) -> str: - if pipe is not None and tank is not None: - raise ValueError("coefficients cannot have both pipe and tank specified") - if self.typ & VarType.Constant: - if pipe is not None or tank is not None: - warnings.warn('constants only have global values, returning the global value', RuntimeWarning) - return self.global_value - if pipe is not None: - return self.pipe_values.get(str(pipe), self.global_value) - else: - return self.tank_values.get(str(tank), self.global_value) - - -class Constant(RxnCoefficient): - """A constant coefficient""" + def dynamics(self, location=None): + location = RxnLocType.make(location) + for k, v in self._dynamics.items(): + if location is not None and v.location != location: + continue + yield k, v - @property - def coeff_type(self): - return VarType.Constant - - typ = coeff_type - -@dataclass -class Parameter(RxnCoefficient): - """A coefficient that has different values based on a pipe or tank""" - - pipe_values: InitVar[Dict[str, float]] = None - """Values for specific pipes""" - tank_values: InitVar[Dict[str, float]] = None - """Values for specific tanks""" - - def __post_init__(self, pipe_values_, tank_values_): - super().__post_init__() - if self._pipe_values is None: - self._pipe_values = dict() - if self._tank_values is None: - self._tank_values = dict() - if isinstance(pipe_values_, dict): - self._pipe_values.update(pipe_values_) - if isinstance(tank_values_ , dict): - self._tank_values.update(tank_values_) - - @property - def pipe_values(self): - return self._pipe_values + def add_dynamics(self, dyn: ReactionDynamics): + return super().add_dynamics(dyn) - @property - def tank_values(self): - return self._tank_values - - @property - def coeff_type(self): - return VarType.Parameter - - typ = coeff_type - - - -@dataclass -class RxnTerm(RxnVariable): - """An alias for a subexpression for easier use in a reaction expression""" - - expression: str - """A subexpression using species and coefficients""" - note: str = None - """A note or comment about this term""" - - @property - def variable_type(self): - return VarType.Term - - typ = variable_type - - @property - def _value(self): - return self.expression - - value = _value - - -@dataclass -class RxnExpression: - """A reaction expression""" - - species: str - """The species the expression applies to""" - loc: RxnLocation - """Does this reaction occur in pipes or tanks""" - typ: ClassVar[ExprType] - """The left-hand-side of the equation (the type of equation)""" - expression: str - """The right-hand-side of the equation (the expression itself)""" - note: str = None - """A note or comment regarding this expression""" - _variables: WaterQualityReactionsModel = field(compare=False, default=None) - """A link to the variable registry for evaluation""" - _transformations: ClassVar[Tuple] = standard_transformations + (convert_xor,) - """Expression transformations""" - - def __post_init__(self): - if not isinstance(self.loc, (RxnLocation, str)): - raise TypeError('loc must be a str or a RxnLocation') - if not isinstance(self.expression_type, ExprType): - raise TypeError('expression type must be an ExprType, got {}'.format(repr(self.expression_type))) - - def link_variables(self, variables: WaterQualityReactionsModel): - if variables is not None: - self._variables = variables - self.validate() - - def validate(self): - """Validate the expression by checking variables are defined. - - Returns - ------- - sympy expression - _description_ - - Raises - ------ - ValueError - _description_ - RuntimeError - _description_ - """ - if self._variables is None: - raise ValueError("No variables have been linked to this RxnExpression") - expr = sympy.parse_expr(self.expression, transformations=self._transformations) - expr_vars = expr.free_symbols - missing = expr_vars - self._variables.all_symbols - if len(missing) > 0: - raise RuntimeError("Validation failed: the following symbols are undefined: {}".format(missing)) - return expr - - @property - def expression_type(self) -> ExprType: - """The type of expression""" - raise NotImplementedError("subclass of RxnExpression does not define the expression type") - - def to_msx_string(self) -> str: - """Get the expression as an EPANET-MSX input-file style string. - - Returns - ------- - str - the expression for use in an EPANET-MSX input file - """ - return "{} {} {} ;{}".format(self.typ.name.upper(), self.species, self.expression, self.note if self.note else "") - - -class Equilibrium(RxnExpression): - """An equilibrium expression, where the evaluated expression should equal 0.""" - - @property - def expression_type(self): - return ExprType.Equil - - typ = expression_type - - -class Rate(RxnExpression): - """A decay rate reaction, where the expression is the change in concentration per time for a specific species.""" - - @property - def expression_type(self): - return ExprType.Rate - - typ = expression_type - - -class Formula(RxnExpression): - """A formula for the concentration of a species based solely on the values of the other species.""" - - @property - def expression_type(self): - return ExprType.Formula - - typ = expression_type + def add_variable(self, var: ReactionVariable): + return super().add_variable(var) + + def del_dynamics(self, species, location): + return super().del_dynamics(species, location) + + def del_variable(self, name: str): + return super().del_variable(name) + + def get_dynamics(self, species, location): + species = str(species) + location = RxnLocType.make(location) + if location == RxnLocType.PIPE: + return self._pipe_dynamics.get(species, None) + elif location == RxnLocType.TANK: + return self._tank_dynamics.get(species, None) + + def get_variable(self, name: str) -> ReactionVariable: + return self._variables[name] diff --git a/wntr/reaction/options.py b/wntr/reaction/options.py new file mode 100644 index 000000000..7a5393170 --- /dev/null +++ b/wntr/reaction/options.py @@ -0,0 +1,246 @@ +import re +import logging +import copy + +from wntr.network.options import _float_or_None, _int_or_None, _OptionsBase + +logger = logging.getLogger(__name__) + + +class TimeOptions(_OptionsBase): + """ + Options related to reaction simulation. + + Parameters + ---------- + timestep : int >= 1 + Water quality timestep (seconds), by default 60 (one minute). + + """ + + _pattern1 = re.compile(r"^(\d+):(\d+):(\d+)$") + _pattern2 = re.compile(r"^(\d+):(\d+)$") + _pattern3 = re.compile(r"^(\d+)$") + + def __init__( + self, + timestep: int = 60, + ): + self.timestep = timestep + + def __setattr__(self, name, value): + if name in {"timestep"}: + try: + value = max(1, int(value)) + except ValueError: + raise ValueError("%s must be an integer >= 1" % name) + elif name not in {"timestep"}: + raise AttributeError("%s is not a valid attribute in TimeOptions" % name) + self.__dict__[name] = value + + +class QualityOptions(_OptionsBase): + """ + Options related to water quality modeling. These options come from + the "[OPTIONS]" section of an EPANET-MSX input file. + + Parameters + ---------- + area_units : str, optional + The units of area to use in surface concentration forms, by default ``M2``. Valid values are ``FT2``, ``M2``, or ``CM2``. + + rate_units : str, optional + The timee units to use in rate reactions, by default ``MIN``. Valid values are ``SEC``, ``MIN``, ``HR``, or ``DAY``. + + solver : str, optional + The solver to use, by default ``RK5``. Options are ``RK5`` (5th order Runge-Kutta method), ``ROS2`` (2nd order Rosenbrock method), or ``EUL`` (Euler method). + + coupling : str, optional + Use coupling method for solution, by default ``NONE``. Valid options are ``FULL`` or ``NONE``. + + rtol : float, optional + Relative concentration tolerance, by default 1.0e-4. + + atol : float, optional + Absolute concentration tolerance, by default 1.0e-4. + + compiler : str, optional + Whether to use a compiler, by default ``NONE``. Valid options are ``VC``, ``GC``, or ``NONE`` + + segments : int, optional + Maximum number of segments per pipe (MSX 2.0 or newer only), by default 5000. + + peclet : int, optional + Peclet threshold for applying dispersion (MSX 2.0 or newer only), by default 1000. + """ + + def __init__( + self, + area_units: str = "M2", + rate_units: str = "MIN", + solver: str = "RK5", + coupling: str = "NONE", + rtol: float = 1.0e-4, + atol: float = 1.0e-4, + compiler: str = "", + segments: int = 5000, + peclet: int = 1000, + ): + self.area_units = area_units + self.rate_units = rate_units + self.solver = solver + self.coupling = coupling + self.rtol = rtol + self.atol = atol + self.compiler = compiler + self.segments = segments + self.peclet = peclet + + def __setattr__(self, name, value): + if name in ["atol", "rtol"]: + try: + value = float(value) + except ValueError: + raise ValueError("%s must be a number", name) + elif name in ["segments", "peclet"]: + try: + value = int(value) + except ValueError: + raise ValueError("%s must be a number", name) + elif name not in ["area_units", "rate_units", "solver", "coupling", "compiler"]: + raise AttributeError("%s is not a valid attribute of QualityOptions" % name) + self.__dict__[name] = value + + +class ReportOptions(_OptionsBase): + """ + Options related to EPANET report outputs. + The values in this options class *do not* affect the behavior of the WNTRSimulator. + These only affect what is written to an EPANET INP file and the results that are + in the EPANET-created report file. + + Parameters + ---------- + report_filename : str + Provides the filename to use for outputting an EPANET report file, + by default this will be the prefix plus ".rpt". + + status : str + Output solver status ("YES", "NO", "FULL"). "FULL" is only useful for debugging + + summary : str + Output summary information ("YES" or "NO") + + energy : str + Output energy information + + nodes : None, "ALL", or list + Output node information in report file. If a list of node names is provided, + EPANET only provides report information for those nodes. + + links : None, "ALL", or list + Output link information in report file. If a list of link names is provided, + EPANET only provides report information for those links. + + pagesize : str + Page size for EPANET report output + + + """ + + def __init__( + self, + pagesize: list = None, + report_filename: str = None, + species: dict = None, + species_precision: dict = None, + nodes: bool = False, + links: bool = False, + ): + self.pagesize = pagesize + self.report_filename = report_filename + self.species = species if species is not None else dict() + self.species_precision = species_precision if species_precision is not None else dict() + self.nodes = nodes + self.links = links + + def __setattr__(self, name, value): + if name not in ["pagesize", "report_filename", "species", "nodes", "links", "species_precision"]: + raise AttributeError("%s is not a valid attribute of ReportOptions" % name) + self.__dict__[name] = value + + +class UserOptions(_OptionsBase): + """ + Options defined by the user. + + Provides an empty class that accepts getattribute and setattribute methods to + create user-defined options. For example, if using WNTR for uncertainty + quantification, certain options could be added here that would never be + used directly by WNTR, but which would be saved on pickling and could be + used by the user-built analysis scripts. + + """ + + def __init__(self, **kwargs): + for k, v in kwargs.items(): + self.__dict__[k] = v + + +class RxnOptions(_OptionsBase): + """ + Water network model options class. + + These options mimic options in EPANET. + The `user` attribute is a generic python class object that allows for + dynamically created attributes that are user specific. + + Parameters + ---------- + title : str + The title to print in the .msx file + + time : TimeOptions + Contains all timing options for the scenarios + + quality : QualityOptions + Contains water quality simulation options and source definitions + + report : ReportOptions + Contains options for how for format and save report + + user : dict + An empty dictionary that allows for user specified options + + + """ + + def __init__(self, title: str = None, time: TimeOptions = None, report: ReportOptions = None, quality: QualityOptions = None, user: UserOptions = None): + self.title = (title,) + self.time = TimeOptions.factory(time) + self.report = ReportOptions.factory(report) + self.quality = QualityOptions.factory(quality) + self.user = UserOptions.factory(user) + + def __setattr__(self, name, value): + if name == "time": + if not isinstance(value, (TimeOptions, dict, tuple, list)): + raise ValueError("time must be a TimeOptions or convertable object") + value = TimeOptions.factory(value) + elif name == "report": + if not isinstance(value, (ReportOptions, dict, tuple, list)): + raise ValueError("report must be a ReportOptions or convertable object") + value = ReportOptions.factory(value) + elif name == "quality": + if not isinstance(value, (QualityOptions, dict, tuple, list)): + raise ValueError("quality must be a QualityOptions or convertable object") + value = QualityOptions.factory(value) + elif name == "user": + value = UserOptions.factory(value) + elif name not in ["title"]: + raise ValueError("%s is not a valid member of WaterNetworkModel") + self.__dict__[name] = value + + def to_dict(self): + """Dictionary representation of the options""" + return dict(self) diff --git a/wntr/reaction/toolkitmsx.py b/wntr/reaction/toolkitmsx.py new file mode 100644 index 000000000..4310f283f --- /dev/null +++ b/wntr/reaction/toolkitmsx.py @@ -0,0 +1,596 @@ +""" +The wntr.reaction.toolkit module is a Python extension for the EPANET MSX +Programmers Toolkit DLLs. +""" +import ctypes +import os +import os.path +import platform +import sys +from ctypes import byref +from ..epanet.toolkit import EpanetException, ENepanet +from ..epanet.util import SizeLimits +from pkg_resources import resource_filename + +epanet_toolkit = "wntr.epanet.toolkit" + +if os.name in ["nt", "dos"]: + libepanet = resource_filename(__name__, "Windows/epanet2.dll") + libmsx = resource_filename(__name__, "Windows/epanetmsx.dll") +elif sys.platform in ["darwin"]: + libepanet = resource_filename(__name__, "Darwin/libepanet.dylib") + libmsx = resource_filename(__name__, "Darwin/libepanetmsx.dylib") +else: + libepanet = resource_filename(__name__, "Linux/libepanet2.so") + libmsx = resource_filename(__name__, "Linux/libepanetmsx.so") + +import logging + +logger = logging.getLogger(__name__) + + +class EpanetMsxToolkitError(Exception): + ERROR_CODES = { + 101: "insufficient memory available.", + 102: "no network data available.", + 103: "hydraulics not initialized.", + 104: "no hydraulics for water quality analysis.", + 105: "water quality not initialized.", + 106: "no results saved to report on.", + 107: "hydraulics supplied from external file.", + 108: "cannot use external file while hydraulics solver is active.", + 109: "cannot change time parameter when solver is active.", + 110: "cannot solve network hydraulic equations.", + 120: "cannot solve water quality transport equations.", + 200: "Cannot read EPANET-MSX file.", + 201: "Syntax error", + 202: "Function call contains an illegal numeric value", + 203: "Function call refers to an undefined node", + 204: "Function call refers to an undefined link", + 205: "Function call refers to an undefined time pattern", + 206: "Function call refers to an undefined curve", + 207: "Function call attempts to control a check valve pipe or a GPV valve", + 208: "Function call contains illegal PDA pressure limits", + 209: "Function call contains an illegal node property value", + 211: "Function call contains an illegal link property value", + 212: "Function call refers to an undefined Trace Node", + 213: "Function call contains an invalid option value", + 214: "Too many characters in a line of an input file", + 215: "Function call contains a duplicate ID label", + 216: "Function call refers to an undefined pump", + 217: "Invalid pump energy data", + 219: "Illegal valve connection to tank node", + 220: "Illegal valve connection to another valve", + 221: "Mis-placed clause in rule-based control", + 222: "Link assigned same start and end nodes", + 223: "Not enough nodes in network", + 224: "No tanks or reservoirs in network", + 225: "Invalid lower/upper levels for tank", + 226: "No head curve or power rating for pump", + 227: "Invalid head curve for pump", + 230: "Nonincreasing x-values for curve", + 233: "Network has unconnected node", + 240: "Function call refers to nonexistent water quality source", + 241: "Function call refers to nonexistent control", + 250: "Function call contains invalid format (e.g. too long an ID name)", + 251: "Function call contains invalid parameter code", + 253: "Function call refers to nonexistent demand category", + 254: "Function call refers to node with no coordinates", + 257: "Function call refers to nonexistent rule", + 258: "Function call refers to nonexistent rule clause", + 259: "Function call attempts to delete a node that still has links connected to it", + 260: "Function call attempts to delete node assigned as a Trace Node", + 261: "Function call attempts to delete a node or link contained in a control", + 262: "Function call attempts to modify network structure while a solver is open", + 301: "Identical file names used for different types of files", + 302: "Cannot open input file", + 303: "Cannot open report file", + 304: "Cannot open output file", + 305: "Cannot open hydraulics file", + 306: "Hydraulics file does not match network data", + 307: "Cannot read hydraulics file", + 308: "Cannot save results to binary file", + 309: "Cannot save results to report file", + 501: "insufficient memory available.", + 502: "no EPANET data file supplied.", + 503: "could not open MSX input file.", + 504: "could not open hydraulic results file.", + 505: "could not read hydraulic results file.", + 506: "could not read MSX input file.", + 507: "too few pipe reaction expressions.", + 508: "too few tank reaction expressions.", + 509: "could not open differential equation solver.", + 510: "could not open algebraic equation solver.", + 511: "could not open binary results file.", + 512: "read/write on binary results file.", + 513: "could not integrate reaction rate expressions.", + 514: "could not solve reaction equilibrium expressions.", + 515: "reference made to an unknown type of object.", + 516: "reference made to an illegal object index.", + 517: "reference made to an undefined object ID.", + 518: "invalid property values were specified.", + 519: "an MSX project was not opened.", + 520: "an MSX project is already opened.", + 521: "could not open MSX report file.", + 522: "could not compile chemistry functions.", + 523: "could not load functions from compiled chemistry file.", + 524: "illegal math operation.", + } + + def __init__(self, code, *args: object) -> None: + msg = self.ERROR_CODES.get(code, "EPANET MSX error: {}".format(code)) + super().__init__(msg, *args) + + +class MSXepanet(ENepanet): + def __init__(self, inpfile="", rptfile="", binfile="", version=2.2): + + self.ENlib = None + self.errcode = 0 + self.errcodelist = [] + self.cur_time = 0 + + self.Warnflag = False + self.Errflag = False + self.fileLoaded = False + + self.inpfile = inpfile + self.rptfile = rptfile + self.binfile = binfile + + if float(version) == 2.0: + libnames = ["epanetmsx"] + if "64" in platform.machine(): + libnames.insert(0, "epanetmsx_amd64") + elif float(version) == 2.2: + libnames = ["epanetmsx", "epanetmsx_win32"] + if "64" in platform.machine(): + libnames.insert(0, "epanetmsx_amd64") + for lib in libnames: + try: + if os.name in ["nt", "dos"]: + libepanet = resource_filename(epanet_toolkit, "Windows/%s.dll" % lib) + self.ENlib = ctypes.windll.LoadLibrary(libepanet) + elif sys.platform in ["darwin"]: + libepanet = resource_filename(epanet_toolkit, "Darwin/lib%s.dylib" % lib) + self.ENlib = ctypes.cdll.LoadLibrary(libepanet) + else: + libepanet = resource_filename(epanet_toolkit, "Linux/lib%s.so" % lib) + self.ENlib = ctypes.cdll.LoadLibrary(libepanet) + return + except Exception as E1: + if lib == libnames[-1]: + raise E1 + pass + finally: + self._project = None + + return + + # ----------running the simulation----------------------------------------------------- + def MSXopen(self, nomeinp): + """Opens the MSX Toolkit to analyze a particular distribution system + Arguments: + nomeinp: name of the msx input file + """ + ierr = self.ENlib.MSXopen(ctypes.c_char_p(nomeinp.encode())) + if ierr != 0: + raise EpanetMsxToolkitError(ierr) + + def MSXclose( + self, + ): + """Closes down the Toolkit system (including all files being processed)""" + ierr = self.ENlib.MSXclose() + if ierr != 0: + raise EpanetMsxToolkitError(ierr) + + def MSXusehydfile(self, fname): + """Uses the contents of the specified file as the current binary hydraulics file""" + ierr = self.ENlib.MSXusehydfile(ctypes.c_char_p(fname.encode())) + if ierr != 0: + raise EpanetMsxToolkitError(ierr) + + def MSXsolveH( + self, + ): + """Runs a complete hydraulic simulation with results + for all time periods written to the binary Hydraulics file.""" + ierr = self.ENlib.MSXsolveH() + if ierr != 0: + raise EpanetMsxToolkitError(ierr) + + def MSXinit(self, saveFlag=0): + """Initializes the MSX system before solving for water quality results in step-wise fashion + set saveFlag to 1 if water quality results should be saved to a scratch binary file, or to 0 is not saved to file""" + ierr = self.ENlib.MSXinit(saveFlag) + if ierr != 0: + raise EpanetMsxToolkitError(ierr) + + def MSXsolveQ( + self, + ): + """solves for water quality over the entire simulation period and saves the results to an internal scratch file""" + ierr = self.ENlib.MSXsolveQ() + if ierr != 0: + raise EpanetMsxToolkitError(ierr) + + def MSXstep( + self, + ): + """Advances the water quality simulation one water quality time step. + The time remaining in the overall simulation is returned as tleft, the current time as t.""" + t = ctypes.c_long() + tleft = ctypes.c_long() + ierr = self.ENlib.MSXstep(ctypes.byref(t), ctypes.byref(tleft)) + if ierr != 0: + raise EpanetMsxToolkitError(ierr) + out = [t.value, tleft.value] + return out + + def MSXsaveoutfile(self, fname): + """saves water quality results computed for each node, link and reporting time period to a named binary file""" + ierr = self.ENlib.MSXsaveoutfile(ctypes.c_char_p(fname.encode())) + if ierr != 0: + raise EpanetMsxToolkitError(ierr) + + def MSXsavemsxfile(self, fname): + """saves the data associated with the current MSX project into a new MSX input file""" + ierr = self.ENlib.MSXsavemsxfile(ctypes.c_char_p(fname.encode())) + if ierr != 0: + raise EpanetMsxToolkitError(ierr) + + def MSXreport( + self, + ): + """Writes water quality simulations results as instructed by the MSX input file to a text file""" + ierr = self.ENlib.MSXreport() + if ierr != 0: + raise EpanetMsxToolkitError(ierr) + + # ---------get parameters--------------------------------------------------------------- + def MSXgetindex(self, type, name): + """Retrieves the internal index of an MSX object given its name. + Arguments: + type (int) + MSX_SPECIES - 3 (for a chemical species) + MSX_CONSTANT - 6 (for a reaction constant + MSX_PARAMETER - 5 (for a reaction parameter) + MSX_PATTERN - 7 (for a time pattern)""" + type_ind = 100 # in case the type input is in text + if type == "MSX_SPECIES" or type == 3: + type_ind = 3 + if type == "MSX_CONSTANT" or type == 6: + type_ind = 6 + if type == "MSX_PARAMETER" or type == 5: + type_ind = 5 + if type == "MSX_PATTERN" or type == 7: + type_ind = 7 + if type_ind == 100: + raise Exception("unrecognized type") + ind = ctypes.c_int() + ierr = self.ENlib.MSXgetindex(type_ind, ctypes.c_char_p(name.encode()), ctypes.byref(ind)) + if ierr != 0: + raise EpanetMsxToolkitError(ierr) + return ind.value + + def MSXgetIDlen(self, type, index): + """Retrieves the number of characters in the ID name of an MSX object given its internal index number. + Arguments: + type - int: + MSX_SPECIES - 3 (for a chemical species) + MSX_CONSTANT - 6 (for a reaction constant + MSX_PARAMETER - 5 (for a reaction parameter) + MSX_PATTERN - 7 (for a time pattern)""" + type_ind = 100 # in case the type input is in text + if type == "MSX_SPECIES" or type == 3: + type_ind = 3 + if type == "MSX_CONSTANT" or type == 6: + type_ind = 6 + if type == "MSX_PARAMETER" or type == 5: + type_ind = 5 + if type == "MSX_PATTERN" or type == 7: + type_ind = 7 + if type_ind == 100: + raise Exception("unrecognized type") + len = ctypes.c_int() + ierr = self.ENlib.MSXgetIDlen(type_ind, ctypes.c_int(index), ctypes.byref(len)) + if ierr != 0: + raise EpanetMsxToolkitError(ierr) + return len.value + + def MSXgetID(self, type, index): + """Retrieves the ID name of an object given its internal index number + Arguments: + type: + MSX_SPECIES - 3 (for a chemical species) + MSX_CONSTANT - 6 (for a reaction constant + MSX_PARAMETER - 5 (for a reaction parameter) + MSX_PATTERN - 7 (for a time pattern) + maxlen: maxi number of characters that id can hold not counting null termination character""" + type_ind = 100 # in case the type input is in text + if type == "MSX_SPECIES" or type == 3: + type_ind = 3 + if type == "MSX_CONSTANT" or type == 6: + type_ind = 6 + if type == "MSX_PARAMETER" or type == 5: + type_ind = 5 + if type == "MSX_PATTERN" or type == 7: + type_ind = 7 + if type_ind == 100: + raise Exception("unrecognized type") + maxlen = 32 + id = ctypes.create_string_buffer(maxlen) + ierr = self.ENlib.MSXgetID(type_ind, ctypes.c_int(index), ctypes.byref(id), ctypes.c_int(maxlen - 1)) + if ierr != 0: + raise EpanetMsxToolkitError(ierr) + # the .decode() added my MF 6/3/21 + return id.value.decode() + + def MSXgetinitqual(self, type, ind, spe): + """Retrieves the initial concentration of a particular chemical species assigned to a specific node + or link of the pipe network. + Arguments: + type is type of object: MSX_NODE (0), MSX_LINK (1) + ind is the internal sequence number (starting from 1) assigned to the node or link + speicies is the sequence number of teh species (starting from 1)""" + type_ind = 100 + if type == "MSX_NODE" or type == 0: + type_ind = 0 + if type == "MSX_LINK" or type == 1: + type_ind = 1 + if type_ind == 100: + raise Exception("unrecognized type") + iniqual = ctypes.c_double() + ierr = self.ENlib.MSXgetinitqual(ctypes.c_int(type_ind), ctypes.c_int(ind), ctypes.c_int(spe), ctypes.byref(iniqual)) + if ierr != 0: + raise EpanetMsxToolkitError(ierr) + return iniqual.value + + def MSXgetqual(self, type, ind, spe): + """Retrieves a chemical species concentration at a given node or the average concentration along a link at the current simulation time step + Arguments: + type is type of object: MSX_NODE (0), MSX_LINK (1) + ind is the internal sequence number (starting from 1) assigned to the node or link + speicies is the sequence number of teh species (starting from 1) + concentrations expressed as: mass units per liter for bulk species and mass per unit area for surface species""" + type_ind = 100 + if type == "MSX_NODE" or type == 0: + type_ind = 0 + if type == "MSX_LINK" or type == 1: + type_ind = 1 + if type_ind == 100: + raise Exception("unrecognized type") + qual = ctypes.c_double() + ierr = self.ENlib.MSXgetqual(ctypes.c_int(type_ind), ctypes.c_int(ind), ctypes.c_int(spe), ctypes.byref(qual)) + if ierr != 0: + raise EpanetMsxToolkitError(ierr) + return qual.value + + def MSXgetconstant(self, ind): + """Retrieves the value of a particular reaction constant + Arguments: + ind is the sequence number of the reaction constant (starting from 1) as it appeared in the MSX input file""" + const = ctypes.c_double() + ierr = self.ENlib.MSXgetconstant(ind, ctypes.byref(const)) + if ierr != 0: + raise EpanetMsxToolkitError(ierr) + return const.value + + def MSXgetparameter(self, type, ind, param_ind): + """Retrieves the value of a particular reaction parameter for a give TANK or PIPE + Arguments: + type is the type of object: MSX_NODE (0) or MSX_LINK (1) + ind is the internal sequence number(starting from 1) assigned to the node or link + param is the sequence number of the parameter (starting from 1 as listed in the MSX input file)""" + type_ind = 100 # in case type input is in text + if type == "MSX_NODE" or type == 0: + type_ind = 0 + if type == "MSX_LINK" or type == 1: + type_ind = 1 + if type_ind == 100: + raise Exception("unrecognized type") + param = ctypes.c_double() + ierr = self.ENlib.MSXgetparameter(ctypes.c_int(type_ind), ctypes.c_int(ind), ctypes.c_int(param_ind), ctypes.byref(param)) + if ierr != 0: + raise EpanetMsxToolkitError(ierr) + return param.value + + def MSXgetsource(self, node, spe): + """Retrieves information on any external source of a particular chemical species assigned to a specific node of the pipe network + Arguments: + node is the internal sequence number (starting from 1) assigned to the node of interest + species is the sequence number of the species of interest (starting from 1 as listed in the MSX input file) + type is returned with the type of external source and will be one of the following pre-defined constants + MSX_NOSOURCE (-1) no source; MSX_CONCEN (0) a concentration source; MSX_MASS (1) mass booster source; + MSX_SETPOINT (2) setpoint source; MSX_FLOWPACED (3) flow paced source + level is returned with the baseline concentration (or mass flow rate) of the source + pat is returned with the index of the time pattern used to add variability to the source's baseline level (0 if no pattern defined for the source)""" + level = ctypes.c_double() + type = ctypes.c_int() + pat = ctypes.c_int() + ierr = self.ENlib.MSXgetsource(ctypes.c_int(node), ctypes.c_int(spe), ctypes.byref(type), ctypes.byref(level), ctypes.byref(pat)) + if ierr != 0: + raise EpanetMsxToolkitError(ierr) + src_out = [type.value, level.value, pat.value] + return src_out + + def MSXgetpatternlen(self, pat): + """Retrieves the number of time periods within a SOURCE time pattern + Arguments: + pat is the internal sequence number (starting from 1) of the pattern as appears in the MSX input file""" + len = ctypes.c_int() + ierr = self.ENlib.MSXgetpatternlen(pat, ctypes.byref(len)) + if ierr != 0: + raise EpanetMsxToolkitError(ierr) + return len.value + + def MSXgetpatternvalue(self, pat, period): + """Retrieves the multiplier at a specific time period for a given SOURCE time pattern + Arguments: + pat is the internal sequence number (starting from 1) of the pattern as appears in the MSX input file + period is the index of the time period (starting from 1) whose multiplier is being sought + value is the vlaue of teh pattern's multiplier in teh desired period""" + val = ctypes.c_double() + ierr = self.ENlib.MSXgetpatternvalue(pat, period, ctypes.byref(val)) + if ierr != 0: + raise EpanetMsxToolkitError(ierr) + return val.value + + def MSXgetcount(self, type): + """Retrieves the number of objects of a specified type. + Arguments: + MSX_SPECIES - 3 (for a chemical species) + MSX_CONSTANT - 6 (for a reaction constant + MSX_PARAMETER - 5 (for a reaction parameter) + MSX_PATTERN - 7 (for a time pattern) + maxlen: maxi number of characters that id can hold not counting null termination character""" + type_ind = 100 # in case the type input is in text + if type == "MSX_SPECIES" or type == 3: + type_ind = 3 + if type == "MSX_CONSTANT" or type == 6: + type_ind = 6 + if type == "MSX_PARAMETER" or type == 5: + type_ind = 5 + if type == "MSX_PATTERN" or type == 7: + type_ind = 7 + if type_ind == 100: + raise Exception("unrecognized type") + count = ctypes.c_int() + ierr = self.ENlib.MSXgetcount(type_ind, ctypes.byref(count)) + if ierr != 0: + raise EpanetMsxToolkitError(ierr) + return count.value + + def MSXgetspecies(self, spe): + """Retrieves the attributes of a chemical species given its internal index number. + species is the sequence number of the species (starting from 1 as listed in teh MSX input file_ + type: MSX_BULK (defined as 0) and MSX_WALL (defined as 1) + units: C_style character string array that is returned with the mass units that were defined for the species in question(hold max 15 characters) + aTol returned with absolute concentration tolerance defined for the species + rTol returned with the relative concentration tolerance defined for the species""" + type_ind = ctypes.c_int() + units = ctypes.create_string_buffer(15) + aTol = ctypes.c_double() + rTol = ctypes.c_double() + ierr = self.ENlib.MSXgetspecies(spe, ctypes.byref(type_ind), ctypes.byref(units), ctypes.byref(aTol), ctypes.byref(rTol)) + if ierr != 0: + raise EpanetMsxToolkitError(ierr) + spe_out = [type_ind.value, units.value, aTol.value, rTol.value] + return spe_out + + def MSXgeterror(self, errcode, len=100): + """returns the text for an error message given its error code + arguments: + code is the code number of an error condition generated by EPANET-MSX + msg is a C-style string containing text of error message corresponding to error code + len is the max number of charaters that msg can contain (at least 80)""" + errmsg = ctypes.create_string_buffer(len) + self.ENlib.MSXgeterror(errcode, ctypes.byref(errmsg), len) + return errmsg.value.decode() + + # --------------set parameters----------------------------------- + + def MSXsetconstant(self, ind, value): + """assigns a new value to a specific reaction constant + Arguments: + ind is the sequence number of the reaction constant (starting from 1) as it appreaed in the MSX input file + value is the new value to be assigned to the constant""" + ierr = self.ENlib.MSXsetconstant(ctypes.c_int(ind), ctypes.c_double(value)) + if ierr != 0: + raise EpanetMsxToolkitError(ierr) + + def MSXsetparameter(self, type, ind, param, value): + """assigns a value to a particular reaction parameter for a given TANK or PIPE + Arguments: + type is the type of object: MSX_NODE (0) or MSX_LINK (1) + ind is the internal sequence number(starting from 1) assigned to the node or link + param is the sequence number of the parameter (starting from 1 as listed in the MSX input file""" + type_ind = 100 + if type == "MSX_NODE" or type == 0: + type_ind = 0 + if type == "MSX_LINK" or type == 1: + type_ind = 1 + if type_ind == 100: + raise Exception("unrecognized type") + ierr = self.ENlib.MSXsetparameter(ctypes.c_int(type_ind), ctypes.c_int(ind), ctypes.c_int(param), ctypes.c_double(value)) + if ierr != 0: + raise EpanetMsxToolkitError(ierr) + + def MSXsetinitqual(self, type, ind, spe, value): + """Retrieves the initial concentration of a particular chemical species assigned to a specific node + or link of the pipe network. + Arguments: + type is type of object: MSX_NODE (0), MSX_LINK (1) + ind is the internal sequence number (starting from 1) assigned to the node or link + speicies is the sequence number of teh species (starting from 1)""" + type_ind = 100 + if type == "MSX_NODE" or type == 0: + type_ind = 0 + if type == "MSX_LINK" or type == 1: + type_ind = 1 + if type_ind == 100: + raise Exception("unrecognized type") + ierr = self.ENlib.MSXsetinitqual(ctypes.c_int(type_ind), ctypes.c_int(ind), ctypes.c_int(spe), ctypes.c_double(value)) + if ierr != 0: + raise EpanetMsxToolkitError(ierr) + + def MSXsetsource(self, node, spe, type_n, level, pat): + """sets the attributes of an external source of a particular chemical species in a specific node of the pipe network + Arguments: + node is the internal sequence number (starting from 1) assigned to the node of interest + species is the sequence number of the species of interest (starting from 1 as listed in the MSX input file) + type is returned with the type of exteernal source and will be one of the following pre-defined constants + MSX_NOSOURCE (-1) no source; MSX_CONCEN (0) a concentration source; MSX_MASS (1) mass booster source; + MSX_SETPOINT (2) setpoint source; MSX_FLOWPACED (3) flow paced source + level is the baseline concentration (or mass flow rate) of the source + pat is the index of the time pattern used to add variability to the source's baseline level (0 if no pattern defined for the source)""" + type_ind = 100 + if type_n == "MSX_NOSOURCE" or type_n == -1: + type_ind = -1 + if type_n == "MSX_CONCEN" or type_n == 0: + type_ind = 0 + if type_n == "MSX_MASS" or type_n == 1: + type_ind = 1 + if type_n == "MSX_SETPOINT" or type_n == 2: + type_ind = 2 + if type_n == "MSX_FLOWPACED" or type_n == 3: + type_ind = 3 + if type_ind == 100: + raise Exception("unrecognized type") + ierr = self.ENlib.MSXsetsource(ctypes.c_int(node), ctypes.c_int(spe), ctypes.c_int(type_ind), ctypes.c_double(level), ctypes.c_int(pat)) + if ierr != 0: + raise EpanetMsxToolkitError(ierr) + + def MSXsetpattern(self, pat, mult): + """assigns a new set of multipliers to a given MSX SOURCE time pattern + Arguments: + pat is the internal sequence number (starting from 1) of the pattern as appears in the MSX input file + mult is an array of multiplier values to replace those preciously used by the pattern + len is the number of entries in mult""" + length = len(mult) + cfactors_type = ctypes.c_double * length + cfactors = cfactors_type() + for i in range(length): + cfactors[i] = float(mult[i]) + ierr = self.ENlib.MSXsetpattern(ctypes.c_int(pat), cfactors, ctypes.c_int(length)) + if ierr != 0: + raise EpanetMsxToolkitError(ierr) + + def MSXsetpatternvalue(self, pat, period, value): + """Sets the multiplier factor for a specific period within a SOURCE time pattern. + Arguments: + index: time pattern index + period: period within time pattern + value: multiplier factor for the period""" + ierr = self.ENlib.MSXsetpatternvalue(ctypes.c_int(pat), ctypes.c_int(period), ctypes.c_double(value)) + if ierr != 0: + raise EpanetMsxToolkitError(ierr) + + def MSXaddpattern(self, patternid): + """Adds a new, empty MSX source time pattern to an MSX project. + Arguments: + pattern id: c-string name of pattern""" + ierr = self.ENlib.MSXaddpattern(ctypes.c_char_p(patternid.encode())) + if ierr != 0: + raise EpanetMsxToolkitError(ierr) diff --git a/wntr/tests/test_reactions.py b/wntr/tests/test_reactions.py index 12c5df470..6fc835448 100644 --- a/wntr/tests/test_reactions.py +++ b/wntr/tests/test_reactions.py @@ -13,6 +13,7 @@ test_data_dir = join(testdir, "data_for_testing") ex_datadir = join(testdir, "..", "..", "examples", "networks") + class Test(unittest.TestCase): @classmethod def setUpClass(self): @@ -23,72 +24,70 @@ def tearDownClass(self): pass def test_RxnVariable_reserved_name_exception(self): - self.assertRaises(ValueError, wntr.reaction.model.RxnVariable, 'I') - self.assertRaises(ValueError, wntr.reaction.model.RxnSpecies, 'Ff', 'mg') - self.assertRaises(ValueError, wntr.reaction.model.BulkSpecies, 'D', 'mg') - self.assertRaises(ValueError, wntr.reaction.model.WallSpecies, 'Q', 'mg') - self.assertRaises(ValueError, wntr.reaction.model.RxnCoefficient, 'Re', 0.52) + self.assertRaises(ValueError, wntr.reaction.model.RxnVariable, "I") + self.assertRaises(ValueError, wntr.reaction.model.RxnSpecies, "Ff", "mg") + self.assertRaises(ValueError, wntr.reaction.model.BulkSpecies, "D", "mg") + self.assertRaises(ValueError, wntr.reaction.model.WallSpecies, "Q", "mg") + self.assertRaises(ValueError, wntr.reaction.model.RxnCoefficient, "Re", 0.52) def test_RxnVariable_direct_instantiation_exceptions(self): - self.assertRaises(NotImplementedError, wntr.reaction.model.RxnVariable, 'Test') - self.assertRaises(NotImplementedError, wntr.reaction.model.RxnSpecies, 'Test', 'mg/L') - self.assertRaises(NotImplementedError, wntr.reaction.model.RxnCoefficient, 'Test', 0.524) + self.assertRaises(NotImplementedError, wntr.reaction.model.RxnVariable, "Test") + self.assertRaises(NotImplementedError, wntr.reaction.model.RxnSpecies, "Test", "mg/L") + self.assertRaises(NotImplementedError, wntr.reaction.model.RxnCoefficient, "Test", 0.524) def test_RxnVariable_symbols_and_sympy(self): - species1 = wntr.reaction.model.BulkSpecies('Cl', 'mg') - symbol1 = sympy.symbols('Cl') - self.assertEqual(species1.get_symbol(), symbol1) - - const1 = wntr.reaction.model.Constant('Kb', 0.482) - symbol2 = sympy.symbols('Kb') - self.assertEqual(const1.get_symbol(), symbol2) + species1 = wntr.reaction.model.BulkSpecies("Cl", "mg") + symbol1 = sympy.symbols("Cl") + self.assertEqual(species1.symbol, symbol1) - param1 = wntr.reaction.model.Constant('Ka', 0.482) - symbol3 = sympy.symbols('Ka') - self.assertEqual(param1.get_symbol(), symbol3) + const1 = wntr.reaction.model.ConstantCoeff("Kb", 0.482) + symbol2 = sympy.symbols("Kb") + self.assertEqual(const1.symbol, symbol2) - term1 = wntr.reaction.model.RxnTerm('T0', '-3.2 * Kb * Cl^2', note='bar') - symbol4 = sympy.symbols('T0') - self.assertEqual(term1.get_symbol(), symbol4) + param1 = wntr.reaction.model.ConstantCoeff("Ka", 0.482) + symbol3 = sympy.symbols("Ka") + self.assertEqual(param1.symbol, symbol3) + term1 = wntr.reaction.model.FunctionalTerm("T0", "-3.2 * Kb * Cl^2", note="bar") + symbol4 = sympy.symbols("T0") + self.assertEqual(term1.symbol, symbol4) def test_RxnVariable_values(self): - species1 = wntr.reaction.model.BulkSpecies('Cl', 'mg') + species1 = wntr.reaction.model.BulkSpecies("Cl", "mg") self.assertEqual(species1.get_value(), species1.value) - self.assertRaises(TypeError, species1.get_value, pipe='blah') - const1 = wntr.reaction.model.Constant('Kb', 0.482, note='test') + self.assertRaises(TypeError, species1.get_value, pipe="blah") + const1 = wntr.reaction.model.ConstantCoeff("Kb", 0.482, note="test") self.assertEqual(const1.get_value(), const1.value) - test_pipe_dict = {'PIPE': 0.38} - test_tank_dict = {'TANK': 222.23} - param2 = wntr.reaction.model.Parameter('Kb', 0.482, note='test', pipe_values=test_pipe_dict, tank_values=test_tank_dict) + test_pipe_dict = {"PIPE": 0.38} + test_tank_dict = {"TANK": 222.23} + param2 = wntr.reaction.model.ParameterizedCoeff("Kb", 0.482, note="test", pipe_values=test_pipe_dict, tank_values=test_tank_dict) self.assertEqual(param2.get_value(), param2.global_value) - self.assertEqual(param2.get_value(pipe='PIPE'), test_pipe_dict['PIPE']) - self.assertEqual(param2.get_value(pipe='FOO'), param2.global_value) - self.assertEqual(param2.get_value(tank='TANK'), test_tank_dict['TANK']) - self.assertRaises(ValueError, param2.get_value, pipe='PIPE', tank='TANK') - + self.assertEqual(param2.get_value(pipe="PIPE"), test_pipe_dict["PIPE"]) + self.assertEqual(param2.get_value(pipe="FOO"), param2.global_value) + self.assertEqual(param2.get_value(tank="TANK"), test_tank_dict["TANK"]) + self.assertRaises(ValueError, param2.get_value, pipe="PIPE", tank="TANK") def test_RxnVariable_string_functions(self): - species1 = wntr.reaction.model.BulkSpecies('Cl', 'mg') - species2 = wntr.reaction.model.WallSpecies('Cl', 'mg', 0.01, 0.0001, note='Testing stuff') - const1 = wntr.reaction.model.Constant('Kb', 0.482) - param1 = wntr.reaction.model.Parameter('Ka', 0.482, note='foo') - term1 = wntr.reaction.model.RxnTerm('T0', '-3.2 * Kb * Cl^2', note='bar') - - self.assertEqual(str(species1), 'Cl') - self.assertEqual(species1.to_msx_string(), 'BULK Cl mg ;') - self.assertEqual(species2.to_msx_string(), 'WALL Cl mg 0.01 0.0001 ;Testing stuff') - self.assertEqual(str(const1), 'Kb') - self.assertEqual(str(param1), 'Ka') - self.assertEqual(const1.to_msx_string(), 'CONSTANT Kb 0.482 ;') - self.assertEqual(param1.to_msx_string(), 'PARAMETER Ka 0.482 ;foo') - self.assertEqual(str(term1), 'T0') - self.assertEqual(term1.to_msx_string(), 'T0 -3.2 * Kb * Cl^2 ;bar') + species1 = wntr.reaction.model.BulkSpecies("Cl", "mg") + species2 = wntr.reaction.model.WallSpecies("Cl", "mg", 0.01, 0.0001, note="Testing stuff") + const1 = wntr.reaction.model.ConstantCoeff("Kb", 0.482) + param1 = wntr.reaction.model.ParameterizedCoeff("Ka", 0.482, note="foo") + term1 = wntr.reaction.model.FunctionalTerm("T0", "-3.2 * Kb * Cl^2", note="bar") + + self.assertEqual(str(species1), "Cl") + self.assertEqual(species1.to_msx_string(), "BULK Cl mg ;") + self.assertEqual(species2.to_msx_string(), "WALL Cl mg 0.01 0.0001 ;Testing stuff") + self.assertEqual(str(const1), "Kb") + self.assertEqual(str(param1), "Ka") + self.assertEqual(const1.to_msx_string(), "CONSTANT Kb 0.482 ;") + self.assertEqual(param1.to_msx_string(), "PARAMETER Ka 0.482 ;foo") + self.assertEqual(str(term1), "T0") + self.assertEqual(term1.to_msx_string(), "T0 -3.2 * Kb * Cl^2 ;bar") def test_RxnSpecies_tolerances(self): - #"""RxnSpecies(*s) tolerance settings""" - species1 = wntr.reaction.model.BulkSpecies('Cl', 'mg') - species2 = wntr.reaction.model.WallSpecies('Cl', 'mg', 0.01, 0.0001, note='Testing stuff') + # """RxnSpecies(*s) tolerance settings""" + species1 = wntr.reaction.model.BulkSpecies("Cl", "mg") + species2 = wntr.reaction.model.WallSpecies("Cl", "mg", 0.01, 0.0001, note="Testing stuff") self.assertIsNone(species1.get_tolerances()) self.assertIsNotNone(species2.get_tolerances()) self.assertTupleEqual(species2.get_tolerances(), (0.01, 0.0001)) @@ -107,139 +106,139 @@ def test_RxnSpecies_tolerances(self): self.assertIsNone(species2.get_tolerances()) def test_BulkSpecies_creation(self): - #"""BlukSpecies object creation (direct instantiation)""" - self.assertRaises(TypeError, wntr.reaction.model.BulkSpecies, 'I') - self.assertRaises(ValueError, wntr.reaction.model.BulkSpecies, 'I', 'mg') - self.assertRaises(ValueError, wntr.reaction.model.BulkSpecies, 'Cl', 'mg', 0.01) - self.assertRaises(ValueError, wntr.reaction.model.BulkSpecies, 'Cl', 'mg', None, 0.01) - species = wntr.reaction.model.BulkSpecies('Cl', 'mg') - self.assertEqual(species.name, 'Cl') - self.assertEqual(species.value, 'mg') + # """BlukSpecies object creation (direct instantiation)""" + self.assertRaises(TypeError, wntr.reaction.model.BulkSpecies, "I") + self.assertRaises(ValueError, wntr.reaction.model.BulkSpecies, "I", "mg") + self.assertRaises(ValueError, wntr.reaction.model.BulkSpecies, "Cl", "mg", 0.01) + self.assertRaises(ValueError, wntr.reaction.model.BulkSpecies, "Cl", "mg", None, 0.01) + species = wntr.reaction.model.BulkSpecies("Cl", "mg") + self.assertEqual(species.name, "Cl") + self.assertEqual(species.value, "mg") self.assertEqual(species.value, species.unit) - self.assertEqual(species.species_type, wntr.reaction.model.VarType.Bulk) + self.assertEqual(species.species_type, wntr.reaction.model.RxnVarType.Bulk) self.assertIsNone(species.Atol) self.assertIsNone(species.Rtol) self.assertIsNone(species.note) - species = wntr.reaction.model.BulkSpecies('Cl', 'mg', 0.01, 0.0001, note='Testing stuff') - self.assertEqual(species.variable_type, wntr.reaction.model.VarType.Bulk) - self.assertEqual(species.name, 'Cl') - self.assertEqual(species.value, 'mg') + species = wntr.reaction.model.BulkSpecies("Cl", "mg", 0.01, 0.0001, note="Testing stuff") + self.assertEqual(species.variable_type, wntr.reaction.model.RxnVarType.Bulk) + self.assertEqual(species.name, "Cl") + self.assertEqual(species.value, "mg") self.assertEqual(species.Atol, 0.01) self.assertEqual(species.Rtol, 0.0001) - self.assertEqual(species.note, 'Testing stuff') + self.assertEqual(species.note, "Testing stuff") def test_WallSpecies_creation(self): - #"""WallSpecies object creation (direct instantiation)""" - self.assertRaises(TypeError, wntr.reaction.model.WallSpecies, 'I') - self.assertRaises(ValueError, wntr.reaction.model.WallSpecies, 'I', 'mg') - self.assertRaises(ValueError, wntr.reaction.model.WallSpecies, 'Cl', 'mg', 0.01) - self.assertRaises(ValueError, wntr.reaction.model.WallSpecies, 'Cl', 'mg', None, 0.01) - species = wntr.reaction.model.WallSpecies('Cl', 'mg') - self.assertEqual(species.name, 'Cl') - self.assertEqual(species.value, 'mg') + # """WallSpecies object creation (direct instantiation)""" + self.assertRaises(TypeError, wntr.reaction.model.WallSpecies, "I") + self.assertRaises(ValueError, wntr.reaction.model.WallSpecies, "I", "mg") + self.assertRaises(ValueError, wntr.reaction.model.WallSpecies, "Cl", "mg", 0.01) + self.assertRaises(ValueError, wntr.reaction.model.WallSpecies, "Cl", "mg", None, 0.01) + species = wntr.reaction.model.WallSpecies("Cl", "mg") + self.assertEqual(species.name, "Cl") + self.assertEqual(species.value, "mg") self.assertEqual(species.value, species.unit) - self.assertEqual(species.species_type, wntr.reaction.model.VarType.Wall) + self.assertEqual(species.species_type, wntr.reaction.model.RxnVarType.Wall) self.assertIsNone(species.Atol) self.assertIsNone(species.Rtol) self.assertIsNone(species.note) - species = wntr.reaction.model.WallSpecies('Cl', 'mg', 0.01, 0.0001, note='Testing stuff') - self.assertEqual(species.variable_type, wntr.reaction.model.VarType.Wall) - self.assertEqual(species.name, 'Cl') - self.assertEqual(species.value, 'mg') + species = wntr.reaction.model.WallSpecies("Cl", "mg", 0.01, 0.0001, note="Testing stuff") + self.assertEqual(species.variable_type, wntr.reaction.model.RxnVarType.Wall) + self.assertEqual(species.name, "Cl") + self.assertEqual(species.value, "mg") self.assertEqual(species.Atol, 0.01) self.assertEqual(species.Rtol, 0.0001) - self.assertEqual(species.note, 'Testing stuff') + self.assertEqual(species.note, "Testing stuff") def test_Constant_creation(self): - self.assertRaises(TypeError, wntr.reaction.model.Constant, 'Re') - self.assertRaises(ValueError, wntr.reaction.model.Constant, 'Re', 2.48) - const1 = wntr.reaction.model.Constant('Kb', 0.482, note='test') + self.assertRaises(TypeError, wntr.reaction.model.ConstantCoeff, "Re") + self.assertRaises(ValueError, wntr.reaction.model.ConstantCoeff, "Re", 2.48) + const1 = wntr.reaction.model.ConstantCoeff("Kb", 0.482, note="test") # FIXME: Find a way to suppress warning printing # self.assertWarns(RuntimeWarning, wntr.reaction.model.Constant, 'Kb1', 0.83, pipe_values={'a',1}) - self.assertEqual(const1.name, 'Kb') + self.assertEqual(const1.name, "Kb") self.assertEqual(const1.global_value, 0.482) self.assertEqual(const1.value, const1.global_value) - self.assertEqual(const1.coeff_type, wntr.reaction.model.VarType.Constant) - self.assertEqual(const1.note, 'test') + self.assertEqual(const1.coeff_type, wntr.reaction.model.RxnVarType.Constant) + self.assertEqual(const1.note, "test") def test_Parameter_creation(self): - self.assertRaises(TypeError, wntr.reaction.model.Parameter, 'Re') - self.assertRaises(ValueError, wntr.reaction.model.Parameter, 'Re', 2.48) - param1 = wntr.reaction.model.Parameter('Kb', 0.482, note='test') - self.assertEqual(param1.name, 'Kb') + self.assertRaises(TypeError, wntr.reaction.model.ParameterizedCoeff, "Re") + self.assertRaises(ValueError, wntr.reaction.model.ParameterizedCoeff, "Re", 2.48) + param1 = wntr.reaction.model.ParameterizedCoeff("Kb", 0.482, note="test") + self.assertEqual(param1.name, "Kb") self.assertEqual(param1.global_value, 0.482) self.assertEqual(param1.value, param1.global_value) - self.assertEqual(param1.coeff_type, wntr.reaction.model.VarType.Parameter) - self.assertEqual(param1.note, 'test') - test_pipe_dict = {'PIPE': 0.38} - test_tank_dict = {'TANK': 222.23} - param2 = wntr.reaction.model.Parameter('Kb', 0.482, note='test', pipe_values=test_pipe_dict, tank_values=test_tank_dict) + self.assertEqual(param1.coeff_type, wntr.reaction.model.RxnVarType.Parameter) + self.assertEqual(param1.note, "test") + test_pipe_dict = {"PIPE": 0.38} + test_tank_dict = {"TANK": 222.23} + param2 = wntr.reaction.model.ParameterizedCoeff("Kb", 0.482, note="test", pipe_values=test_pipe_dict, tank_values=test_tank_dict) self.assertDictEqual(param2.pipe_values, test_pipe_dict) self.assertDictEqual(param2.tank_values, test_tank_dict) def test_RxnTerm_creation(self): - self.assertRaises(TypeError, wntr.reaction.model.RxnTerm, 'Re') - self.assertRaises(ValueError, wntr.reaction.model.RxnTerm, 'Re', '1.0*Re') - term1 = wntr.reaction.model.RxnTerm('T0', '-3.2 * Kb * Cl^2', note='bar') - self.assertEqual(term1.name, 'T0') - self.assertEqual(term1.expression, '-3.2 * Kb * Cl^2') - self.assertEqual(term1.variable_type, wntr.reaction.model.VarType.Term) - self.assertEqual(term1.note, 'bar') + self.assertRaises(TypeError, wntr.reaction.model.FunctionalTerm, "Re") + self.assertRaises(ValueError, wntr.reaction.model.FunctionalTerm, "Re", "1.0*Re") + term1 = wntr.reaction.model.FunctionalTerm("T0", "-3.2 * Kb * Cl^2", note="bar") + self.assertEqual(term1.name, "T0") + self.assertEqual(term1.expression, "-3.2 * Kb * Cl^2") + self.assertEqual(term1.variable_type, wntr.reaction.model.RxnVarType.Term) + self.assertEqual(term1.note, "bar") self.assertEqual(term1.value, term1.expression) def test_RxnExpression_direct_instantiation_exceptions(self): - self.assertRaises(TypeError, wntr.reaction.model.RxnExpression, 'Cl', wntr.reaction.model.RxnLocation.Pipes) - self.assertRaises(NotImplementedError, wntr.reaction.model.RxnExpression, 'Cl', wntr.reaction.model.RxnLocation.Pipes, '-Ka + Kb * Cl + T0') - self.assertRaises(TypeError, wntr.reaction.model.RxnExpression, 'Cl') - self.assertRaises(TypeError, wntr.reaction.model.RxnExpression, 'Cl', 39) - self.assertRaises(TypeError, wntr.reaction.model.RxnExpression, 'Cl', 39, '-Ka + Kb * Cl + T0') - + self.assertRaises(TypeError, wntr.reaction.model.RxnExpression, "Cl", wntr.reaction.model.RxnLocType.Pipes) + self.assertRaises(NotImplementedError, wntr.reaction.model.RxnExpression, "Cl", wntr.reaction.model.RxnLocType.Pipes, "-Ka + Kb * Cl + T0") + self.assertRaises(TypeError, wntr.reaction.model.RxnExpression, "Cl") + self.assertRaises(TypeError, wntr.reaction.model.RxnExpression, "Cl", 39) + self.assertRaises(TypeError, wntr.reaction.model.RxnExpression, "Cl", 39, "-Ka + Kb * Cl + T0") + def test_RxnExpression_strings(self): - equil1 = wntr.reaction.model.Equilibrium( 'Cl', wntr.reaction.model.RxnLocation.Pipes, '-Ka + Kb * Cl + T0') - rate1 = wntr.reaction.model.Rate( 'Cl', wntr.reaction.model.RxnLocation.Tanks, '-Ka + Kb * Cl + T0', note='Foo Bar') - formula1 = wntr.reaction.model.Formula( 'Cl', wntr.reaction.model.RxnLocation.Pipes, '-Ka + Kb * Cl + T0') - self.assertEqual(equil1.to_msx_string(), 'EQUIL Cl -Ka + Kb * Cl + T0 ;') - self.assertEqual(rate1.to_msx_string(), 'RATE Cl -Ka + Kb * Cl + T0 ;Foo Bar') - self.assertEqual(formula1.to_msx_string(), 'FORMULA Cl -Ka + Kb * Cl + T0 ;') + equil1 = wntr.reaction.model.EquilibriumExpression("Cl", wntr.reaction.model.RxnLocType.Pipes, "-Ka + Kb * Cl + T0") + rate1 = wntr.reaction.model.RateExpression("Cl", wntr.reaction.model.RxnLocType.Tanks, "-Ka + Kb * Cl + T0", note="Foo Bar") + formula1 = wntr.reaction.model.FormulaExpression("Cl", wntr.reaction.model.RxnLocType.Pipes, "-Ka + Kb * Cl + T0") + self.assertEqual(equil1.to_msx_string(), "EQUIL Cl -Ka + Kb * Cl + T0 ;") + self.assertEqual(rate1.to_msx_string(), "RATE Cl -Ka + Kb * Cl + T0 ;Foo Bar") + self.assertEqual(formula1.to_msx_string(), "FORMULA Cl -Ka + Kb * Cl + T0 ;") def test_Equilibrium_creation(self): - equil1 = wntr.reaction.model.Equilibrium( 'Cl', wntr.reaction.model.RxnLocation.Pipes, '-Ka + Kb * Cl + T0') - self.assertEqual(equil1.species, 'Cl') - self.assertEqual(equil1.expression, '-Ka + Kb * Cl + T0') - self.assertEqual(equil1.expression_type, wntr.reaction.model.ExprType.Equil) + equil1 = wntr.reaction.model.EquilibriumExpression("Cl", wntr.reaction.model.RxnLocType.Pipes, "-Ka + Kb * Cl + T0") + self.assertEqual(equil1.species, "Cl") + self.assertEqual(equil1.expression, "-Ka + Kb * Cl + T0") + self.assertEqual(equil1.expression_type, wntr.reaction.model.RxnExprType.Equil) def test_Rate_creation(self): - rate1 = wntr.reaction.model.Rate( 'Cl', wntr.reaction.model.RxnLocation.Tanks, '-Ka + Kb * Cl + T0', note='Foo Bar') - self.assertEqual(rate1.species, 'Cl') - self.assertEqual(rate1.expression, '-Ka + Kb * Cl + T0') - self.assertEqual(rate1.expression_type, wntr.reaction.model.ExprType.Rate) - self.assertEqual(rate1.note, 'Foo Bar') + rate1 = wntr.reaction.model.RateExpression("Cl", wntr.reaction.model.RxnLocType.Tanks, "-Ka + Kb * Cl + T0", note="Foo Bar") + self.assertEqual(rate1.species, "Cl") + self.assertEqual(rate1.expression, "-Ka + Kb * Cl + T0") + self.assertEqual(rate1.expression_type, wntr.reaction.model.RxnExprType.Rate) + self.assertEqual(rate1.note, "Foo Bar") def test_Formula_creation(self): - formula1 = wntr.reaction.model.Formula( 'Cl', wntr.reaction.model.RxnLocation.Pipes, '-Ka + Kb * Cl + T0') - self.assertEqual(formula1.species, 'Cl') - self.assertEqual(formula1.expression, '-Ka + Kb * Cl + T0') - self.assertEqual(formula1.expression_type, wntr.reaction.model.ExprType.Formula) - + formula1 = wntr.reaction.model.FormulaExpression("Cl", wntr.reaction.model.RxnLocType.Pipes, "-Ka + Kb * Cl + T0") + self.assertEqual(formula1.species, "Cl") + self.assertEqual(formula1.expression, "-Ka + Kb * Cl + T0") + self.assertEqual(formula1.expression_type, wntr.reaction.model.RxnExprType.Formula) + def test_WaterQualityReactionsModel_creation_specific_everything(self): rxn_model1 = wntr.reaction.model.WaterQualityReactionsModel() - bulk1 = wntr.reaction.model.BulkSpecies('Cl', 'mg') - wall1 = wntr.reaction.model.WallSpecies('ClOH', 'mg', 0.01, 0.0001, note='Testing stuff') - const1 = wntr.reaction.model.Constant('Kb', 0.482) - param1 = wntr.reaction.model.Parameter('Ka', 0.482, note='foo') - term1 = wntr.reaction.model.RxnTerm('T0', '-3.2 * Kb * Cl^2', note='bar') - equil1 = wntr.reaction.model.Equilibrium( 'Cl', wntr.reaction.model.RxnLocation.Pipes, '-Ka + Kb * Cl + T0') - rate1 = wntr.reaction.model.Rate( 'Cl', wntr.reaction.model.RxnLocation.Tanks, '-Ka + Kb * Cl + T0', note='Foo Bar') - formula1 = wntr.reaction.model.Formula( 'ClOH', wntr.reaction.model.RxnLocation.Pipes, '-Ka + Kb * Cl + T0') - - bulk2 = rxn_model1.add_bulk_species('Cl', 'mg') - wall2 = rxn_model1.add_wall_species('ClOH', 'mg', 0.01, 0.0001, note='Testing stuff') - const2 = rxn_model1.add_constant('Kb', 0.482) - param2 = rxn_model1.add_parameter('Ka', 0.482, note='foo') - term2 = rxn_model1.add_term('T0', '-3.2 * Kb * Cl^2', note='bar') - equil2 = rxn_model1.add_pipe_reaction('equil', 'Cl', '-Ka + Kb * Cl + T0') - rate2 = rxn_model1.add_tank_reaction(wntr.reaction.model.ExprType.Rate, 'Cl', '-Ka + Kb * Cl + T0', note='Foo Bar') - formula2 = rxn_model1.add_reaction('pipes', 'formula', 'ClOH', '-Ka + Kb * Cl + T0') + bulk1 = wntr.reaction.model.BulkSpecies("Cl", "mg") + wall1 = wntr.reaction.model.WallSpecies("ClOH", "mg", 0.01, 0.0001, note="Testing stuff") + const1 = wntr.reaction.model.ConstantCoeff("Kb", 0.482) + param1 = wntr.reaction.model.ParameterizedCoeff("Ka", 0.482, note="foo") + term1 = wntr.reaction.model.FunctionalTerm("T0", "-3.2 * Kb * Cl^2", note="bar") + equil1 = wntr.reaction.model.EquilibriumExpression(bulk1, wntr.reaction.model.RxnLocType.Pipes, "-Ka + Kb * Cl + T0") + rate1 = wntr.reaction.model.RateExpression(bulk1, wntr.reaction.model.RxnLocType.Tanks, "-Ka + Kb * Cl + T0", note="Foo Bar") + formula1 = wntr.reaction.model.FormulaExpression(wall1, wntr.reaction.model.RxnLocType.Pipes, "-Ka + Kb * Cl + T0") + + bulk2 = rxn_model1.add_bulk_species("Cl", "mg") + wall2 = rxn_model1.add_wall_species("ClOH", "mg", 0.01, 0.0001, note="Testing stuff") + const2 = rxn_model1.add_constant("Kb", 0.482) + param2 = rxn_model1.add_parameter("Ka", 0.482, note="foo") + term2 = rxn_model1.add_term("T0", "-3.2 * Kb * Cl^2", note="bar") + equil2 = rxn_model1.add_pipe_reaction("Cl", "equil", "-Ka + Kb * Cl + T0") + rate2 = rxn_model1.add_tank_reaction("Cl", wntr.reaction.model.RxnExprType.Rate, "-Ka + Kb * Cl + T0", note="Foo Bar") + formula2 = rxn_model1.add_reaction("pipes", "ClOH", "formula", "-Ka + Kb * Cl + T0") self.assertEqual(bulk1, bulk2) self.assertEqual(wall1, wall2) self.assertEqual(const1, const2) @@ -250,22 +249,22 @@ def test_WaterQualityReactionsModel_creation_specific_everything(self): self.assertEqual(formula1, formula2) def test_WaterQualityReactionsModel_creation_generic_species_coeffs(self): - bulk1 = wntr.reaction.model.BulkSpecies('Cl', 'mg') - wall1 = wntr.reaction.model.WallSpecies('ClOH', 'mg', 0.01, 0.0001, note='Testing stuff') - const1 = wntr.reaction.model.Constant('Kb', 0.482) - param1 = wntr.reaction.model.Parameter('Ka', 0.482, note='foo') - term1 = wntr.reaction.model.RxnTerm('T0', '-3.2 * Kb * Cl^2', note='bar') + bulk1 = wntr.reaction.model.BulkSpecies("Cl", "mg") + wall1 = wntr.reaction.model.WallSpecies("ClOH", "mg", 0.01, 0.0001, note="Testing stuff") + const1 = wntr.reaction.model.ConstantCoeff("Kb", 0.482) + param1 = wntr.reaction.model.ParameterizedCoeff("Ka", 0.482, note="foo") + term1 = wntr.reaction.model.FunctionalTerm("T0", "-3.2 * Kb * Cl^2", note="bar") rxn_model2 = wntr.reaction.model.WaterQualityReactionsModel() - self.assertRaises(ValueError, rxn_model2.add_species, wntr.reaction.model.VarType.Species, 'Cl', 'mg') - self.assertRaises(TypeError, rxn_model2.add_coefficient, None, 'Kb', 0.482) - self.assertRaises(ValueError, rxn_model2.add_coefficient, 'Wall', 'Kb', 0.482) + self.assertRaises(ValueError, rxn_model2.add_species, wntr.reaction.model.RxnVarType.Species, "Cl", "mg") + self.assertRaises(TypeError, rxn_model2.add_coefficient, None, "Kb", 0.482) + self.assertRaises(ValueError, rxn_model2.add_coefficient, "Wall", "Kb", 0.482) - bulk3 = rxn_model2.add_species('Bulk', 'Cl', 'mg') - wall3 = rxn_model2.add_species(wntr.reaction.model.VarType.Wall, 'ClOH', 'mg', 0.01, 0.0001, note='Testing stuff') - const3 = rxn_model2.add_coefficient('Consolation', 'Kb', 0.482) - param3 = rxn_model2.add_coefficient(wntr.reaction.model.VarType.P, 'Ka', 0.482, note='foo') + bulk3 = rxn_model2.add_species("Bulk", "Cl", "mg") + wall3 = rxn_model2.add_species(wntr.reaction.model.RxnVarType.Wall, "ClOH", "mg", 0.01, 0.0001, note="Testing stuff") + const3 = rxn_model2.add_coefficient("Consolation", "Kb", 0.482) + param3 = rxn_model2.add_coefficient(wntr.reaction.model.RxnVarType.P, "Ka", 0.482, note="foo") self.assertEqual(bulk3, bulk1) self.assertEqual(wall3, wall1) @@ -273,22 +272,22 @@ def test_WaterQualityReactionsModel_creation_generic_species_coeffs(self): self.assertEqual(param3, param1) def test_WaterQualityReactionsModel_creation_generic_variables_reactions(self): - bulk1 = wntr.reaction.model.BulkSpecies('Cl', 'mg') - wall1 = wntr.reaction.model.WallSpecies('ClOH', 'mg', 0.01, 0.0001, note='Testing stuff') - const1 = wntr.reaction.model.Constant('Kb', 0.482) - param1 = wntr.reaction.model.Parameter('Ka', 0.482, note='foo') - term1 = wntr.reaction.model.RxnTerm('T0', '-3.2 * Kb * Cl^2', note='bar') + bulk1 = wntr.reaction.model.BulkSpecies("Cl", "mg") + wall1 = wntr.reaction.model.WallSpecies("ClOH", "mg", 0.01, 0.0001, note="Testing stuff") + const1 = wntr.reaction.model.ConstantCoeff("Kb", 0.482) + param1 = wntr.reaction.model.ParameterizedCoeff("Ka", 0.482, note="foo") + term1 = wntr.reaction.model.FunctionalTerm("T0", "-3.2 * Kb * Cl^2", note="bar") rxn_model2 = wntr.reaction.model.WaterQualityReactionsModel() - self.assertRaises(ValueError, rxn_model2.add_variable, wntr.reaction.model.VarType.Species, 'Cl', 'mg') - self.assertRaises(ValueError, rxn_model2.add_variable, None, 'Kb', 0.482) + self.assertRaises(ValueError, rxn_model2.add_variable, wntr.reaction.model.RxnVarType.Species, "Cl", "mg") + self.assertRaises(ValueError, rxn_model2.add_variable, None, "Kb", 0.482) - bulk3 = rxn_model2.add_variable('Bulk', 'Cl', 'mg') - wall3 = rxn_model2.add_variable(wntr.reaction.model.VarType.Wall, 'ClOH', 'mg', 0.01, 0.0001, note='Testing stuff') - const3 = rxn_model2.add_variable('Consolation', 'Kb', 0.482) - param3 = rxn_model2.add_variable(wntr.reaction.model.VarType.P, 'Ka', 0.482, note='foo') - term3 = rxn_model2.add_variable('tErM', 'T0', '-3.2 * Kb * Cl^2', note='bar') + bulk3 = rxn_model2.add_variable("Bulk", "Cl", "mg") + wall3 = rxn_model2.add_variable(wntr.reaction.model.RxnVarType.Wall, "ClOH", "mg", 0.01, 0.0001, note="Testing stuff") + const3 = rxn_model2.add_variable("Consolation", "Kb", 0.482) + param3 = rxn_model2.add_variable(wntr.reaction.model.RxnVarType.P, "Ka", 0.482, note="foo") + term3 = rxn_model2.add_variable("tErM", "T0", "-3.2 * Kb * Cl^2", note="bar") self.assertEqual(bulk3, bulk1) self.assertEqual(wall3, wall1) @@ -296,5 +295,6 @@ def test_WaterQualityReactionsModel_creation_generic_variables_reactions(self): self.assertEqual(param3, param1) self.assertEqual(term3, term1) + if __name__ == "__main__": unittest.main(verbosity=2) From 6b4394a29397995f2d3e156117b86fc55bbc73c9 Mon Sep 17 00:00:00 2001 From: dbhart Date: Fri, 25 Aug 2023 12:29:47 -0600 Subject: [PATCH 06/75] Forgot some files --- documentation/apidoc/wntr.reaction.io.rst | 7 ++++++ .../apidoc/wntr.reaction.library.rst | 7 ++++++ documentation/apidoc/wntr.reaction.model.rst | 7 ++++++ documentation/apidoc/wntr.reaction.rst | 19 ++++++++++++++ .../apidoc/wntr.reaction.toolkitmsx.rst | 7 ++++++ documentation/apidoc/wntr.rst | 1 + documentation/conf.py | 1 + documentation/index.rst | 1 + wntr/reaction/__init__.py | 2 +- wntr/reaction/library.py | 25 +++++++++++++++++++ 10 files changed, 76 insertions(+), 1 deletion(-) create mode 100644 documentation/apidoc/wntr.reaction.io.rst create mode 100644 documentation/apidoc/wntr.reaction.library.rst create mode 100644 documentation/apidoc/wntr.reaction.model.rst create mode 100644 documentation/apidoc/wntr.reaction.rst create mode 100644 documentation/apidoc/wntr.reaction.toolkitmsx.rst create mode 100644 wntr/reaction/library.py diff --git a/documentation/apidoc/wntr.reaction.io.rst b/documentation/apidoc/wntr.reaction.io.rst new file mode 100644 index 000000000..de42d9c04 --- /dev/null +++ b/documentation/apidoc/wntr.reaction.io.rst @@ -0,0 +1,7 @@ +wntr.reaction.io module +======================= + +.. automodule:: wntr.reaction.io + :members: + :undoc-members: + :show-inheritance: diff --git a/documentation/apidoc/wntr.reaction.library.rst b/documentation/apidoc/wntr.reaction.library.rst new file mode 100644 index 000000000..730e22bce --- /dev/null +++ b/documentation/apidoc/wntr.reaction.library.rst @@ -0,0 +1,7 @@ +wntr.reaction.library module +============================ + +.. automodule:: wntr.reaction.library + :members: + :undoc-members: + :show-inheritance: diff --git a/documentation/apidoc/wntr.reaction.model.rst b/documentation/apidoc/wntr.reaction.model.rst new file mode 100644 index 000000000..774082841 --- /dev/null +++ b/documentation/apidoc/wntr.reaction.model.rst @@ -0,0 +1,7 @@ +wntr.reaction.model module +========================== + +.. automodule:: wntr.reaction.model + :members: + :undoc-members: + :show-inheritance: diff --git a/documentation/apidoc/wntr.reaction.rst b/documentation/apidoc/wntr.reaction.rst new file mode 100644 index 000000000..d8b61ab22 --- /dev/null +++ b/documentation/apidoc/wntr.reaction.rst @@ -0,0 +1,19 @@ +wntr.reaction package +===================== + +.. automodule:: wntr.reaction + :members: + :undoc-members: + :show-inheritance: + +Submodules +---------- + +.. toctree:: + :maxdepth: 4 + + wntr.reaction.io + wntr.reaction.library + wntr.reaction.model + wntr.reaction.options + wntr.reaction.toolkitmsx diff --git a/documentation/apidoc/wntr.reaction.toolkitmsx.rst b/documentation/apidoc/wntr.reaction.toolkitmsx.rst new file mode 100644 index 000000000..ed46dfcad --- /dev/null +++ b/documentation/apidoc/wntr.reaction.toolkitmsx.rst @@ -0,0 +1,7 @@ +wntr.reaction.toolkitmsx module +=============================== + +.. automodule:: wntr.reaction.toolkitmsx + :members: + :undoc-members: + :show-inheritance: diff --git a/documentation/apidoc/wntr.rst b/documentation/apidoc/wntr.rst index abab02a50..6b203c464 100644 --- a/documentation/apidoc/wntr.rst +++ b/documentation/apidoc/wntr.rst @@ -20,6 +20,7 @@ Subpackages wntr.metrics wntr.morph wntr.network + wntr.reaction wntr.scenario wntr.sim wntr.utils diff --git a/documentation/conf.py b/documentation/conf.py index 38819bec8..bdcf9ebf2 100644 --- a/documentation/conf.py +++ b/documentation/conf.py @@ -42,6 +42,7 @@ 'sphinx.ext.intersphinx', ] +autosummary_generate = True napoleon_use_rtype = False viewcode_import = True numpydoc_show_class_members = True diff --git a/documentation/index.rst b/documentation/index.rst index 5ef2fdd51..f7d9e1c42 100644 --- a/documentation/index.rst +++ b/documentation/index.rst @@ -30,6 +30,7 @@ designed to simulate and analyze resilience of water distribution networks. graphics gis advancedsim + advancedqual license whatsnew developers diff --git a/wntr/reaction/__init__.py b/wntr/reaction/__init__.py index d57287b5a..71fab1e33 100644 --- a/wntr/reaction/__init__.py +++ b/wntr/reaction/__init__.py @@ -5,7 +5,7 @@ # pyomo.dae # sympy -from . import model +from . import model, io, options, toolkitmsx # from . import library # from . import msx_toolkit # from . import MSXPY_toolkit diff --git a/wntr/reaction/library.py b/wntr/reaction/library.py new file mode 100644 index 000000000..cc9e53bad --- /dev/null +++ b/wntr/reaction/library.py @@ -0,0 +1,25 @@ +# -*- coding: utf-8 -*- +""" +Library of common reactions. + +@author: John Burkhart, US EPA ORD +""" + +from .model import WaterQualityReactionsModel + +nicotine = WaterQualityReactionsModel() +nicotine.options.quality.area_units = 'M2' +nicotine.options.quality.rate_units = 'MIN' +nicotine.options.time.timestep = 1 +nicotine.add_bulk_species('Nx', unit='MG', note='Nicotine') +nicotine.add_bulk_species('HOCL', unit='MG', note='Free chlorine') +nicotine.add_constant('kd', value=2.33e-3, unit='min^(-1)', note='decay rate') +nicotine.add_constant('K1', value=5.92e-2, unit='L * min^(-1) * mg^(-1)', note='decay constant for chlorine as function of mass(Nic)') +nicotine.add_constant('K2', value=1.84e-1, unit='L * min^(-1) * mg^(-1)', note='decay constant for nicotine as function of mass(Cl)') +nicotine.add_term('RXCL', expr='kd * HOCL + K1 * Nx * HOCL') +nicotine.add_term('RXN', expr='K2 * Nx * HOCL') +nicotine.add_pipe_reaction('rate', 'Nx', expression='-RXN') +nicotine.add_pipe_reaction('rate', 'HOCL', expression='-RXCL') +nicotine.add_tank_reaction('rate', 'Nx', '0') +nicotine.add_tank_reaction('rate', 'HOCL', '0') + From 8036ef327936694aed27757764b916371e88ac15 Mon Sep 17 00:00:00 2001 From: dbhart Date: Fri, 25 Aug 2023 15:09:00 -0600 Subject: [PATCH 07/75] Updated code structure checkin --- wntr/reaction/base.py | 373 +++++++++++++++++++++++++++++++++++ wntr/reaction/dynamics.py | 78 ++++++++ wntr/reaction/model.py | 198 ++++++++++++++++--- wntr/reaction/toolkitmsx.py | 8 + wntr/reaction/variables.py | 212 ++++++++++++++++++++ wntr/tests/test_reactions.py | 222 +++++++++------------ 6 files changed, 932 insertions(+), 159 deletions(-) create mode 100644 wntr/reaction/base.py create mode 100644 wntr/reaction/dynamics.py create mode 100644 wntr/reaction/variables.py diff --git a/wntr/reaction/base.py b/wntr/reaction/base.py new file mode 100644 index 000000000..5f17d58a3 --- /dev/null +++ b/wntr/reaction/base.py @@ -0,0 +1,373 @@ +import abc +from abc import ABC, abstractmethod, abstractproperty +from collections.abc import MutableMapping +import enum +import logging +from dataclasses import InitVar, asdict, dataclass, field +from enum import Enum, IntFlag +from typing import Any, ClassVar, Dict, Generator, ItemsView, Iterator, KeysView, List, Set, Tuple, Union, ValuesView + +import sympy +from sympy import Float, Symbol, init_printing, symbols, Function +from sympy.parsing import parse_expr +from sympy.parsing.sympy_parser import convert_xor, standard_transformations + +from wntr.network.model import WaterNetworkModel + +from .options import RxnOptions + +logger = logging.getLogger(__name__) + +RESERVED_NAMES = ("D", "Q", "U", "Re", "Us", "Ff", "Av") +SYMPY_RESERVED = ("E", "I", "pi") +EXPR_TRANSFORMS = standard_transformations + (convert_xor,) + +class KeyInOtherDictError(KeyError): + pass + +class VariableNameExistsError(KeyError): + pass + +class RxnVarType(Enum): + """The type of reaction variable. + + .. rubric:: Valid Values + + The following types are defined, and aliases of the first character + are also defined. + + .. autosummary:: + + Bulk + Wall + Constant + Parameter + Term + + Species + Coeff + + """ + + BULK = 1 + """A species that reacts with other bulk chemicals""" + WALL = 2 + """A species that reacts with the pipe walls""" + CONSTANT = 4 + """A constant coefficient for use in a reaction expression""" + PARAMETER = 8 + """A coefficient that has a value dependent on the pipe or tank""" + TERM = 16 + """A term that is aliased for ease of writing expressions""" + INTERNAL = 32 + """An internal variable - see RESERVED_NAMES""" + + B = BULK + """Alias for :attr:`Bulk`""" + W = WALL + """Alias for :attr:`Wall`""" + C = CONSTANT + """Alias for :attr:`Constant`""" + P = PARAMETER + """Alias for :attr:`Parameter`""" + T = TERM + """Alias for :attr:`Term`""" + I = INTERNAL + """Alias for :attr:`Internal`""" + CONST = CONSTANT + """Alias for :attr:`Constant`""" + PARAM = PARAMETER + """Alias for :attr:`Parameter`""" + + @classmethod + def make(cls, value: Union[str, int, 'RxnVarType']): + if value is None: + return + if isinstance(value, cls): + return value + if isinstance(value, int): + return cls(value) + if isinstance(value, str): + try: + return cls[value[0].upper()] + except KeyError: + raise KeyError(value) + raise TypeError("Invalid type '{}'".format(type(value))) + + +class RxnLocType(Enum): + """What type of network component does this reaction occur in + + .. rubric:: Valid values + + The following types are defined, and aliases of the first character + are also defined. + + .. autosummary:: + + Pipes + Tanks + """ + + PIPE = 1 + """The expression describes a reaction in pipes""" + TANK = 2 + """The expression describes a reaction in tanks""" + P = PIPE + """Alias for :attr:`Pipes`""" + T = TANK + """Alias for :attr:`Tanks`""" + + @classmethod + def make(cls, value: Union[str, int, 'RxnLocType']): + if value is None: + return + if isinstance(value, cls): + return value + if isinstance(value, int): + return cls(value) + if isinstance(value, str): + try: + return cls[value[0].upper()] + except KeyError: + raise KeyError(value) + raise TypeError("Invalid type '{}'".format(type(value))) + + +class RxnExprType(Enum): + """The type of reaction expression. + + .. rubric:: Valid values + + The following types are defined, and aliases of the first character + are also defined. + + .. autosummary:: + + Equil + Rate + Formula + """ + + EQUIL = 1 + """used for equilibrium expressions where it is assumed that the expression supplied is being equated to zero""" + RATE = 2 + """used to supply the equation that expresses the rate of change of the given species with respect to time as a function of the other species in the model""" + FORMULA = 3 + """used when the concentration of the named species is a simple function of the remaining species""" + E = EQUIL + """Alias for :attr:`Equil`""" + R = RATE + """Alias for :attr:`Rate`""" + F = FORMULA + """Alias for :attr:`Formula`""" + + @classmethod + def make(cls, value: Union[str, int, 'RxnExprType']): + if value is None: + return + if isinstance(value, cls): + return value + if isinstance(value, int): + return cls(value) + if isinstance(value, str): + try: + return cls[value[0].upper()] + except KeyError: + raise KeyError(value) + raise TypeError("Invalid type '{}'".format(type(value))) + + +class DisjointMapping(MutableMapping): + """A dictionary that checks a namespace for existing entries. + + To create a new instance, pass a set to act as a namespace. If the namespace does not + exist, a new namespace will be instantiated. If it does exist, then a new, disjoint + dictionary will be created that checks the namespace keys before it will allow a new + item to be added to the dictionary. An item can only belong to one of the disjoint dictionaries + associated with the namespace. + + Examples + -------- + Assume there is a namespace `nodes` that has two distinct subsets of objects, `tanks` + and `reservoirs`. A name for a tank cannot also be used for a reservoir, and a node + cannot be both a `tank` and a `reservoir`. A DisjointNamespaceDict allows two separate + dictionaries to be kept, one for each subtype, but the keys within the two dictionaries + will be ensured to not overlap. + + Parameters + ---------- + __keyspace : set + the name of the namespace for consistency checking + *args, **kwargs : Any + regular arguments and keyword arguments passed to the underlying dictionary + + """ + + __keyspace: dict = None + __data: dict = None + + def __new__(cls, __keyspace: dict, *args, **kwargs): + if __keyspace is None: + __keyspace = dict() + newobj = super().__new__(cls) + return newobj + + def __init__(self, __keyspace, *args, **kwargs): + self.__keyspace = __keyspace + temp = dict(*args, **kwargs) + overlap = set(self.__keyspace.keys()).intersection(temp.keys()) + if overlap: + raise KeyInOtherDictError(overlap) + self.__keyspace.update(temp) + self.__data = temp + + def __getitem__(self, __key: Any) -> Any: + try: + return self.__data.__getitem__(__key) + except KeyError as e: + if __key in self.__keyspace.keys(): + raise KeyInOtherDictError(__key) + raise + + def __setitem__(self, __key: Any, __value: Any) -> None: + if __key not in self.__data.keys() and __key in self.__keyspace.keys(): + raise KeyInOtherDictError(__key) + return self.__data.__setitem__(__key, __value) + + def __delitem__(self, __key: Any) -> None: + if __key not in self.__data.keys() and __key in self.__keyspace.keys(): + raise KeyInOtherDictError(__key) + self.__keyspace.__delitem__(__key) + return self.__data.__delitem__(__key) + + def __contains__(self, __key: object) -> bool: + return self.__data.__contains__(__key) + + def __iter__(self) -> Iterator: + return self.__data.__iter__() + + def __len__(self) -> int: + return self.__data.__len__() + + def keys(self) -> KeysView: + return self.__data.keys() + + def items(self) -> ItemsView: + return self.__data.items() + + def values(self) -> ValuesView: + return self.__data.values() + + def clear(self) -> None: + for k in self.__data.keys(): + self.__keyspace.__delitem__(k) + return self.__data.clear() + + def popitem(self) -> tuple: + (k, v) = self.__data.popitem() + self.__keyspace.__delitem__(k) + return (k, v) + + def new_disjoint_mapping(self): + return DisjointMapping(self.__keyspace) + + +@dataclass +class ReactionVariable(ABC): + + name: str + + @abstractproperty + def var_type(self) -> RxnVarType: + raise NotImplementedError + + @abstractmethod + def to_msx_string(self) -> str: + raise NotImplementedError + + @property + def symbol(self): + return sympy.Symbol(self.name) + + def __str__(self) -> str: + return self.name + + +@dataclass +class ReactionDynamics(ABC): + + species: str + location: RxnLocType + + @abstractproperty + def expr_type(self) -> RxnExprType: + raise NotImplementedError + + @abstractmethod + def to_msx_string(self) -> str: + raise NotImplementedError + + def __str__(self) -> str: + return self.to_key(self.species, self.location) + + @classmethod + def to_key(cls, species, location): + location = RxnLocType.make(location) + return species + "." + location.name.lower() + + +class VariableRegistry(ABC): + + @abstractmethod + def variables(self, var_type=None): + raise NotImplementedError + + @abstractmethod + def get_variable(self, name: str) -> ReactionVariable: + raise NotImplementedError + + @abstractmethod + def del_variable(self, name: str): + raise NotImplementedError + + +class ReactionRegistry(ABC): + + @abstractmethod + def reactions(self, location=None): + raise NotImplementedError + + @abstractmethod + def get_reaction(self, species, location=None) -> List[ReactionDynamics]: + raise NotImplementedError + + @abstractmethod + def del_reaction(self, species, location=None): + raise NotImplementedError + + +class LinkedVariablesMixin: + + __variable_registry = None + + @property + def _variable_registry(self) -> VariableRegistry: + return self.__variable_registry + + @_variable_registry.setter + def _variable_registry(self, value): + if value is not None and not isinstance(value, VariableRegistry): + raise TypeError("Linked model must be a RxnModel, got {}".format(type(value))) + self.__variable_registry = value + +@dataclass +class ExpressionMixin(ABC): + + expression: str + + @abstractmethod + def sympify(self): + raise NotImplementedError + + diff --git a/wntr/reaction/dynamics.py b/wntr/reaction/dynamics.py new file mode 100644 index 000000000..190f65862 --- /dev/null +++ b/wntr/reaction/dynamics.py @@ -0,0 +1,78 @@ +import enum +import logging +from dataclasses import InitVar, asdict, dataclass, field +from enum import Enum, IntFlag +from typing import Any, ClassVar, Dict, List, Set, Tuple, Union + +import sympy +from sympy import Float, Function, Symbol, init_printing, symbols +from sympy.parsing import parse_expr +from sympy.parsing.sympy_parser import convert_xor, standard_transformations + +from wntr.network.model import WaterNetworkModel +from wntr.reaction.base import RxnVarType + +from .base import ExpressionMixin, LinkedVariablesMixin, RxnExprType, RxnLocType, VariableRegistry, ReactionDynamics, RxnVarType +from .variables import Coefficient, NamedExpression, Species + +logger = logging.getLogger(__name__) + + +class MSXDefinedDynamicsMixin: + def to_msx_string(self) -> str: + """Get the expression as an EPANET-MSX input-file style string. + + Returns + ------- + str + the expression for use in an EPANET-MSX input file + """ + return "{} {} {} ;{}".format(self.expr_type.name.upper(), str(self.species), self.expression, self.note if self.note else "") + + +@dataclass(repr=False) +class RateDynamics(MSXDefinedDynamicsMixin, LinkedVariablesMixin, ExpressionMixin, ReactionDynamics): + note: str = None + variable_registry: InitVar[VariableRegistry] = field(default=None, compare=False) + + def __post_init__(self, variable_registry): + self._variable_registry = variable_registry + + @property + def expr_type(self) -> RxnExprType: + return RxnExprType.RATE + + def sympify(self): + raise NotImplementedError + + +@dataclass(repr=False) +class EquilibriumDynamics(MSXDefinedDynamicsMixin, LinkedVariablesMixin, ExpressionMixin, ReactionDynamics): + note: str = None + variable_registry: InitVar[VariableRegistry] = field(default=None, compare=False) + + def __post_init__(self, variable_registry): + self._variable_registry = variable_registry + + @property + def expr_type(self) -> RxnExprType: + return RxnExprType.EQUIL + + def sympify(self): + raise NotImplementedError + + +@dataclass(repr=False) +class FormulaDynamics(MSXDefinedDynamicsMixin, LinkedVariablesMixin, ExpressionMixin, ReactionDynamics): + note: str = None + variable_registry: InitVar[VariableRegistry] = field(default=None, compare=False) + + def __post_init__(self, variable_registry): + self._variable_registry = variable_registry + + @property + def expr_type(self) -> RxnExprType: + return RxnExprType.FORMULA + + def sympify(self): + raise NotImplementedError diff --git a/wntr/reaction/model.py b/wntr/reaction/model.py index 749053389..0ef920278 100644 --- a/wntr/reaction/model.py +++ b/wntr/reaction/model.py @@ -9,7 +9,7 @@ from collections.abc import MutableMapping from dataclasses import InitVar, dataclass, field, asdict from enum import Enum, IntFlag -from typing import Any, ClassVar, Dict, Generator, Hashable, Iterator, List, Set, Tuple, Union +from typing import Any, ClassVar, Dict, Generator, Hashable, Iterator, List, Literal, Set, Tuple, Union import sympy from sympy import Float, Symbol, symbols, init_printing @@ -17,18 +17,19 @@ from sympy.parsing.sympy_parser import standard_transformations, convert_xor from wntr.network.model import WaterNetworkModel -from .base import ReactionDynamics, ReactionVariable -from .variables import InternalVariable +from wntr.reaction.dynamics import EquilibriumDynamics, FormulaDynamics, RateDynamics +from .base import ReactionDynamics, ReactionVariable, VariableNameExistsError +from .variables import BulkSpecies, Coefficient, Constant, InternalVariable, NamedExpression, Parameter, Species, Term, WallSpecies from .options import RxnOptions -from .base import DynamicsRegistry, VariableRegistry, RxnExprType, RxnLocType, RxnVarType, DisjointMapping, RESERVED_NAMES, SYMPY_RESERVED +from .base import ReactionRegistry, VariableRegistry, RxnExprType, RxnLocType, RxnVarType, DisjointMapping, RESERVED_NAMES, SYMPY_RESERVED -class MultispeciesWaterQualityModel(DynamicsRegistry, VariableRegistry): - def __init__(self, title: str = None, desc: str = None, allow_sympy_reserved=False): +class WaterQualityReactionsModel(ReactionRegistry, VariableRegistry): + def __init__(self, wn: WaterNetworkModel = None, *, title: str = None, desc: str = None, allow_sympy_reserved=False): self.title: str = title self.desc: str = desc self.options = RxnOptions() - self._wn: WaterNetworkModel = None + self._wn: WaterNetworkModel = wn self._variables: Dict[str, ReactionVariable] = dict() self._species = DisjointMapping(self._variables) @@ -39,14 +40,39 @@ def __init__(self, title: str = None, desc: str = None, allow_sympy_reserved=Fal self._pipe_dynamics = DisjointMapping(self._dynamics) self._tank_dynamics = DisjointMapping(self._dynamics) + self._usage: Dict[str, Set[str]] = dict() + + self._sources: Dict[str, float] = dict() + self._inital_quality: Dict[Hashable, float] = dict() + self._wn: WaterNetworkModel = None + for name in RESERVED_NAMES: self._variables[name] = InternalVariable(name) if not allow_sympy_reserved: for name in SYMPY_RESERVED: self._variables[name] = InternalVariable(name) - def link_water_network_model(self, wn: WaterNetworkModel): - self._wn = wn + def _is_variable_registered(self, var_or_name: Union[str, ReactionVariable]) -> bool: + name = str(var_or_name) + if name in self._variables: + return True + return False + + @property + def variable_name_list(self) -> List[str]: + return list(self._variables.keys()) + + @property + def species_name_list(self) -> List[str]: + return list(self._species.keys()) + + @property + def coefficient_name_list(self) -> List[str]: + return list(self._coeff.keys()) + + @property + def other_term_name_list(self) -> List[str]: + return list(self._terms.keys()) def variables(self, var_type=None): var_type = RxnVarType.make(var_type) @@ -55,32 +81,150 @@ def variables(self, var_type=None): continue yield k, v - def dynamics(self, location=None): + def add_species(self, species_type: Union[str, Literal[RxnVarType.BULK], Literal[RxnVarType.WALL]], name: str, unit: str, atol: float = None, rtol: float = None, note: str = None) -> Species: + species_type = RxnVarType.make(species_type) + if species_type not in [RxnVarType.BULK, RxnVarType.WALL]: + raise ValueError('Species must be BULK or WALL, got {:s}'.format(species_type)) + if self._is_variable_registered(name): + raise VariableNameExistsError('The variable {} already exists in this model'.format(name)) + if (atol is None) ^ (rtol is None): + raise TypeError('atol and rtol must be the same type, got {} and {}'.format(atol, rtol)) + if species_type is RxnVarType.BULK: + var = BulkSpecies(name, unit, atol, rtol, note, self) + elif species_type is RxnVarType.WALL: + var = WallSpecies(name, unit, atol, rtol, note, self) + self._species[name] = var + return var + + def add_bulk_species(self, name: str, unit: str, atol: float = None, rtol: float = None, note: str = None) -> BulkSpecies: + return self.add_species(RxnVarType.BULK, name, unit, atol, rtol, note) + + def add_wall_species(self, name: str, unit: str, atol: float = None, rtol: float = None, note: str = None) -> WallSpecies: + return self.add_species(RxnVarType.WALL, name, unit, atol, rtol, note) + + def add_coefficient(self, coeff_type: Union[str, Literal[RxnVarType.CONST], Literal[RxnVarType.PARAM]], name: str, global_value: float, note: str=None, unit: str=None, **kwargs) -> Coefficient: + coeff_type = RxnVarType.make(coeff_type) + if coeff_type not in [RxnVarType.CONST, RxnVarType.PARAM]: + raise ValueError('Species must be CONST or PARAM, got {:s}'.format(coeff_type)) + if self._is_variable_registered(name): + raise VariableNameExistsError('The variable {} already exists in this model'.format(name)) + if coeff_type is RxnVarType.CONST: + var = Constant(name=name, global_value=global_value, note=note, unit=unit, variable_registry=self) + elif coeff_type is RxnVarType.PARAM: + var = Parameter(name=name, global_value=global_value, note=note, unit=unit, variable_registry=self, **kwargs) + self._coeff[name] = var + return var + + def add_constant_coeff(self, name: str, global_value: float, note: str=None, unit: str=None) -> Constant: + return self.add_coefficient(RxnVarType.CONST, name=name, global_value=global_value, note=note, unit=unit) + + def add_parameterized_coeff(self, name: str, global_value: float, note: str=None, unit: str=None, pipe_values: Dict[str, float] = None, tank_values: Dict[str, float] = None) -> Parameter: + return self.add_coefficient(RxnVarType.PARAM, name=name, global_value=global_value, note=note, unit=unit, _pipe_values=pipe_values, _tank_values=tank_values) + + def add_other_term(self, name: str, expression: str, note: str = None) -> NamedExpression: + if self._is_variable_registered(name): + raise VariableNameExistsError('The variable {} already exists in this model'.format(name)) + var = NamedExpression(name=name, expression=expression, note=note, variable_registry=self) + self._terms[name] = var + return var + + def del_variable(self, name: str): + return self._variables.__delitem__(name) + + def get_variable(self, name: str) -> ReactionVariable: + return self._variables[name] + + def reactions(self, location=None): location = RxnLocType.make(location) for k, v in self._dynamics.items(): if location is not None and v.location != location: continue yield k, v - - def add_dynamics(self, dyn: ReactionDynamics): - return super().add_dynamics(dyn) - - def add_variable(self, var: ReactionVariable): - return super().add_variable(var) - - def del_dynamics(self, species, location): - return super().del_dynamics(species, location) - - def del_variable(self, name: str): - return super().del_variable(name) - - def get_dynamics(self, species, location): + + def add_reaction(self, location: RxnLocType, species: Union[str, Species], dynamics: Union[str, int, RxnExprType], expression: str, note: str = None): + location = RxnLocType.make(location) + species = str(species) + _key = ReactionDynamics.to_key(species, location) + if _key in self._dynamics.keys(): + raise RuntimeError('The species {} already has a {} reaction defined. Use set_reaction instead.') + dynamics = RxnExprType.make(dynamics) + new = None + if dynamics is RxnExprType.EQUIL: + new = EquilibriumDynamics(species=species, location=location, expression=expression, note=note, variable_registry=self) + elif dynamics is RxnExprType.RATE: + new = RateDynamics(species=species, location=location, expression=expression, note=note, variable_registry=self) + elif dynamics is RxnExprType.FORMULA: + new = FormulaDynamics(species=species, location=location, expression=expression, note=note, variable_registry=self) + else: + raise ValueError('Invalid dynamics type, {}'.format(dynamics)) + if location is RxnLocType.PIPE: + self._pipe_dynamics[str(new)] = new + elif location is RxnLocType.TANK: + self._tank_dynamics[str(new)] = new + else: + raise ValueError('Invalid location type, {}'.format(location)) + return new + + def add_pipe_reaction(self, species: Union[str, Species], dynamics: Union[str, int, RxnExprType], expression: str, note: str = None) -> ReactionDynamics: + return self.add_reaction(RxnLocType.PIPE, species=species, dynamics=dynamics, expression=expression, note=note) + + def add_tank_reaction(self, species: Union[str, Species], dynamics: Union[str, int, RxnExprType], expression: str, note: str = None) -> ReactionDynamics: + return self.add_reaction(RxnLocType.TANK, species=species, dynamics=dynamics, expression=expression, note=note) + + def del_reaction(self, species: Union[str, Species], location: Union[str, int, RxnLocType, Literal['all']]): + if location != 'all': + location = RxnLocType.make(location) + species = str(species) + if location is None: + raise TypeError('location cannot be None when removing a reaction. Use "all" for all locations.') + elif location == 'all': + name = ReactionDynamics.to_key(species, RxnLocType.PIPE) + try: + self._pipe_dynamics.__delitem__(name) + except KeyError: + pass + name = ReactionDynamics.to_key(species, RxnLocType.TANK) + try: + self._tank_dynamics.__delitem__(name) + except KeyError: + pass + elif location is RxnLocType.PIPE: + name = ReactionDynamics.to_key(species, RxnLocType.PIPE) + try: + self._pipe_dynamics.__delitem__(name) + except KeyError: + pass + elif location is RxnLocType.TANK: + name = ReactionDynamics.to_key(species, RxnLocType.TANK) + try: + self._tank_dynamics.__delitem__(name) + except KeyError: + pass + else: + raise ValueError('Invalid location, {}'.format(location)) + + def get_reaction(self, species, location): species = str(species) location = RxnLocType.make(location) if location == RxnLocType.PIPE: return self._pipe_dynamics.get(species, None) elif location == RxnLocType.TANK: return self._tank_dynamics.get(species, None) - - def get_variable(self, name: str) -> ReactionVariable: - return self._variables[name] + + def init_printing(self, *args, **kwargs): + """Call sympy.init_printing(*args, **kwargs)""" + init_printing(*args, **kwargs) + + @property + def options(self) -> RxnOptions: + """The multispecies reaction model options.""" + return self._options + + @options.setter + def options(self, value): + if not isinstance(value, RxnOptions): + raise TypeError("Expected a RxnOptions object, got {}".format(type(value))) + self._options = value + + def link_water_network_model(self, wn: WaterNetworkModel): + self._wn = wn diff --git a/wntr/reaction/toolkitmsx.py b/wntr/reaction/toolkitmsx.py index 4310f283f..3eba00e1b 100644 --- a/wntr/reaction/toolkitmsx.py +++ b/wntr/reaction/toolkitmsx.py @@ -1,6 +1,14 @@ """ The wntr.reaction.toolkit module is a Python extension for the EPANET MSX Programmers Toolkit DLLs. + +.. note:: + + Code in this section taken from code originally written by Junli Hao 07/29/2018, + "EPANET-MSX-Python-wrapper" on GitHub, licensed under the BSD license. See LICENSE.txt for more + details. + + """ import ctypes import os diff --git a/wntr/reaction/variables.py b/wntr/reaction/variables.py new file mode 100644 index 000000000..ab79dc535 --- /dev/null +++ b/wntr/reaction/variables.py @@ -0,0 +1,212 @@ +import enum +import logging +from dataclasses import InitVar, asdict, dataclass, field +from enum import Enum, IntFlag +from typing import Any, ClassVar, Dict, List, Set, Tuple, Union + +import sympy +from sympy import Float, Function, Symbol, init_printing, symbols +from sympy.parsing import parse_expr +from sympy.parsing.sympy_parser import convert_xor, standard_transformations + +from wntr.network.model import WaterNetworkModel + +from .base import ExpressionMixin, LinkedVariablesMixin, VariableRegistry, ReactionVariable, RxnVarType, RESERVED_NAMES + +logger = logging.getLogger(__name__) + + +@dataclass(repr=False) +class Species(LinkedVariablesMixin, ReactionVariable): + + unit: str + atol: InitVar[float] = None + rtol: InitVar[float] = None + note: str = None + variable_registry: InitVar[VariableRegistry] = None + + def __post_init__(self, atol=None, rtol=None, reaction_model=None): + if isinstance(atol, property): atol=None + if isinstance(rtol, property): rtol=None + if self.name in RESERVED_NAMES: + raise ValueError('Name cannot be a reserved name') + if (atol is None) ^ (rtol is None): + raise TypeError('atol and rtol must be the same type, got {} and {}'.format(atol, rtol)) + self._atol = atol + self._rtol = rtol + self._variable_registry = reaction_model + + @property + def atol(self) -> float: + return self._atol + + @property + def rtol(self) -> float: + return self._rtol + + def get_tolerances(self) -> Union[Tuple[float, float], None]: + if self._atol is not None and self._rtol is not None: + return (self._atol, self._rtol) + return None + + def set_tolerances(self, atol: float, rtol: float): + if atol is None and rtol is None: + self._atol = self._rtol = None + return + try: + if not isinstance(atol, float): + atol = float(atol) + if not isinstance(rtol, float): + rtol = float(rtol) + except Exception as e: + raise TypeError('atol and rtol must be the same type, got {} and {}'.format(atol, rtol)) + if atol <= 0: + raise ValueError("Absolute tolerance atol must be greater than 0") + if rtol <= 0: + raise ValueError("Relative tolerance rtol must be greater than 0") + self._atol = atol + self._rtol = rtol + + def clear_tolerances(self): + self._atol = self._rtol = None + + def to_msx_string(self) -> str: + tols = self.get_tolerances() + if tols is None: + # tolstr = "{:<12s} {:<12s}".format("", "") + tolstr = '' + else: + #tolstr = "{:12.6g} {:12.6g}".format(*tols) + tolstr = "{} {}".format(*tols) + # return "{:<4s} {:<32s} {:s} {:s} ;{:s}".format( + return "{:s} {:s} {:s} {:s} ;{:s}".format( + self.var_type.name.upper(), + self.name, + self.unit, + tolstr, + self.note if self.note is not None else "", + ) + + def __repr__(self): + return "{}(name={}, unit={}, atol={}, rtol={}, note={})".format( + self.__class__.__name__, repr(self.name), repr(self.unit), self.atol, self.rtol, repr(self.note) + ) + + +@dataclass(repr=False) +class BulkSpecies(Species): + @property + def var_type(self) -> RxnVarType: + return RxnVarType.BULK + + +@dataclass(repr=False) +class WallSpecies(Species): + @property + def var_type(self) -> RxnVarType: + return RxnVarType.WALL + + +@dataclass(repr=False) +class Coefficient(LinkedVariablesMixin, ReactionVariable): + + global_value: float + note: str = None + unit: str = None + variable_registry: InitVar[VariableRegistry] = None + + def __post_init__(self, reaction_model): + if self.name in RESERVED_NAMES: + raise ValueError('Name cannot be a reserved name') + self._variable_registry = reaction_model + + def get_value(self) -> float: + return self.global_value + + def to_msx_string(self) -> str: + # return "{:<6s} {:<32s} {:g};{:s}".format( + return "{:s} {:s} {} ;{:s}".format( + self.var_type.name.upper(), + self.name, + self.global_value, + self.note if self.note is not None else "", + ) + + def __repr__(self): + return "{}(name={}, global_value={}, unit={}, note={})".format(self.__class__.__name__, repr(self.name), repr(self.global_value), repr(self.unit), repr(self.note)) + + +@dataclass(repr=False) +class Constant(Coefficient): + @property + def var_type(self) -> RxnVarType: + return RxnVarType.CONST + + +@dataclass(repr=False) +class Parameter(Coefficient): + + _pipe_values: Dict[str, float] = field(default_factory=dict) + _tank_values: Dict[str, float] = field(default_factory=dict) + + @property + def var_type(self) -> RxnVarType: + return RxnVarType.PARAM + + def get_value(self, pipe: str = None, tank: str = None) -> float: + if pipe is not None and tank is not None: + raise TypeError("Cannot get a value for a pipe and tank at the same time - one or both must be None") + if pipe is not None: + return self._pipe_values.get(pipe, self.global_value) + if tank is not None: + return self._tank_values.get(tank, self.global_value) + return self.global_value + + @property + def pipe_values(self) -> Dict[str, float]: + return self._pipe_values + + @property + def tank_values(self) -> Dict[str, float]: + return self._tank_values + + +@dataclass(repr=False) +class NamedExpression(LinkedVariablesMixin, ExpressionMixin, ReactionVariable): + + note: str = None + variable_registry: InitVar[VariableRegistry] = field(default=None, compare=False) + + def __post_init__(self, reaction_model): + if self.name in RESERVED_NAMES: + raise ValueError('Name cannot be a reserved name') + self._variable_registry = reaction_model + + @property + def var_type(self) -> RxnVarType: + return RxnVarType.TERM + + def sympify(self): + raise NotImplementedError + + def to_msx_string(self) -> str: + return "{:s} {:s} ;{:s}".format(self.name, self.expression, self.note if self.note is not None else "") + + def __repr__(self): + return "{}(name={}, expression={}, note={})".format(self.__class__.__name__, repr(self.name), repr(self.expression), repr(self.note)) + + +Term = NamedExpression + + +class InternalVariable(ReactionVariable): + + @property + def var_type(self) -> RxnVarType: + return RxnVarType.INTERNAL + + def to_msx_string(self) -> str: + raise TypeError("InternalVariable is not output to an MSX input file") + + def __repr__(self): + return "{}(name={})".format(self.__class__.__name__, repr(self.name)) diff --git a/wntr/tests/test_reactions.py b/wntr/tests/test_reactions.py index 6fc835448..63fe33b9e 100644 --- a/wntr/tests/test_reactions.py +++ b/wntr/tests/test_reactions.py @@ -23,56 +23,48 @@ def setUpClass(self): def tearDownClass(self): pass - def test_RxnVariable_reserved_name_exception(self): - self.assertRaises(ValueError, wntr.reaction.model.RxnVariable, "I") - self.assertRaises(ValueError, wntr.reaction.model.RxnSpecies, "Ff", "mg") + def test_ReactionVariable_reserved_name_exception(self): self.assertRaises(ValueError, wntr.reaction.model.BulkSpecies, "D", "mg") self.assertRaises(ValueError, wntr.reaction.model.WallSpecies, "Q", "mg") - self.assertRaises(ValueError, wntr.reaction.model.RxnCoefficient, "Re", 0.52) - - def test_RxnVariable_direct_instantiation_exceptions(self): - self.assertRaises(NotImplementedError, wntr.reaction.model.RxnVariable, "Test") - self.assertRaises(NotImplementedError, wntr.reaction.model.RxnSpecies, "Test", "mg/L") - self.assertRaises(NotImplementedError, wntr.reaction.model.RxnCoefficient, "Test", 0.524) + self.assertRaises(ValueError, wntr.reaction.model.Constant, "Re", 0.52) + self.assertRaises(ValueError, wntr.reaction.model.Parameter, "Re", 0.52) + self.assertRaises(ValueError, wntr.reaction.model.NamedExpression, "Re", 0.52) def test_RxnVariable_symbols_and_sympy(self): species1 = wntr.reaction.model.BulkSpecies("Cl", "mg") symbol1 = sympy.symbols("Cl") self.assertEqual(species1.symbol, symbol1) - const1 = wntr.reaction.model.ConstantCoeff("Kb", 0.482) + const1 = wntr.reaction.model.Constant("Kb", 0.482) symbol2 = sympy.symbols("Kb") self.assertEqual(const1.symbol, symbol2) - param1 = wntr.reaction.model.ConstantCoeff("Ka", 0.482) + param1 = wntr.reaction.model.Constant("Ka", 0.482) symbol3 = sympy.symbols("Ka") self.assertEqual(param1.symbol, symbol3) - term1 = wntr.reaction.model.FunctionalTerm("T0", "-3.2 * Kb * Cl^2", note="bar") + term1 = wntr.reaction.model.NamedExpression("T0", "-3.2 * Kb * Cl^2", note="bar") symbol4 = sympy.symbols("T0") self.assertEqual(term1.symbol, symbol4) def test_RxnVariable_values(self): - species1 = wntr.reaction.model.BulkSpecies("Cl", "mg") - self.assertEqual(species1.get_value(), species1.value) - self.assertRaises(TypeError, species1.get_value, pipe="blah") - const1 = wntr.reaction.model.ConstantCoeff("Kb", 0.482, note="test") - self.assertEqual(const1.get_value(), const1.value) + const1 = wntr.reaction.model.Constant("Kb", 0.482, note="test") + self.assertEqual(const1.get_value(), const1.global_value) test_pipe_dict = {"PIPE": 0.38} test_tank_dict = {"TANK": 222.23} - param2 = wntr.reaction.model.ParameterizedCoeff("Kb", 0.482, note="test", pipe_values=test_pipe_dict, tank_values=test_tank_dict) + param2 = wntr.reaction.model.Parameter("Kb", 0.482, note="test", _pipe_values=test_pipe_dict, _tank_values=test_tank_dict) self.assertEqual(param2.get_value(), param2.global_value) self.assertEqual(param2.get_value(pipe="PIPE"), test_pipe_dict["PIPE"]) self.assertEqual(param2.get_value(pipe="FOO"), param2.global_value) self.assertEqual(param2.get_value(tank="TANK"), test_tank_dict["TANK"]) - self.assertRaises(ValueError, param2.get_value, pipe="PIPE", tank="TANK") + self.assertRaises(TypeError, param2.get_value, pipe="PIPE", tank="TANK") def test_RxnVariable_string_functions(self): species1 = wntr.reaction.model.BulkSpecies("Cl", "mg") species2 = wntr.reaction.model.WallSpecies("Cl", "mg", 0.01, 0.0001, note="Testing stuff") - const1 = wntr.reaction.model.ConstantCoeff("Kb", 0.482) - param1 = wntr.reaction.model.ParameterizedCoeff("Ka", 0.482, note="foo") - term1 = wntr.reaction.model.FunctionalTerm("T0", "-3.2 * Kb * Cl^2", note="bar") + const1 = wntr.reaction.model.Constant("Kb", 0.482) + param1 = wntr.reaction.model.Parameter("Ka", 0.482, note="foo") + term1 = wntr.reaction.model.NamedExpression("T0", "-3.2 * Kb * Cl^2", note="bar") self.assertEqual(str(species1), "Cl") self.assertEqual(species1.to_msx_string(), "BULK Cl mg ;") @@ -84,7 +76,7 @@ def test_RxnVariable_string_functions(self): self.assertEqual(str(term1), "T0") self.assertEqual(term1.to_msx_string(), "T0 -3.2 * Kb * Cl^2 ;bar") - def test_RxnSpecies_tolerances(self): + def test_Species_tolerances(self): # """RxnSpecies(*s) tolerance settings""" species1 = wntr.reaction.model.BulkSpecies("Cl", "mg") species2 = wntr.reaction.model.WallSpecies("Cl", "mg", 0.01, 0.0001, note="Testing stuff") @@ -95,174 +87,164 @@ def test_RxnSpecies_tolerances(self): self.assertRaises(ValueError, species1.set_tolerances, -0.51, 0.01) self.assertRaises(ValueError, species1.set_tolerances, 0.0, 0.0) species1.set_tolerances(0.01, 0.0001) - self.assertEqual(species1.Atol, 0.01) - self.assertEqual(species1.Rtol, 0.0001) + self.assertEqual(species1.atol, 0.01) + self.assertEqual(species1.rtol, 0.0001) species1.set_tolerances(None, None) - self.assertIsNone(species1.Atol) - self.assertIsNone(species1.Rtol) + self.assertIsNone(species1.atol) + self.assertIsNone(species1.rtol) species2.clear_tolerances() - self.assertIsNone(species1.Atol) - self.assertIsNone(species1.Rtol) + self.assertIsNone(species1.atol) + self.assertIsNone(species1.rtol) self.assertIsNone(species2.get_tolerances()) def test_BulkSpecies_creation(self): # """BlukSpecies object creation (direct instantiation)""" - self.assertRaises(TypeError, wntr.reaction.model.BulkSpecies, "I") - self.assertRaises(ValueError, wntr.reaction.model.BulkSpecies, "I", "mg") - self.assertRaises(ValueError, wntr.reaction.model.BulkSpecies, "Cl", "mg", 0.01) - self.assertRaises(ValueError, wntr.reaction.model.BulkSpecies, "Cl", "mg", None, 0.01) + self.assertRaises(TypeError, wntr.reaction.model.BulkSpecies, "Re") + self.assertRaises(ValueError, wntr.reaction.model.BulkSpecies, "Re", "mg") + self.assertRaises(TypeError, wntr.reaction.model.BulkSpecies, "Cl", "mg", 0.01) + self.assertRaises(TypeError, wntr.reaction.model.BulkSpecies, "Cl", "mg", None, 0.01) species = wntr.reaction.model.BulkSpecies("Cl", "mg") self.assertEqual(species.name, "Cl") - self.assertEqual(species.value, "mg") - self.assertEqual(species.value, species.unit) - self.assertEqual(species.species_type, wntr.reaction.model.RxnVarType.Bulk) - self.assertIsNone(species.Atol) - self.assertIsNone(species.Rtol) + self.assertEqual(species.unit, "mg") + self.assertEqual(species.var_type, wntr.reaction.model.RxnVarType.BULK) + self.assertIsNone(species.atol) + self.assertIsNone(species.rtol) self.assertIsNone(species.note) species = wntr.reaction.model.BulkSpecies("Cl", "mg", 0.01, 0.0001, note="Testing stuff") - self.assertEqual(species.variable_type, wntr.reaction.model.RxnVarType.Bulk) + self.assertEqual(species.var_type, wntr.reaction.model.RxnVarType.BULK) self.assertEqual(species.name, "Cl") - self.assertEqual(species.value, "mg") - self.assertEqual(species.Atol, 0.01) - self.assertEqual(species.Rtol, 0.0001) + self.assertEqual(species.unit, "mg") + self.assertEqual(species.atol, 0.01) + self.assertEqual(species.rtol, 0.0001) self.assertEqual(species.note, "Testing stuff") def test_WallSpecies_creation(self): # """WallSpecies object creation (direct instantiation)""" - self.assertRaises(TypeError, wntr.reaction.model.WallSpecies, "I") - self.assertRaises(ValueError, wntr.reaction.model.WallSpecies, "I", "mg") - self.assertRaises(ValueError, wntr.reaction.model.WallSpecies, "Cl", "mg", 0.01) - self.assertRaises(ValueError, wntr.reaction.model.WallSpecies, "Cl", "mg", None, 0.01) + self.assertRaises(TypeError, wntr.reaction.model.WallSpecies, "Re") + self.assertRaises(ValueError, wntr.reaction.model.WallSpecies, "Re", "mg") + self.assertRaises(TypeError, wntr.reaction.model.WallSpecies, "Cl", "mg", 0.01) + self.assertRaises(TypeError, wntr.reaction.model.WallSpecies, "Cl", "mg", None, 0.01) species = wntr.reaction.model.WallSpecies("Cl", "mg") self.assertEqual(species.name, "Cl") - self.assertEqual(species.value, "mg") - self.assertEqual(species.value, species.unit) - self.assertEqual(species.species_type, wntr.reaction.model.RxnVarType.Wall) - self.assertIsNone(species.Atol) - self.assertIsNone(species.Rtol) + self.assertEqual(species.unit, "mg") + self.assertEqual(species.var_type, wntr.reaction.model.RxnVarType.WALL) + self.assertIsNone(species.atol) + self.assertIsNone(species.rtol) self.assertIsNone(species.note) species = wntr.reaction.model.WallSpecies("Cl", "mg", 0.01, 0.0001, note="Testing stuff") - self.assertEqual(species.variable_type, wntr.reaction.model.RxnVarType.Wall) + self.assertEqual(species.var_type, wntr.reaction.model.RxnVarType.WALL) self.assertEqual(species.name, "Cl") - self.assertEqual(species.value, "mg") - self.assertEqual(species.Atol, 0.01) - self.assertEqual(species.Rtol, 0.0001) + self.assertEqual(species.unit, "mg") + self.assertEqual(species.atol, 0.01) + self.assertEqual(species.rtol, 0.0001) self.assertEqual(species.note, "Testing stuff") def test_Constant_creation(self): - self.assertRaises(TypeError, wntr.reaction.model.ConstantCoeff, "Re") - self.assertRaises(ValueError, wntr.reaction.model.ConstantCoeff, "Re", 2.48) - const1 = wntr.reaction.model.ConstantCoeff("Kb", 0.482, note="test") + self.assertRaises(TypeError, wntr.reaction.model.Constant, "Re") + self.assertRaises(ValueError, wntr.reaction.model.Constant, "Re", 2.48) + const1 = wntr.reaction.model.Constant("Kb", 0.482, note="test") # FIXME: Find a way to suppress warning printing # self.assertWarns(RuntimeWarning, wntr.reaction.model.Constant, 'Kb1', 0.83, pipe_values={'a',1}) self.assertEqual(const1.name, "Kb") self.assertEqual(const1.global_value, 0.482) - self.assertEqual(const1.value, const1.global_value) - self.assertEqual(const1.coeff_type, wntr.reaction.model.RxnVarType.Constant) + self.assertEqual(const1.get_value(), const1.global_value) + self.assertEqual(const1.var_type, wntr.reaction.model.RxnVarType.CONST) self.assertEqual(const1.note, "test") def test_Parameter_creation(self): - self.assertRaises(TypeError, wntr.reaction.model.ParameterizedCoeff, "Re") - self.assertRaises(ValueError, wntr.reaction.model.ParameterizedCoeff, "Re", 2.48) - param1 = wntr.reaction.model.ParameterizedCoeff("Kb", 0.482, note="test") + self.assertRaises(TypeError, wntr.reaction.model.Parameter, "Re") + self.assertRaises(ValueError, wntr.reaction.model.Parameter, "Re", 2.48) + param1 = wntr.reaction.model.Parameter("Kb", 0.482, note="test") self.assertEqual(param1.name, "Kb") self.assertEqual(param1.global_value, 0.482) - self.assertEqual(param1.value, param1.global_value) - self.assertEqual(param1.coeff_type, wntr.reaction.model.RxnVarType.Parameter) + self.assertEqual(param1.get_value(), param1.global_value) + self.assertEqual(param1.var_type, wntr.reaction.model.RxnVarType.PARAM) self.assertEqual(param1.note, "test") test_pipe_dict = {"PIPE": 0.38} test_tank_dict = {"TANK": 222.23} - param2 = wntr.reaction.model.ParameterizedCoeff("Kb", 0.482, note="test", pipe_values=test_pipe_dict, tank_values=test_tank_dict) + param2 = wntr.reaction.model.Parameter("Kb", 0.482, note="test", _pipe_values=test_pipe_dict, _tank_values=test_tank_dict) self.assertDictEqual(param2.pipe_values, test_pipe_dict) self.assertDictEqual(param2.tank_values, test_tank_dict) def test_RxnTerm_creation(self): - self.assertRaises(TypeError, wntr.reaction.model.FunctionalTerm, "Re") - self.assertRaises(ValueError, wntr.reaction.model.FunctionalTerm, "Re", "1.0*Re") - term1 = wntr.reaction.model.FunctionalTerm("T0", "-3.2 * Kb * Cl^2", note="bar") + self.assertRaises(TypeError, wntr.reaction.model.NamedExpression, "Re") + self.assertRaises(ValueError, wntr.reaction.model.NamedExpression, "Re", "1.0*Re") + term1 = wntr.reaction.model.NamedExpression("T0", "-3.2 * Kb * Cl^2", note="bar") self.assertEqual(term1.name, "T0") self.assertEqual(term1.expression, "-3.2 * Kb * Cl^2") - self.assertEqual(term1.variable_type, wntr.reaction.model.RxnVarType.Term) + self.assertEqual(term1.var_type, wntr.reaction.model.RxnVarType.TERM) self.assertEqual(term1.note, "bar") - self.assertEqual(term1.value, term1.expression) - - def test_RxnExpression_direct_instantiation_exceptions(self): - self.assertRaises(TypeError, wntr.reaction.model.RxnExpression, "Cl", wntr.reaction.model.RxnLocType.Pipes) - self.assertRaises(NotImplementedError, wntr.reaction.model.RxnExpression, "Cl", wntr.reaction.model.RxnLocType.Pipes, "-Ka + Kb * Cl + T0") - self.assertRaises(TypeError, wntr.reaction.model.RxnExpression, "Cl") - self.assertRaises(TypeError, wntr.reaction.model.RxnExpression, "Cl", 39) - self.assertRaises(TypeError, wntr.reaction.model.RxnExpression, "Cl", 39, "-Ka + Kb * Cl + T0") def test_RxnExpression_strings(self): - equil1 = wntr.reaction.model.EquilibriumExpression("Cl", wntr.reaction.model.RxnLocType.Pipes, "-Ka + Kb * Cl + T0") - rate1 = wntr.reaction.model.RateExpression("Cl", wntr.reaction.model.RxnLocType.Tanks, "-Ka + Kb * Cl + T0", note="Foo Bar") - formula1 = wntr.reaction.model.FormulaExpression("Cl", wntr.reaction.model.RxnLocType.Pipes, "-Ka + Kb * Cl + T0") + equil1 = wntr.reaction.model.EquilibriumDynamics("Cl", wntr.reaction.model.RxnLocType.PIPE, "-Ka + Kb * Cl + T0") + rate1 = wntr.reaction.model.RateDynamics("Cl", wntr.reaction.model.RxnLocType.TANK, "-Ka + Kb * Cl + T0", note="Foo Bar") + formula1 = wntr.reaction.model.FormulaDynamics("Cl", wntr.reaction.model.RxnLocType.PIPE, "-Ka + Kb * Cl + T0") self.assertEqual(equil1.to_msx_string(), "EQUIL Cl -Ka + Kb * Cl + T0 ;") self.assertEqual(rate1.to_msx_string(), "RATE Cl -Ka + Kb * Cl + T0 ;Foo Bar") self.assertEqual(formula1.to_msx_string(), "FORMULA Cl -Ka + Kb * Cl + T0 ;") def test_Equilibrium_creation(self): - equil1 = wntr.reaction.model.EquilibriumExpression("Cl", wntr.reaction.model.RxnLocType.Pipes, "-Ka + Kb * Cl + T0") + equil1 = wntr.reaction.model.EquilibriumDynamics("Cl", wntr.reaction.model.RxnLocType.PIPE, "-Ka + Kb * Cl + T0") self.assertEqual(equil1.species, "Cl") self.assertEqual(equil1.expression, "-Ka + Kb * Cl + T0") - self.assertEqual(equil1.expression_type, wntr.reaction.model.RxnExprType.Equil) + self.assertEqual(equil1.expr_type, wntr.reaction.model.RxnExprType.EQUIL) def test_Rate_creation(self): - rate1 = wntr.reaction.model.RateExpression("Cl", wntr.reaction.model.RxnLocType.Tanks, "-Ka + Kb * Cl + T0", note="Foo Bar") + rate1 = wntr.reaction.model.RateDynamics("Cl", wntr.reaction.model.RxnLocType.TANK, "-Ka + Kb * Cl + T0", note="Foo Bar") self.assertEqual(rate1.species, "Cl") self.assertEqual(rate1.expression, "-Ka + Kb * Cl + T0") - self.assertEqual(rate1.expression_type, wntr.reaction.model.RxnExprType.Rate) + self.assertEqual(rate1.expr_type, wntr.reaction.model.RxnExprType.RATE) self.assertEqual(rate1.note, "Foo Bar") def test_Formula_creation(self): - formula1 = wntr.reaction.model.FormulaExpression("Cl", wntr.reaction.model.RxnLocType.Pipes, "-Ka + Kb * Cl + T0") + formula1 = wntr.reaction.model.FormulaDynamics("Cl", wntr.reaction.model.RxnLocType.PIPE, "-Ka + Kb * Cl + T0") self.assertEqual(formula1.species, "Cl") self.assertEqual(formula1.expression, "-Ka + Kb * Cl + T0") - self.assertEqual(formula1.expression_type, wntr.reaction.model.RxnExprType.Formula) + self.assertEqual(formula1.expr_type, wntr.reaction.model.RxnExprType.FORMULA) def test_WaterQualityReactionsModel_creation_specific_everything(self): rxn_model1 = wntr.reaction.model.WaterQualityReactionsModel() bulk1 = wntr.reaction.model.BulkSpecies("Cl", "mg") wall1 = wntr.reaction.model.WallSpecies("ClOH", "mg", 0.01, 0.0001, note="Testing stuff") - const1 = wntr.reaction.model.ConstantCoeff("Kb", 0.482) - param1 = wntr.reaction.model.ParameterizedCoeff("Ka", 0.482, note="foo") - term1 = wntr.reaction.model.FunctionalTerm("T0", "-3.2 * Kb * Cl^2", note="bar") - equil1 = wntr.reaction.model.EquilibriumExpression(bulk1, wntr.reaction.model.RxnLocType.Pipes, "-Ka + Kb * Cl + T0") - rate1 = wntr.reaction.model.RateExpression(bulk1, wntr.reaction.model.RxnLocType.Tanks, "-Ka + Kb * Cl + T0", note="Foo Bar") - formula1 = wntr.reaction.model.FormulaExpression(wall1, wntr.reaction.model.RxnLocType.Pipes, "-Ka + Kb * Cl + T0") + const1 = wntr.reaction.model.Constant("Kb", 0.482) + param1 = wntr.reaction.model.Parameter("Ka", 0.482, note="foo") + term1 = wntr.reaction.model.NamedExpression("T0", "-3.2 * Kb * Cl^2", note="bar") + equil1 = wntr.reaction.model.EquilibriumDynamics(bulk1, wntr.reaction.model.RxnLocType.PIPE, "-Ka + Kb * Cl + T0") + rate1 = wntr.reaction.model.RateDynamics(bulk1, wntr.reaction.model.RxnLocType.TANK, "-Ka + Kb * Cl + T0", note="Foo Bar") + formula1 = wntr.reaction.model.FormulaDynamics(wall1, wntr.reaction.model.RxnLocType.PIPE, "-Ka + Kb * Cl + T0") bulk2 = rxn_model1.add_bulk_species("Cl", "mg") wall2 = rxn_model1.add_wall_species("ClOH", "mg", 0.01, 0.0001, note="Testing stuff") - const2 = rxn_model1.add_constant("Kb", 0.482) - param2 = rxn_model1.add_parameter("Ka", 0.482, note="foo") - term2 = rxn_model1.add_term("T0", "-3.2 * Kb * Cl^2", note="bar") + const2 = rxn_model1.add_constant_coeff("Kb", 0.482) + param2 = rxn_model1.add_parameterized_coeff("Ka", 0.482, note="foo") + term2 = rxn_model1.add_other_term("T0", "-3.2 * Kb * Cl^2", note="bar") equil2 = rxn_model1.add_pipe_reaction("Cl", "equil", "-Ka + Kb * Cl + T0") - rate2 = rxn_model1.add_tank_reaction("Cl", wntr.reaction.model.RxnExprType.Rate, "-Ka + Kb * Cl + T0", note="Foo Bar") - formula2 = rxn_model1.add_reaction("pipes", "ClOH", "formula", "-Ka + Kb * Cl + T0") + rate2 = rxn_model1.add_tank_reaction("Cl", wntr.reaction.model.RxnExprType.R, "-Ka + Kb * Cl + T0", note="Foo Bar") + formula2 = rxn_model1.add_reaction("PIPE", "ClOH", "formula", "-Ka + Kb * Cl + T0") self.assertEqual(bulk1, bulk2) self.assertEqual(wall1, wall2) self.assertEqual(const1, const2) - self.assertEqual(param1, param2) + # self.assertEqual(param1, param2) # No good way to compare dicts inside self.assertEqual(term1, term2) - self.assertEqual(equil1, equil2) - self.assertEqual(rate1, rate2) - self.assertEqual(formula1, formula2) + # self.assertEqual(equil1, equil2) + # self.assertEqual(rate1, rate2) + # self.assertEqual(formula1, formula2) def test_WaterQualityReactionsModel_creation_generic_species_coeffs(self): bulk1 = wntr.reaction.model.BulkSpecies("Cl", "mg") wall1 = wntr.reaction.model.WallSpecies("ClOH", "mg", 0.01, 0.0001, note="Testing stuff") - const1 = wntr.reaction.model.ConstantCoeff("Kb", 0.482) - param1 = wntr.reaction.model.ParameterizedCoeff("Ka", 0.482, note="foo") - term1 = wntr.reaction.model.FunctionalTerm("T0", "-3.2 * Kb * Cl^2", note="bar") + const1 = wntr.reaction.model.Constant("Kb", 0.482) + param1 = wntr.reaction.model.Parameter("Ka", 0.482, note="foo") + term1 = wntr.reaction.model.NamedExpression("T0", "-3.2 * Kb * Cl^2", note="bar") rxn_model2 = wntr.reaction.model.WaterQualityReactionsModel() - self.assertRaises(ValueError, rxn_model2.add_species, wntr.reaction.model.RxnVarType.Species, "Cl", "mg") + self.assertRaises(ValueError, rxn_model2.add_species, wntr.reaction.model.RxnVarType.CONST, "Cl", "mg") self.assertRaises(TypeError, rxn_model2.add_coefficient, None, "Kb", 0.482) self.assertRaises(ValueError, rxn_model2.add_coefficient, "Wall", "Kb", 0.482) - bulk3 = rxn_model2.add_species("Bulk", "Cl", "mg") - wall3 = rxn_model2.add_species(wntr.reaction.model.RxnVarType.Wall, "ClOH", "mg", 0.01, 0.0001, note="Testing stuff") + bulk3 = rxn_model2.add_species("BULK", "Cl", "mg") + wall3 = rxn_model2.add_species(wntr.reaction.model.RxnVarType.WALL, "ClOH", "mg", 0.01, 0.0001, note="Testing stuff") const3 = rxn_model2.add_coefficient("Consolation", "Kb", 0.482) param3 = rxn_model2.add_coefficient(wntr.reaction.model.RxnVarType.P, "Ka", 0.482, note="foo") @@ -271,30 +253,6 @@ def test_WaterQualityReactionsModel_creation_generic_species_coeffs(self): self.assertEqual(const3, const1) self.assertEqual(param3, param1) - def test_WaterQualityReactionsModel_creation_generic_variables_reactions(self): - bulk1 = wntr.reaction.model.BulkSpecies("Cl", "mg") - wall1 = wntr.reaction.model.WallSpecies("ClOH", "mg", 0.01, 0.0001, note="Testing stuff") - const1 = wntr.reaction.model.ConstantCoeff("Kb", 0.482) - param1 = wntr.reaction.model.ParameterizedCoeff("Ka", 0.482, note="foo") - term1 = wntr.reaction.model.FunctionalTerm("T0", "-3.2 * Kb * Cl^2", note="bar") - - rxn_model2 = wntr.reaction.model.WaterQualityReactionsModel() - - self.assertRaises(ValueError, rxn_model2.add_variable, wntr.reaction.model.RxnVarType.Species, "Cl", "mg") - self.assertRaises(ValueError, rxn_model2.add_variable, None, "Kb", 0.482) - - bulk3 = rxn_model2.add_variable("Bulk", "Cl", "mg") - wall3 = rxn_model2.add_variable(wntr.reaction.model.RxnVarType.Wall, "ClOH", "mg", 0.01, 0.0001, note="Testing stuff") - const3 = rxn_model2.add_variable("Consolation", "Kb", 0.482) - param3 = rxn_model2.add_variable(wntr.reaction.model.RxnVarType.P, "Ka", 0.482, note="foo") - term3 = rxn_model2.add_variable("tErM", "T0", "-3.2 * Kb * Cl^2", note="bar") - - self.assertEqual(bulk3, bulk1) - self.assertEqual(wall3, wall1) - self.assertEqual(const3, const1) - self.assertEqual(param3, param1) - self.assertEqual(term3, term1) - if __name__ == "__main__": unittest.main(verbosity=2) From b37a1d555ab0b320a28d7a022fa3fcac88681e51 Mon Sep 17 00:00:00 2001 From: dbhart Date: Mon, 28 Aug 2023 08:13:12 -0600 Subject: [PATCH 08/75] Update to core reactions model codes --- wntr/reaction/base.py | 285 ++++++++++++++++++++++++++++------- wntr/reaction/dynamics.py | 2 +- wntr/reaction/library.py | 128 ++++++++++++++-- wntr/reaction/model.py | 134 ++++++++++------ wntr/reaction/options.py | 6 +- wntr/reaction/variables.py | 42 +++--- wntr/tests/test_reactions.py | 16 +- 7 files changed, 468 insertions(+), 145 deletions(-) diff --git a/wntr/reaction/base.py b/wntr/reaction/base.py index 5f17d58a3..c95521f03 100644 --- a/wntr/reaction/base.py +++ b/wntr/reaction/base.py @@ -5,7 +5,8 @@ import logging from dataclasses import InitVar, asdict, dataclass, field from enum import Enum, IntFlag -from typing import Any, ClassVar, Dict, Generator, ItemsView, Iterator, KeysView, List, Set, Tuple, Union, ValuesView +from typing import Any, ClassVar, Dict, Generator, ItemsView, Iterator, KeysView, List, Set, Tuple, Union, ValuesView, Hashable +import datetime import sympy from sympy import Float, Symbol, init_printing, symbols, Function @@ -18,16 +19,105 @@ logger = logging.getLogger(__name__) -RESERVED_NAMES = ("D", "Q", "U", "Re", "Us", "Ff", "Av") +HYDRAULIC_VARIABLES = [ + {"name": "D", "note": "pipe diameter (feet or meters) "}, + { + "name": "Kc", + "note": "pipe roughness coefcient (unitless for Hazen-Williams or Chezy-Manning head loss formulas, millifeet or millimeters for Darcy-Weisbach head loss formula)", + }, + {"name": "Q", "note": "pipe flow rate (flow units) "}, + {"name": "U", "note": "pipe flow velocity (ft/sec or m/sec) "}, + {"name": "Re", "note": "flow Reynolds number "}, + {"name": "Us", "note": "pipe shear velocity (ft/sec or m/sec) "}, + {"name": "Ff", "note": "Darcy-Weisbach friction factor "}, + {"name": "Av", "note": "Surface area per unit volume (area units/L) "}, + {"name": "Len", "note": "Pipe length (feet or meters)"}, +] +RESERVED_NAMES = tuple([v['name'] for v in HYDRAULIC_VARIABLES]) SYMPY_RESERVED = ("E", "I", "pi") EXPR_TRANSFORMS = standard_transformations + (convert_xor,) -class KeyInOtherDictError(KeyError): +@dataclass +class Citation: + title: str + year: int + author: str = None + + # citation type/subtype (e.g., "report"/"tech. rep.") + citationtype: str = 'misc' + citationsubtype: str = None + + # document identifiers + doi: str = None + url: str = None + isrn: str = None + isbn: str = None + issn: str = None + eprint: str = None + + # container titles + journaltitle: str = None + maintitle: str = None + booktitle: str = None + issuetitle: str = None + + # conference/proceedings info + eventtitle: str = None + eventdate: datetime.date = None + venue: str = None + + # publishing info + institution: str = None + organization: str = None + publisher: str = None + location: str = None + howpublished: str = None + language: str = None + origlanguage: str = None + + # additional people + editor: str = None + bookauthor: str = None + translator: str = None + annotator: str = None + commentator: str = None + introduction: str = None + foreword: str = None + afterword: str = None + + # identifying info + issue: str = None + series: str = None + volume: str = None + number: str = None + part: str = None + edition: str = None + version: str = None + chapter: str = None + pages: str = None + volumes: str = None + pagetotal: str = None + + # dates + month: str = None + fulldate: datetime.date = None + urldate: datetime.date = None + + # extra + note: str = None + addendum: str = None + abstract: str = None + annotation: str = None + + +class KeyInOtherGroupError(KeyError): pass + class VariableNameExistsError(KeyError): pass + class RxnVarType(Enum): """The type of reaction variable. @@ -80,8 +170,8 @@ class RxnVarType(Enum): """Alias for :attr:`Parameter`""" @classmethod - def make(cls, value: Union[str, int, 'RxnVarType']): - if value is None: + def make(cls, value: Union[str, int, "RxnVarType"]): + if value is None: return if isinstance(value, cls): return value @@ -119,8 +209,8 @@ class RxnLocType(Enum): """Alias for :attr:`Tanks`""" @classmethod - def make(cls, value: Union[str, int, 'RxnLocType']): - if value is None: + def make(cls, value: Union[str, int, "RxnLocType"]): + if value is None: return if isinstance(value, cls): return value @@ -163,8 +253,8 @@ class RxnExprType(Enum): """Alias for :attr:`Formula`""" @classmethod - def make(cls, value: Union[str, int, 'RxnExprType']): - if value is None: + def make(cls, value: Union[str, int, "RxnExprType"]): + if value is None: return if isinstance(value, cls): return value @@ -179,6 +269,103 @@ def make(cls, value: Union[str, int, 'RxnExprType']): class DisjointMapping(MutableMapping): + + __data: Dict[Hashable, Hashable] = None + __key_groupnames: Dict[Hashable, str] = None + __groups: Dict[str, "DisjointMappingGroup"] = None + __usage: Dict[Hashable, Set[Any]] = None + + def __init__(self, *args, **kwargs): + self.__data: Dict[Hashable, Any] = dict(*args, **kwargs) + self.__key_groupnames: Dict[Hashable, str] = dict() + self.__groups: Dict[str, "DisjointMappingGroup"] = dict() + self.__usage: Dict[Hashable, Set[Any]] = dict() + for k, v in self.__data.items(): + self.__key_groupnames[k] = None + self.__usage[k] = set() + + def add_disjoint_group(self, name): + if name in self.__groups.keys(): + raise KeyError("Disjoint group already exists within registry") + new = DisjointMappingGroup(name, self) + self.__groups.__setitem__(name, new) + return new + + def get_disjoint_group(self, name: str): + return self.__groups[name] + + def get_groupname(self, __key: Hashable): + return self.__key_groupnames[__key] + + def add_item_to_group(self, groupname, key, value): + current = self.__key_groupnames.get(key, None) + if current is not None and groupname != current: + raise KeyInOtherGroupError("The key '{}' is already used in a different group '{}'".format(key, groupname)) + if groupname is not None: + group = self.__groups[groupname] + group._data.__setitem__(key, value) + self.__key_groupnames[key] = groupname + return self.__data.__setitem__(key, value) + + def move_item_to_group(self, new_group_name, key): + value = self.__data[key] + current = self.get_groupname(key) + if new_group_name is not None: + new_group = self.__groups[new_group_name] + new_group._data[key] = value + if current is not None: + old_group = self.__groups[current] + old_group._data.__delitem__(key) + self.__key_groupnames[key] = new_group_name + + def remove_item_from_group(self, groupname, key): + current = self.__key_groupnames.get(key, None) + if groupname != current: + raise KeyInOtherGroupError("The key '{}' is in a different group '{}'".format(key, groupname)) + if groupname is not None: + self.__groups[groupname]._data.__delitem__(key) + + def __getitem__(self, __key: Any) -> Any: + return self.__data.__getitem__(__key) + + def __setitem__(self, __key: Any, __value: Any) -> None: + current = self.__key_groupnames.get(__key, None) + if current is not None: + self.__groups[current]._data[__key] = __value + return self.__data.__setitem__(__key, __value) + + def __delitem__(self, __key: Any) -> None: + current = self.__key_groupnames.get(__key, None) + if current is not None: + self.__groups[current]._data.__delitem__(__key) + return self.__data.__delitem__(__key) + + def __contains__(self, __key: object) -> bool: + return self.__data.__contains__(__key) + + def __iter__(self) -> Iterator: + return self.__data.__iter__() + + def __len__(self) -> int: + return self.__data.__len__() + + def keys(self) -> KeysView: + return self.__data.keys() + + def items(self) -> ItemsView: + return self.__data.items() + + def values(self) -> ValuesView: + return self.__data.values() + + def clear(self) -> None: + raise RuntimeError("You cannot clear this") + + def popitem(self) -> tuple: + raise RuntimeError("You cannot pop this") + + +class DisjointMappingGroup(MutableMapping): """A dictionary that checks a namespace for existing entries. To create a new instance, pass a set to act as a namespace. If the namespace does not @@ -204,73 +391,62 @@ class DisjointMapping(MutableMapping): """ - __keyspace: dict = None - __data: dict = None + __name: str = None + __keyspace: DisjointMapping = None + _data: dict = None - def __new__(cls, __keyspace: dict, *args, **kwargs): + def __new__(cls, name: str, __keyspace: DisjointMapping): + if name is None: + raise TypeError("A name must be specified") if __keyspace is None: - __keyspace = dict() + raise TypeError("A registry must be specified") newobj = super().__new__(cls) return newobj - def __init__(self, __keyspace, *args, **kwargs): - self.__keyspace = __keyspace - temp = dict(*args, **kwargs) - overlap = set(self.__keyspace.keys()).intersection(temp.keys()) - if overlap: - raise KeyInOtherDictError(overlap) - self.__keyspace.update(temp) - self.__data = temp + def __init__(self, name: str, __keyspace: DisjointMapping): + if name is None: + raise TypeError("A name must be specified") + if __keyspace is None: + raise TypeError("A registry must be specified") + self.__name: str = name + self.__keyspace: DisjointMapping = __keyspace + self._data = dict() def __getitem__(self, __key: Any) -> Any: - try: - return self.__data.__getitem__(__key) - except KeyError as e: - if __key in self.__keyspace.keys(): - raise KeyInOtherDictError(__key) - raise + return self._data[__key] def __setitem__(self, __key: Any, __value: Any) -> None: - if __key not in self.__data.keys() and __key in self.__keyspace.keys(): - raise KeyInOtherDictError(__key) - return self.__data.__setitem__(__key, __value) + return self.__keyspace.add_item_to_group(self.__name, __key, __value) def __delitem__(self, __key: Any) -> None: - if __key not in self.__data.keys() and __key in self.__keyspace.keys(): - raise KeyInOtherDictError(__key) - self.__keyspace.__delitem__(__key) - return self.__data.__delitem__(__key) + return self.__keyspace.remove_item_from_group(self.__name, __key) def __contains__(self, __key: object) -> bool: - return self.__data.__contains__(__key) + return self._data.__contains__(__key) def __iter__(self) -> Iterator: - return self.__data.__iter__() + return self._data.__iter__() def __len__(self) -> int: - return self.__data.__len__() + return self._data.__len__() def keys(self) -> KeysView: - return self.__data.keys() + return self._data.keys() def items(self) -> ItemsView: - return self.__data.items() + return self._data.items() def values(self) -> ValuesView: - return self.__data.values() + return self._data.values() def clear(self) -> None: - for k in self.__data.keys(): - self.__keyspace.__delitem__(k) - return self.__data.clear() + raise RuntimeError("Cannot clear a group") def popitem(self) -> tuple: - (k, v) = self.__data.popitem() - self.__keyspace.__delitem__(k) - return (k, v) + raise RuntimeError("Cannot pop from a group") - def new_disjoint_mapping(self): - return DisjointMapping(self.__keyspace) + def __repr__(self) -> str: + return "{}(name={}, data={})".format(self.__class__.__name__, repr(self.__name), self._data) @dataclass @@ -293,6 +469,9 @@ def symbol(self): def __str__(self) -> str: return self.name + def __hash__(self) -> int: + return hash(str(self)) + @dataclass class ReactionDynamics(ABC): @@ -316,9 +495,11 @@ def to_key(cls, species, location): location = RxnLocType.make(location) return species + "." + location.name.lower() + def __hash__(self) -> int: + return hash(str(self)) -class VariableRegistry(ABC): +class VariableRegistry(ABC): @abstractmethod def variables(self, var_type=None): raise NotImplementedError @@ -333,7 +514,6 @@ def del_variable(self, name: str): class ReactionRegistry(ABC): - @abstractmethod def reactions(self, location=None): raise NotImplementedError @@ -341,7 +521,7 @@ def reactions(self, location=None): @abstractmethod def get_reaction(self, species, location=None) -> List[ReactionDynamics]: raise NotImplementedError - + @abstractmethod def del_reaction(self, species, location=None): raise NotImplementedError @@ -361,6 +541,7 @@ def _variable_registry(self, value): raise TypeError("Linked model must be a RxnModel, got {}".format(type(value))) self.__variable_registry = value + @dataclass class ExpressionMixin(ABC): @@ -369,5 +550,3 @@ class ExpressionMixin(ABC): @abstractmethod def sympify(self): raise NotImplementedError - - diff --git a/wntr/reaction/dynamics.py b/wntr/reaction/dynamics.py index 190f65862..06de1feb1 100644 --- a/wntr/reaction/dynamics.py +++ b/wntr/reaction/dynamics.py @@ -13,7 +13,7 @@ from wntr.reaction.base import RxnVarType from .base import ExpressionMixin, LinkedVariablesMixin, RxnExprType, RxnLocType, VariableRegistry, ReactionDynamics, RxnVarType -from .variables import Coefficient, NamedExpression, Species +from .variables import Coefficient, OtherTerm, Species logger = logging.getLogger(__name__) diff --git a/wntr/reaction/library.py b/wntr/reaction/library.py index cc9e53bad..16c692e67 100644 --- a/wntr/reaction/library.py +++ b/wntr/reaction/library.py @@ -5,21 +5,121 @@ @author: John Burkhart, US EPA ORD """ +from .base import Citation from .model import WaterQualityReactionsModel -nicotine = WaterQualityReactionsModel() -nicotine.options.quality.area_units = 'M2' -nicotine.options.quality.rate_units = 'MIN' +nicotine = WaterQualityReactionsModel( + title="Nicotine - Chlorine reaction", + desc="Values in libarary are for test purposes ONLY. These highlight the reaction form/relationship but not necessarily the specific system kinetics. Citations are provided where appropriate for sources of values or models. In most cases updates will be necessary to use for different models -- That is, sources, pipes, nodes are for a given network, and must be updated for different models.", +) +nicotine.options.quality.area_units = "M2" +nicotine.options.quality.rate_units = "MIN" nicotine.options.time.timestep = 1 -nicotine.add_bulk_species('Nx', unit='MG', note='Nicotine') -nicotine.add_bulk_species('HOCL', unit='MG', note='Free chlorine') -nicotine.add_constant('kd', value=2.33e-3, unit='min^(-1)', note='decay rate') -nicotine.add_constant('K1', value=5.92e-2, unit='L * min^(-1) * mg^(-1)', note='decay constant for chlorine as function of mass(Nic)') -nicotine.add_constant('K2', value=1.84e-1, unit='L * min^(-1) * mg^(-1)', note='decay constant for nicotine as function of mass(Cl)') -nicotine.add_term('RXCL', expr='kd * HOCL + K1 * Nx * HOCL') -nicotine.add_term('RXN', expr='K2 * Nx * HOCL') -nicotine.add_pipe_reaction('rate', 'Nx', expression='-RXN') -nicotine.add_pipe_reaction('rate', 'HOCL', expression='-RXCL') -nicotine.add_tank_reaction('rate', 'Nx', '0') -nicotine.add_tank_reaction('rate', 'HOCL', '0') +nicotine.add_bulk_species("Nx", unit="MG", note="Nicotine") +nicotine.add_bulk_species("HOCL", unit="MG", note="Free chlorine") +nicotine.add_constant_coeff("kd", global_value=2.33e-3, unit="min^(-1)", note="decay rate") +nicotine.add_constant_coeff("K1", global_value=5.92e-2, unit="L * min^(-1) * mg^(-1)", note="decay constant for chlorine as function of mass(Nic)") +nicotine.add_constant_coeff("K2", global_value=1.84e-1, unit="L * min^(-1) * mg^(-1)", note="decay constant for nicotine as function of mass(Cl)") +nicotine.add_other_term("RXCL", expression="kd * HOCL + K1 * Nx * HOCL") +nicotine.add_other_term("RXN", expression="K2 * Nx * HOCL") +nicotine.add_pipe_reaction("Nx", "rate", expression="-RXN") +nicotine.add_pipe_reaction("HOCL", "rate", expression="-RXCL") +nicotine.add_tank_reaction("Nx", "rate", "0") +nicotine.add_tank_reaction("HOCL", "rate", "0") + +nicotine_ri = WaterQualityReactionsModel( + title="Nicotine - Chlorine reaction with reactive intermediate", +) +# Set options +nicotine_ri.options.quality.area_units = "M2" +nicotine_ri.options.quality.rate_units = "MIN" +nicotine_ri.options.time.timestep = 1 +nicotine_ri.options.quality.atol = 1.0e-10 +nicotine_ri.options.quality.rtol = 1.0e-10 + +# Add species +nicotine_ri.add_bulk_species("Nx", unit="MG", note="Nicotine") +nicotine_ri.add_bulk_species("HOCL", unit="MG", note="Free Chlorine") +nicotine_ri.add_bulk_species("NX2", unit="MG", note="Intermediate Nicotine Reactive") + +# Add coefficients +nicotine_ri.add_constant_coeff("kd", 3.0e-5, note="decay rate", unit="1/min") +nicotine_ri.add_constant_coeff("K1", global_value=9.75e-2, unit="L * min^(-1) * mg^(-1)", note="decay constant for chlorine as function of mass(Nic)") +nicotine_ri.add_constant_coeff("K2", global_value=5.73e-1, unit="L * min^(-1) * mg^(-1)", note="decay constant for nicotine as function of mass(Cl)") +nicotine_ri.add_constant_coeff("K3", global_value=1.34e-2, unit="L * min^(-1) * mg^(-1)", note="decay constant for nicotine as function of mass(N2)") +nicotine_ri.add_constant_coeff("K4", global_value=2.19e-2, unit="L * min^(-1) * mg^(-1)", note="decay constant for nicotine as function of mass(Cl)") + +# Add terms (named subexpressions) +nicotine_ri.add_other_term("RXCL", expression="kd*HOCL + K1*Nx*HOCL + K3*NX2*HOCL") +nicotine_ri.add_other_term("RXN", expression="K2*Nx*HOCL") +nicotine_ri.add_other_term("RXNX2", expression="K2*Nx*HOCL - K4*NX2*HOCL") + +# Add pipe reactions, one per species +nicotine_ri.add_pipe_reaction("Nx", "RATE", expression="-RXN") +nicotine_ri.add_pipe_reaction("HOCL", "RATE", expression="-RXCL") +nicotine_ri.add_pipe_reaction("NX2", "RATE", expression="RXNX2") + +# Tank reactions actually aren't necessary since there aren't any wall species +nicotine_ri.add_tank_reaction("Nx", "RATE", expression="-RXN") +nicotine_ri.add_tank_reaction("HOCL", "RATE", expression="-RXCL") +nicotine_ri.add_tank_reaction("NX2", "RATE", expression="RXNX2") + + +lead_ppm = WaterQualityReactionsModel( + title="Lead Plumbosolvency Model (from Burkhardt et al 2020)", + desc="Parameters for EPA HPS Simulator Model", + citations=Citation( + title="Framework for Modeling Lead in Premise Plumbing Systems Using EPANET", + year=2020, + author=[ + "Jonathan B. Burkhardt", + "Hyoungmin Woo", + "James Mason", + "Feng Shang", + "Simoni Triantafyllidou", + "Michael R. Schock", + "Darren Lytle", + "Regan Murray", + ], + citationtype="article", + journaltitle="J Water Resour Plan Manag", + volume=146, + number=12, + fulldate="2020-12-01", + doi="10.1061/(asce)wr.1943-5452.0001304", + eprint=[ + "PMID:33627937", + "PMCID:PMC7898126", + "NIHMSID:NIHMS1664627", + ], + ), + allow_sympy_reserved_names=True, + options={ + "time": {"timestep": 1}, + "report": { + "species": {"PB2": "YES"}, + "species_precision": {"PB2": 5}, + "nodes": "all", + "links": "all", + }, + "quality": { + "area_units": "M2", + "rate_units": "SEC", + "rtol": 1e-08, + "atol": 1e-08, + }, + }, +) +lead_ppm.options.quality.area_units = "M2" +lead_ppm.options.quality.rate_units = "SEC" +lead_ppm.options.quality.rtol = 1.0e-8 +lead_ppm.options.quality.atol = 1.0e-8 +lead_ppm.options.time.timestep = 1 + +lead_ppm.add_bulk_species("PB2", "ug", note="dissolved lead (Pb)") +lead_ppm.add_constant_coeff("M", global_value=0.117, note="Desorption rate (ug/m^2/s)", unit="ug * m^(-1) * s^(-1)") +lead_ppm.add_constant_coeff("E", global_value=140.0, note="saturation/plumbosolvency level (ug/L)", unit="ug/L") +lead_ppm.add_parameterized_coeff("F", global_value=0, note="determines which pipes have reactions") +lead_ppm.add_pipe_reaction("PB2", "RATE", expression="F*Av*M*(E - PB2)/E") +lead_ppm.add_tank_reaction("PB2", "RATE", expression="0") diff --git a/wntr/reaction/model.py b/wntr/reaction/model.py index 0ef920278..83313ffe6 100644 --- a/wntr/reaction/model.py +++ b/wntr/reaction/model.py @@ -7,38 +7,74 @@ import logging import warnings from collections.abc import MutableMapping -from dataclasses import InitVar, dataclass, field, asdict +from dataclasses import InitVar, asdict, dataclass, field from enum import Enum, IntFlag from typing import Any, ClassVar, Dict, Generator, Hashable, Iterator, List, Literal, Set, Tuple, Union import sympy -from sympy import Float, Symbol, symbols, init_printing +from sympy import Float, Symbol, init_printing, symbols from sympy.parsing import parse_expr -from sympy.parsing.sympy_parser import standard_transformations, convert_xor +from sympy.parsing.sympy_parser import convert_xor, standard_transformations from wntr.network.model import WaterNetworkModel from wntr.reaction.dynamics import EquilibriumDynamics, FormulaDynamics, RateDynamics -from .base import ReactionDynamics, ReactionVariable, VariableNameExistsError -from .variables import BulkSpecies, Coefficient, Constant, InternalVariable, NamedExpression, Parameter, Species, Term, WallSpecies + +from .base import ( + HYDRAULIC_VARIABLES, + RESERVED_NAMES, + SYMPY_RESERVED, + DisjointMapping, + DisjointMappingGroup, + ReactionDynamics, + ReactionRegistry, + ReactionVariable, + RxnExprType, + RxnLocType, + RxnVarType, + VariableNameExistsError, + VariableRegistry, +) from .options import RxnOptions -from .base import ReactionRegistry, VariableRegistry, RxnExprType, RxnLocType, RxnVarType, DisjointMapping, RESERVED_NAMES, SYMPY_RESERVED +from .variables import BulkSpecies, Coefficient, Constant, InternalVariable, OtherTerm, Parameter, Species, WallSpecies +@dataclass class WaterQualityReactionsModel(ReactionRegistry, VariableRegistry): - def __init__(self, wn: WaterNetworkModel = None, *, title: str = None, desc: str = None, allow_sympy_reserved=False): - self.title: str = title - self.desc: str = desc - self.options = RxnOptions() - self._wn: WaterNetworkModel = wn - - self._variables: Dict[str, ReactionVariable] = dict() - self._species = DisjointMapping(self._variables) - self._coeff = DisjointMapping(self._variables) - self._terms = DisjointMapping(self._variables) - - self._dynamics: Dict[str, ReactionDynamics] = dict() - self._pipe_dynamics = DisjointMapping(self._dynamics) - self._tank_dynamics = DisjointMapping(self._dynamics) + """Water quality reactions model object. + + Parameters + ---------- + title : str + The title of reaction model + desc : str + A long description of the model + citations : + """ + title: str = None + desc: str = None + citations: Union[List[str], str] = "you ought to provide citations for this model" + allow_sympy_reserved_names: InitVar[bool] = False + options: InitVar[RxnOptions] = None + _wn: WaterNetworkModel = None + + def __post_init__(self, allow_sympy_reserved_names=False, options=None): + if self._wn is not None and not isinstance(self._wn, WaterNetworkModel): + raise TypeError("Did not receive a WaterNetworkModel or None as first argument, got {}".format(self._wn)) + if isinstance(options, property): + options = RxnOptions() + elif not isinstance(options, RxnOptions): + options = RxnOptions.factory(options) + self._options = options + if isinstance(self.citations, str): + self.citations = [self.citations] + self._variables: DisjointMapping = DisjointMapping() + self._species = self._variables.add_disjoint_group('species') + self._coeff = self._variables.add_disjoint_group('coeff') + self._terms = self._variables.add_disjoint_group('terms') + + self._dynamics: DisjointMapping = DisjointMapping() + self._pipe_dynamics = self._dynamics.add_disjoint_group('pipe') + self._tank_dynamics = self._dynamics.add_disjoint_group('tank') self._usage: Dict[str, Set[str]] = dict() @@ -46,11 +82,11 @@ def __init__(self, wn: WaterNetworkModel = None, *, title: str = None, desc: str self._inital_quality: Dict[Hashable, float] = dict() self._wn: WaterNetworkModel = None - for name in RESERVED_NAMES: - self._variables[name] = InternalVariable(name) - if not allow_sympy_reserved: + for v in HYDRAULIC_VARIABLES: + self._variables[v['name']] = InternalVariable(v['name'], note=v['note']) + if not allow_sympy_reserved_names: for name in SYMPY_RESERVED: - self._variables[name] = InternalVariable(name) + self._variables[name] = InternalVariable(name, note="sympy reserved name") def _is_variable_registered(self, var_or_name: Union[str, ReactionVariable]) -> bool: name = str(var_or_name) @@ -65,11 +101,11 @@ def variable_name_list(self) -> List[str]: @property def species_name_list(self) -> List[str]: return list(self._species.keys()) - + @property def coefficient_name_list(self) -> List[str]: return list(self._coeff.keys()) - + @property def other_term_name_list(self) -> List[str]: return list(self._terms.keys()) @@ -81,14 +117,16 @@ def variables(self, var_type=None): continue yield k, v - def add_species(self, species_type: Union[str, Literal[RxnVarType.BULK], Literal[RxnVarType.WALL]], name: str, unit: str, atol: float = None, rtol: float = None, note: str = None) -> Species: + def add_species( + self, species_type: Union[str, Literal[RxnVarType.BULK], Literal[RxnVarType.WALL]], name: str, unit: str, atol: float = None, rtol: float = None, note: str = None + ) -> Species: species_type = RxnVarType.make(species_type) if species_type not in [RxnVarType.BULK, RxnVarType.WALL]: - raise ValueError('Species must be BULK or WALL, got {:s}'.format(species_type)) + raise ValueError("Species must be BULK or WALL, got {:s}".format(species_type)) if self._is_variable_registered(name): - raise VariableNameExistsError('The variable {} already exists in this model'.format(name)) + raise VariableNameExistsError("The variable {} already exists in this model".format(name)) if (atol is None) ^ (rtol is None): - raise TypeError('atol and rtol must be the same type, got {} and {}'.format(atol, rtol)) + raise TypeError("atol and rtol must be the same type, got {} and {}".format(atol, rtol)) if species_type is RxnVarType.BULK: var = BulkSpecies(name, unit, atol, rtol, note, self) elif species_type is RxnVarType.WALL: @@ -102,12 +140,14 @@ def add_bulk_species(self, name: str, unit: str, atol: float = None, rtol: float def add_wall_species(self, name: str, unit: str, atol: float = None, rtol: float = None, note: str = None) -> WallSpecies: return self.add_species(RxnVarType.WALL, name, unit, atol, rtol, note) - def add_coefficient(self, coeff_type: Union[str, Literal[RxnVarType.CONST], Literal[RxnVarType.PARAM]], name: str, global_value: float, note: str=None, unit: str=None, **kwargs) -> Coefficient: + def add_coefficient( + self, coeff_type: Union[str, Literal[RxnVarType.CONST], Literal[RxnVarType.PARAM]], name: str, global_value: float, note: str = None, unit: str = None, **kwargs + ) -> Coefficient: coeff_type = RxnVarType.make(coeff_type) if coeff_type not in [RxnVarType.CONST, RxnVarType.PARAM]: - raise ValueError('Species must be CONST or PARAM, got {:s}'.format(coeff_type)) + raise ValueError("Species must be CONST or PARAM, got {:s}".format(coeff_type)) if self._is_variable_registered(name): - raise VariableNameExistsError('The variable {} already exists in this model'.format(name)) + raise VariableNameExistsError("The variable {} already exists in this model".format(name)) if coeff_type is RxnVarType.CONST: var = Constant(name=name, global_value=global_value, note=note, unit=unit, variable_registry=self) elif coeff_type is RxnVarType.PARAM: @@ -115,16 +155,18 @@ def add_coefficient(self, coeff_type: Union[str, Literal[RxnVarType.CONST], Lite self._coeff[name] = var return var - def add_constant_coeff(self, name: str, global_value: float, note: str=None, unit: str=None) -> Constant: + def add_constant_coeff(self, name: str, global_value: float, note: str = None, unit: str = None) -> Constant: return self.add_coefficient(RxnVarType.CONST, name=name, global_value=global_value, note=note, unit=unit) - def add_parameterized_coeff(self, name: str, global_value: float, note: str=None, unit: str=None, pipe_values: Dict[str, float] = None, tank_values: Dict[str, float] = None) -> Parameter: + def add_parameterized_coeff( + self, name: str, global_value: float, note: str = None, unit: str = None, pipe_values: Dict[str, float] = None, tank_values: Dict[str, float] = None + ) -> Parameter: return self.add_coefficient(RxnVarType.PARAM, name=name, global_value=global_value, note=note, unit=unit, _pipe_values=pipe_values, _tank_values=tank_values) - def add_other_term(self, name: str, expression: str, note: str = None) -> NamedExpression: + def add_other_term(self, name: str, expression: str, note: str = None) -> OtherTerm: if self._is_variable_registered(name): - raise VariableNameExistsError('The variable {} already exists in this model'.format(name)) - var = NamedExpression(name=name, expression=expression, note=note, variable_registry=self) + raise VariableNameExistsError("The variable {} already exists in this model".format(name)) + var = OtherTerm(name=name, expression=expression, note=note, variable_registry=self) self._terms[name] = var return var @@ -146,7 +188,7 @@ def add_reaction(self, location: RxnLocType, species: Union[str, Species], dynam species = str(species) _key = ReactionDynamics.to_key(species, location) if _key in self._dynamics.keys(): - raise RuntimeError('The species {} already has a {} reaction defined. Use set_reaction instead.') + raise RuntimeError("The species {} already has a {} reaction defined. Use set_reaction instead.") dynamics = RxnExprType.make(dynamics) new = None if dynamics is RxnExprType.EQUIL: @@ -156,13 +198,13 @@ def add_reaction(self, location: RxnLocType, species: Union[str, Species], dynam elif dynamics is RxnExprType.FORMULA: new = FormulaDynamics(species=species, location=location, expression=expression, note=note, variable_registry=self) else: - raise ValueError('Invalid dynamics type, {}'.format(dynamics)) + raise ValueError("Invalid dynamics type, {}".format(dynamics)) if location is RxnLocType.PIPE: self._pipe_dynamics[str(new)] = new elif location is RxnLocType.TANK: self._tank_dynamics[str(new)] = new else: - raise ValueError('Invalid location type, {}'.format(location)) + raise ValueError("Invalid location type, {}".format(location)) return new def add_pipe_reaction(self, species: Union[str, Species], dynamics: Union[str, int, RxnExprType], expression: str, note: str = None) -> ReactionDynamics: @@ -171,13 +213,13 @@ def add_pipe_reaction(self, species: Union[str, Species], dynamics: Union[str, i def add_tank_reaction(self, species: Union[str, Species], dynamics: Union[str, int, RxnExprType], expression: str, note: str = None) -> ReactionDynamics: return self.add_reaction(RxnLocType.TANK, species=species, dynamics=dynamics, expression=expression, note=note) - def del_reaction(self, species: Union[str, Species], location: Union[str, int, RxnLocType, Literal['all']]): - if location != 'all': + def del_reaction(self, species: Union[str, Species], location: Union[str, int, RxnLocType, Literal["all"]]): + if location != "all": location = RxnLocType.make(location) species = str(species) if location is None: raise TypeError('location cannot be None when removing a reaction. Use "all" for all locations.') - elif location == 'all': + elif location == "all": name = ReactionDynamics.to_key(species, RxnLocType.PIPE) try: self._pipe_dynamics.__delitem__(name) @@ -201,8 +243,8 @@ def del_reaction(self, species: Union[str, Species], location: Union[str, int, R except KeyError: pass else: - raise ValueError('Invalid location, {}'.format(location)) - + raise ValueError("Invalid location, {}".format(location)) + def get_reaction(self, species, location): species = str(species) location = RxnLocType.make(location) diff --git a/wntr/reaction/options.py b/wntr/reaction/options.py index 7a5393170..2c2e226ee 100644 --- a/wntr/reaction/options.py +++ b/wntr/reaction/options.py @@ -215,8 +215,7 @@ class RxnOptions(_OptionsBase): """ - def __init__(self, title: str = None, time: TimeOptions = None, report: ReportOptions = None, quality: QualityOptions = None, user: UserOptions = None): - self.title = (title,) + def __init__(self, time: TimeOptions = None, report: ReportOptions = None, quality: QualityOptions = None, user: UserOptions = None): self.time = TimeOptions.factory(time) self.report = ReportOptions.factory(report) self.quality = QualityOptions.factory(quality) @@ -237,7 +236,8 @@ def __setattr__(self, name, value): value = QualityOptions.factory(value) elif name == "user": value = UserOptions.factory(value) - elif name not in ["title"]: + else: + # elif name not in ["title"]: raise ValueError("%s is not a valid member of WaterNetworkModel") self.__dict__[name] = value diff --git a/wntr/reaction/variables.py b/wntr/reaction/variables.py index ab79dc535..f093704a9 100644 --- a/wntr/reaction/variables.py +++ b/wntr/reaction/variables.py @@ -3,6 +3,7 @@ from dataclasses import InitVar, asdict, dataclass, field from enum import Enum, IntFlag from typing import Any, ClassVar, Dict, List, Set, Tuple, Union +import warnings import sympy from sympy import Float, Function, Symbol, init_printing, symbols @@ -26,12 +27,14 @@ class Species(LinkedVariablesMixin, ReactionVariable): variable_registry: InitVar[VariableRegistry] = None def __post_init__(self, atol=None, rtol=None, reaction_model=None): - if isinstance(atol, property): atol=None - if isinstance(rtol, property): rtol=None + if isinstance(atol, property): + atol = None + if isinstance(rtol, property): + rtol = None if self.name in RESERVED_NAMES: - raise ValueError('Name cannot be a reserved name') + raise ValueError("Name cannot be a reserved name") if (atol is None) ^ (rtol is None): - raise TypeError('atol and rtol must be the same type, got {} and {}'.format(atol, rtol)) + raise TypeError("atol and rtol must be the same type, got {} and {}".format(atol, rtol)) self._atol = atol self._rtol = rtol self._variable_registry = reaction_model @@ -39,7 +42,7 @@ def __post_init__(self, atol=None, rtol=None, reaction_model=None): @property def atol(self) -> float: return self._atol - + @property def rtol(self) -> float: return self._rtol @@ -59,7 +62,7 @@ def set_tolerances(self, atol: float, rtol: float): if not isinstance(rtol, float): rtol = float(rtol) except Exception as e: - raise TypeError('atol and rtol must be the same type, got {} and {}'.format(atol, rtol)) + raise TypeError("atol and rtol must be the same type, got {} and {}".format(atol, rtol)) if atol <= 0: raise ValueError("Absolute tolerance atol must be greater than 0") if rtol <= 0: @@ -74,9 +77,9 @@ def to_msx_string(self) -> str: tols = self.get_tolerances() if tols is None: # tolstr = "{:<12s} {:<12s}".format("", "") - tolstr = '' + tolstr = "" else: - #tolstr = "{:12.6g} {:12.6g}".format(*tols) + # tolstr = "{:12.6g} {:12.6g}".format(*tols) tolstr = "{} {}".format(*tols) # return "{:<4s} {:<32s} {:s} {:s} ;{:s}".format( return "{:s} {:s} {:s} {:s} ;{:s}".format( @@ -88,9 +91,7 @@ def to_msx_string(self) -> str: ) def __repr__(self): - return "{}(name={}, unit={}, atol={}, rtol={}, note={})".format( - self.__class__.__name__, repr(self.name), repr(self.unit), self.atol, self.rtol, repr(self.note) - ) + return "{}(name={}, unit={}, atol={}, rtol={}, note={})".format(self.__class__.__name__, repr(self.name), repr(self.unit), self.atol, self.rtol, repr(self.note)) @dataclass(repr=False) @@ -117,7 +118,7 @@ class Coefficient(LinkedVariablesMixin, ReactionVariable): def __post_init__(self, reaction_model): if self.name in RESERVED_NAMES: - raise ValueError('Name cannot be a reserved name') + raise ValueError("Name cannot be a reserved name") self._variable_registry = reaction_model def get_value(self) -> float: @@ -165,21 +166,21 @@ def get_value(self, pipe: str = None, tank: str = None) -> float: @property def pipe_values(self) -> Dict[str, float]: return self._pipe_values - + @property def tank_values(self) -> Dict[str, float]: return self._tank_values @dataclass(repr=False) -class NamedExpression(LinkedVariablesMixin, ExpressionMixin, ReactionVariable): +class OtherTerm(LinkedVariablesMixin, ExpressionMixin, ReactionVariable): note: str = None variable_registry: InitVar[VariableRegistry] = field(default=None, compare=False) def __post_init__(self, reaction_model): if self.name in RESERVED_NAMES: - raise ValueError('Name cannot be a reserved name') + raise ValueError("Name cannot be a reserved name") self._variable_registry = reaction_model @property @@ -196,17 +197,18 @@ def __repr__(self): return "{}(name={}, expression={}, note={})".format(self.__class__.__name__, repr(self.name), repr(self.expression), repr(self.note)) -Term = NamedExpression - - +@dataclass(repr=False) class InternalVariable(ReactionVariable): + note: str = "internal variable - not output to MSX" + unit: str = None + @property def var_type(self) -> RxnVarType: return RxnVarType.INTERNAL def to_msx_string(self) -> str: - raise TypeError("InternalVariable is not output to an MSX input file") + raise TypeError("An InternalVariable is not part of an MSX input file") def __repr__(self): - return "{}(name={})".format(self.__class__.__name__, repr(self.name)) + return "{}(name={}, note={})".format(self.__class__.__name__, repr(self.name), repr(self.note)) diff --git a/wntr/tests/test_reactions.py b/wntr/tests/test_reactions.py index 63fe33b9e..75cc7fcc3 100644 --- a/wntr/tests/test_reactions.py +++ b/wntr/tests/test_reactions.py @@ -28,7 +28,7 @@ def test_ReactionVariable_reserved_name_exception(self): self.assertRaises(ValueError, wntr.reaction.model.WallSpecies, "Q", "mg") self.assertRaises(ValueError, wntr.reaction.model.Constant, "Re", 0.52) self.assertRaises(ValueError, wntr.reaction.model.Parameter, "Re", 0.52) - self.assertRaises(ValueError, wntr.reaction.model.NamedExpression, "Re", 0.52) + self.assertRaises(ValueError, wntr.reaction.model.OtherTerm, "Re", 0.52) def test_RxnVariable_symbols_and_sympy(self): species1 = wntr.reaction.model.BulkSpecies("Cl", "mg") @@ -43,7 +43,7 @@ def test_RxnVariable_symbols_and_sympy(self): symbol3 = sympy.symbols("Ka") self.assertEqual(param1.symbol, symbol3) - term1 = wntr.reaction.model.NamedExpression("T0", "-3.2 * Kb * Cl^2", note="bar") + term1 = wntr.reaction.model.OtherTerm("T0", "-3.2 * Kb * Cl^2", note="bar") symbol4 = sympy.symbols("T0") self.assertEqual(term1.symbol, symbol4) @@ -64,7 +64,7 @@ def test_RxnVariable_string_functions(self): species2 = wntr.reaction.model.WallSpecies("Cl", "mg", 0.01, 0.0001, note="Testing stuff") const1 = wntr.reaction.model.Constant("Kb", 0.482) param1 = wntr.reaction.model.Parameter("Ka", 0.482, note="foo") - term1 = wntr.reaction.model.NamedExpression("T0", "-3.2 * Kb * Cl^2", note="bar") + term1 = wntr.reaction.model.OtherTerm("T0", "-3.2 * Kb * Cl^2", note="bar") self.assertEqual(str(species1), "Cl") self.assertEqual(species1.to_msx_string(), "BULK Cl mg ;") @@ -167,9 +167,9 @@ def test_Parameter_creation(self): self.assertDictEqual(param2.tank_values, test_tank_dict) def test_RxnTerm_creation(self): - self.assertRaises(TypeError, wntr.reaction.model.NamedExpression, "Re") - self.assertRaises(ValueError, wntr.reaction.model.NamedExpression, "Re", "1.0*Re") - term1 = wntr.reaction.model.NamedExpression("T0", "-3.2 * Kb * Cl^2", note="bar") + self.assertRaises(TypeError, wntr.reaction.model.OtherTerm, "Re") + self.assertRaises(ValueError, wntr.reaction.model.OtherTerm, "Re", "1.0*Re") + term1 = wntr.reaction.model.OtherTerm("T0", "-3.2 * Kb * Cl^2", note="bar") self.assertEqual(term1.name, "T0") self.assertEqual(term1.expression, "-3.2 * Kb * Cl^2") self.assertEqual(term1.var_type, wntr.reaction.model.RxnVarType.TERM) @@ -208,7 +208,7 @@ def test_WaterQualityReactionsModel_creation_specific_everything(self): wall1 = wntr.reaction.model.WallSpecies("ClOH", "mg", 0.01, 0.0001, note="Testing stuff") const1 = wntr.reaction.model.Constant("Kb", 0.482) param1 = wntr.reaction.model.Parameter("Ka", 0.482, note="foo") - term1 = wntr.reaction.model.NamedExpression("T0", "-3.2 * Kb * Cl^2", note="bar") + term1 = wntr.reaction.model.OtherTerm("T0", "-3.2 * Kb * Cl^2", note="bar") equil1 = wntr.reaction.model.EquilibriumDynamics(bulk1, wntr.reaction.model.RxnLocType.PIPE, "-Ka + Kb * Cl + T0") rate1 = wntr.reaction.model.RateDynamics(bulk1, wntr.reaction.model.RxnLocType.TANK, "-Ka + Kb * Cl + T0", note="Foo Bar") formula1 = wntr.reaction.model.FormulaDynamics(wall1, wntr.reaction.model.RxnLocType.PIPE, "-Ka + Kb * Cl + T0") @@ -235,7 +235,7 @@ def test_WaterQualityReactionsModel_creation_generic_species_coeffs(self): wall1 = wntr.reaction.model.WallSpecies("ClOH", "mg", 0.01, 0.0001, note="Testing stuff") const1 = wntr.reaction.model.Constant("Kb", 0.482) param1 = wntr.reaction.model.Parameter("Ka", 0.482, note="foo") - term1 = wntr.reaction.model.NamedExpression("T0", "-3.2 * Kb * Cl^2", note="bar") + term1 = wntr.reaction.model.OtherTerm("T0", "-3.2 * Kb * Cl^2", note="bar") rxn_model2 = wntr.reaction.model.WaterQualityReactionsModel() From 489236375097e11c145920d5b3d1d9956e5762bb Mon Sep 17 00:00:00 2001 From: dbhart Date: Mon, 28 Aug 2023 10:06:06 -0600 Subject: [PATCH 09/75] Updates to read things in - there are bugs --- wntr/reaction/io.py | 300 ++++++++++++++++++++++++++++++++++++- wntr/reaction/model.py | 8 +- wntr/reaction/variables.py | 6 + 3 files changed, 308 insertions(+), 6 deletions(-) diff --git a/wntr/reaction/io.py b/wntr/reaction/io.py index 54e6a77a6..fbb8cd302 100644 --- a/wntr/reaction/io.py +++ b/wntr/reaction/io.py @@ -2,30 +2,320 @@ import sys import logging +from wntr.network.elements import Source + +from wntr.reaction.model import WaterQualityReactionsModel +from wntr.reaction.variables import Parameter, Species sys_default_enc = sys.getdefaultencoding() logger = logging.getLogger(__name__) +_INP_SECTIONS = [ + "[TITLE]", + "[OPTIONS]", + "[SPECIES]", + "[COEFFICIENTS]", + "[TERMS]", + "[PIPES]", + "[TANKS]", + "[SOURCES]", + "[QUALITY]", + "[PARAMETERS]", + "[DIFFUSIVITY]", + "[PATTERNS]", + "[REPORT]", +] + + +def _split_line(line): + _vc = line.split(";", 1) + _cmnt = None + _vals = None + if len(_vc) == 0: + pass + elif len(_vc) == 1: + _vals = _vc[0].split() + elif _vc[0] == "": + _cmnt = _vc[1] + else: + _vals = _vc[0].split() + _cmnt = _vc[1] + return _vals, _cmnt + class MsxFile(object): - def __init__(self): - pass + self.sections = dict() + for sec in _INP_SECTIONS: + self.sections[sec] = [] + self.top_comments = [] + self.patterns = dict() def read(self, msx_file, rxn_model=None): - pass + """ + Read an EPANET-MSX input file (.msx) and load data into a water quality + reactions model. Only MSX 2.0 files are recognized. + + + """ + if rxn_model is None: + rxn_model = WaterQualityReactionsModel() + self.rxn = rxn_model + # if not isinstance(msx_file, list): + # msx_file = [msx_file] + rxn_model.filename = msx_file + + self.patterns = dict() + self.top_comments = [] + self.sections = dict() + for sec in _INP_SECTIONS: + self.sections[sec] = [] + + section = None + lnum = 0 + edata = {"fname": msx_file} + with open(msx_file, "r", encoding=sys_default_enc) as f: + for line in f: + lnum += 1 + edata["lnum"] = lnum + line = line.strip() + nwords = len(line.split()) + if len(line) == 0 or nwords == 0: + # Blank line + continue + elif line.startswith("["): + vals = line.split(None, 1) + sec = vals[0].upper() + # Add handlers to deal with extra 'S'es (or missing 'S'es) in INP file + if sec not in _INP_SECTIONS: + trsec = sec.replace("]", "S]") + if trsec in _INP_SECTIONS: + sec = trsec + if sec not in _INP_SECTIONS: + trsec = sec.replace("S]", "]") + if trsec in _INP_SECTIONS: + sec = trsec + edata["sec"] = sec + if sec in _INP_SECTIONS: + section = sec + # logger.info('%(fname)s:%(lnum)-6d %(sec)13s section found' % edata) + continue + elif sec == "[END]": + # logger.info('%(fname)s:%(lnum)-6d %(sec)13s end of file found' % edata) + section = None + break + else: + raise RuntimeError('%(fname)s:%(lnum)d: Invalid section "%(sec)s"' % edata) + elif section is None and line.startswith(";"): + self.top_comments.append(line[1:]) + continue + elif section is None: + logger.debug("Found confusing line: %s", repr(line)) + raise RuntimeError("%(fname)s:%(lnum)d: Non-comment outside of valid section!" % edata) + # We have text, and we are in a section + self.sections[section].append((lnum, line)) + + self._read_title() + self._read_options() + self._read_species() + self._read_coefficients() + self._read_terms() + self._read_pipes() + self._read_tanks() + self._read_sources() + self._read_quality() + self._read_parameters() + self._read_diffusivity() + self._read_patterns() + self._read_report() + return self.rxn + + def _read_title(self): + lines = [] + for lnum, line in self.sections['[TITLE]']: + line = line.split(';')[0] + current = line.split() + if current == []: + continue + lines.append(line) + if len(lines) > 0: + self.rxn.title = lines[0] + if len(lines) > 1: + self.rxn.desc = '\n'.join(lines[1:]) + + def _read_options(self): + lines = [] + for lnum, line in self.sections['[OPTIONS]']: + vals, comment = _split_line(line) + if len(vals) != 2: + raise RuntimeError('Invalid options line: "{}"'.format(line)) + name, val = vals[0].upper(), vals[1].upper() + try: + if name == 'AREA_UNITS': + self.rxn._options.quality.area_units = val + elif name == 'RATE_UNITS': + self.rxn._options.quality.rate_units = val + elif name == 'SOLVER': + self.rxn._options.quality.solver = val + elif name == 'COUPLING': + self.rxn._options.quality.coupling = val + elif name == 'TIMESTEP': + self.rxn._options.time.timestep = int(val) + elif name == 'ATOL': + self.rxn._options.quality.atol = float(val) + elif name == 'RTOL': + self.rxn._options.quality.rtol = float(val) + elif name == 'COMPILER': + self.rxn._options.quality.compiler = val + elif name == 'SEGMENTS': + self.rxn._options.quality.segments = int(val) + elif name == 'PECLET': + self.rxn._options.quality.peclet = int(val) + except Exception as e: + raise ('Error in options line: "{}"'.format(line)) from e + + def _read_species(self): + lines = [] + for lnum, line in self.sections['[SPECIES]']: + vals, comment = _split_line(line) + if len(vals) not in [3, 5]: + raise RuntimeError('Invalid species line: "{}"'.format(line)) + try: + if len(vals) == 3: + species = self.rxn.add_species(vals[0], vals[1], vals[2], note=comment) + elif len(vals) == 5: + species = self.rxn.add_species(vals[0], vals[1], vals[2], float(vals[3]), float(vals[4]), note=comment) + except Exception as e: + raise RuntimeError('Invalid species line: "{}"'.format(line)) from e + + def _read_coefficients(self): + lines = [] + for lnum, line in self.sections['[COEFFICIENTS]']: + vals, comment = _split_line(line) + if len(vals) != 3: + raise RuntimeError('Invalid coefficient line: "{}"'.format(line)) + try: + coeff = self.rxn.add_coefficient(vals[0], vals[1], float(vals[2]), note=comment) + except Exception as e: + raise RuntimeError('Invalid coefficient line: "{}"'.format(line)) from e + + def _read_terms(self): + lines = [] + for lnum, line in self.sections['[TERMS]']: + vals, comment = _split_line(line) + if len(vals) < 2: + raise RuntimeError('Invalid term line: "{}"'.format(line)) + term = self.rxn.add_other_term(vals[0], ' '.join(vals[1:]), note=comment) + + def _read_pipes(self): + lines = [] + for lnum, line in self.sections['[PIPES]']: + vals, comment = _split_line(line) + if len(vals) < 3: + raise RuntimeError('Invalid tanks line: "{}"'.format(line)) + reaction = self.rxn.add_pipe_reaction(vals[0], vals[1], vals[2:], note=comment) + + def _read_tanks(self): + lines = [] + for lnum, line in self.sections['[TANKS]']: + vals, comment = _split_line(line) + if len(vals) < 3: + raise RuntimeError('Invalid tanks line: "{}"'.format(line)) + reaction = self.rxn.add_tank_reaction(vals[0], vals[1], vals[2:], note=comment) + + def _read_sources(self): + lines = [] + for lnum, line in self.sections['[SOURCES]']: + vals, comment = _split_line(line) + try: + if len(vals) == 4: + typ, node, spec, strength = vals + pat = None + else: + typ, node, spec, strength, pat = vals + source = Source(None, name=spec, node_name=node, source_type=typ, strength=strength, pattern=pat) + self.rxn._sources['{}:{}:{}'.format(typ,node,spec)] = source + except Exception as e: + raise RuntimeError('Invalid sources line: "{}"'.format(line)) from e + + def _read_quality(self): + lines = [] + for lnum, line in self.sections['[QUALITY]']: + vals, comment = _split_line(line) + self.rxn._inital_quality.extend(lines) + + def _read_parameters(self): + lines = [] + for lnum, line in self.sections['[PARAMETERS]']: + vals, comment = _split_line(line) + try: + typ, netid, paramid, value = vals + coeff = self.rxn.get_variable(paramid) + if not isinstance(coeff, Parameter): + raise RuntimeError('Invalid parameter {}'.format(paramid)) + value = float(value) + if typ.lower()[0] == 'p': + coeff.pipe_values[netid] = vals + elif typ.lower()[0] == 't': + coeff.tank_values[netid] = vals + else: + raise RuntimeError('Invalid parameter type {}'.format(typ)) + except Exception as e: + raise RuntimeError('Invalid parameters line: "{}"'.format(line)) from e + + def _read_diffusivity(self): + lines = [] + for lnum, line in self.sections['[DIFFUSIVITY]']: + vals, comment = _split_line(line) + if len(vals) != 2: + raise RuntimeError('Error in diffusivity line: "{}"'.format(line)) + try: + species = self.rxn.get_variable(vals[0]) + except: + raise RuntimeError('Invalid species {} in diffusivity line: "{}"'.format(vals[0], line)) + if not isinstance(species, Species): + raise RuntimeError('Invalid species {} in diffusivity line: "{}"'.format(vals[0], line)) + try: + species.diffusivity = float(vals[1]) + except Exception as e: + raise RuntimeError('Error in diffusivity line: "{}"'.format(line)) from e + + def _read_patterns(self): + _patterns = dict() + for lnum, line in self.sections['[PATTERNS]']: + # read the lines for each pattern -- patterns can be multiple lines of arbitrary length + line = line.split(';')[0] + current = line.split() + if current == []: + continue + pattern_name = current[0] + if pattern_name not in _patterns: + _patterns[pattern_name] = [] + for i in current[1:]: + _patterns[pattern_name].append(float(i)) + else: + for i in current[1:]: + _patterns[pattern_name].append(float(i)) + for pattern_name, pattern in _patterns.items(): + # add the patterns to the water newtork model + self.rxn.add_pattern(pattern_name, pattern) + + + def _read_report(self): + lines = [] + for lnum, line in self.sections['[REPORT]']: + vals, comment = _split_line(line) + self.rxn._report.extend(lines) def write(self, filename, rxn_model): pass - class MsxBinFile(object): def __init__(self): pass def read(self, filename): pass - diff --git a/wntr/reaction/model.py b/wntr/reaction/model.py index 83313ffe6..48581f534 100644 --- a/wntr/reaction/model.py +++ b/wntr/reaction/model.py @@ -50,6 +50,7 @@ class WaterQualityReactionsModel(ReactionRegistry, VariableRegistry): A long description of the model citations : """ + filename: str = None title: str = None desc: str = None citations: Union[List[str], str] = "you ought to provide citations for this model" @@ -79,8 +80,10 @@ def __post_init__(self, allow_sympy_reserved_names=False, options=None): self._usage: Dict[str, Set[str]] = dict() self._sources: Dict[str, float] = dict() - self._inital_quality: Dict[Hashable, float] = dict() + self._inital_quality = list() self._wn: WaterNetworkModel = None + self._patterns: Dict[str, Any] = dict() + self._report = list() for v in HYDRAULIC_VARIABLES: self._variables[v['name']] = InternalVariable(v['name'], note=v['note']) @@ -270,3 +273,6 @@ def options(self, value): def link_water_network_model(self, wn: WaterNetworkModel): self._wn = wn + + def add_pattern(self, name, pat): + self._patterns[name] = pat \ No newline at end of file diff --git a/wntr/reaction/variables.py b/wntr/reaction/variables.py index f093704a9..1037d7d5b 100644 --- a/wntr/reaction/variables.py +++ b/wntr/reaction/variables.py @@ -24,13 +24,18 @@ class Species(LinkedVariablesMixin, ReactionVariable): atol: InitVar[float] = None rtol: InitVar[float] = None note: str = None + diffusivity: float = None variable_registry: InitVar[VariableRegistry] = None def __post_init__(self, atol=None, rtol=None, reaction_model=None): if isinstance(atol, property): atol = None + elif atol is not None: + atol = float(atol) if isinstance(rtol, property): rtol = None + elif rtol is not None: + rtol = float(rtol) if self.name in RESERVED_NAMES: raise ValueError("Name cannot be a reserved name") if (atol is None) ^ (rtol is None): @@ -119,6 +124,7 @@ class Coefficient(LinkedVariablesMixin, ReactionVariable): def __post_init__(self, reaction_model): if self.name in RESERVED_NAMES: raise ValueError("Name cannot be a reserved name") + self.global_value = float(self.global_value) self._variable_registry = reaction_model def get_value(self) -> float: From 3649f605ced34f071c20b6e33433cfec9c0eb156 Mon Sep 17 00:00:00 2001 From: dbhart Date: Tue, 29 Aug 2023 17:02:08 -0600 Subject: [PATCH 10/75] Updates to documentation and completing the I/O --- documentation/apidoc/wntr.reaction.base.rst | 7 + .../apidoc/wntr.reaction.dynamics.rst | 7 + .../apidoc/wntr.reaction.options.rst | 7 + documentation/apidoc/wntr.reaction.rst | 3 + .../apidoc/wntr.reaction.variables.rst | 7 + wntr/reaction/__init__.py | 6 +- wntr/reaction/base.py | 482 +++++++++----- wntr/reaction/dynamics.py | 211 +++++-- wntr/reaction/io.py | 304 ++++++--- wntr/reaction/library.py | 100 +-- wntr/reaction/model.py | 596 +++++++++++++++--- wntr/reaction/options.py | 104 ++- wntr/reaction/toolkitmsx.py | 8 +- wntr/reaction/variables.py | 251 ++++++-- wntr/tests/test_reactions.py | 54 +- wntr/utils/citations.py | 116 ++++ 16 files changed, 1694 insertions(+), 569 deletions(-) create mode 100644 documentation/apidoc/wntr.reaction.base.rst create mode 100644 documentation/apidoc/wntr.reaction.dynamics.rst create mode 100644 documentation/apidoc/wntr.reaction.options.rst create mode 100644 documentation/apidoc/wntr.reaction.variables.rst create mode 100644 wntr/utils/citations.py diff --git a/documentation/apidoc/wntr.reaction.base.rst b/documentation/apidoc/wntr.reaction.base.rst new file mode 100644 index 000000000..6263973e7 --- /dev/null +++ b/documentation/apidoc/wntr.reaction.base.rst @@ -0,0 +1,7 @@ +wntr.reaction.base module +========================== + +.. automodule:: wntr.reaction.base + :members: + :undoc-members: + :show-inheritance: diff --git a/documentation/apidoc/wntr.reaction.dynamics.rst b/documentation/apidoc/wntr.reaction.dynamics.rst new file mode 100644 index 000000000..a1f8ae82a --- /dev/null +++ b/documentation/apidoc/wntr.reaction.dynamics.rst @@ -0,0 +1,7 @@ +wntr.reaction.dynamics module +============================== + +.. automodule:: wntr.reaction.dynamics + :members: + :undoc-members: + :show-inheritance: diff --git a/documentation/apidoc/wntr.reaction.options.rst b/documentation/apidoc/wntr.reaction.options.rst new file mode 100644 index 000000000..8d461d5b6 --- /dev/null +++ b/documentation/apidoc/wntr.reaction.options.rst @@ -0,0 +1,7 @@ +wntr.reaction.options module +============================ + +.. automodule:: wntr.reaction.options + :members: + :undoc-members: + :show-inheritance: diff --git a/documentation/apidoc/wntr.reaction.rst b/documentation/apidoc/wntr.reaction.rst index d8b61ab22..cf0d7e3d1 100644 --- a/documentation/apidoc/wntr.reaction.rst +++ b/documentation/apidoc/wntr.reaction.rst @@ -12,8 +12,11 @@ Submodules .. toctree:: :maxdepth: 4 + wntr.reaction.base + wntr.reaction.dynamics wntr.reaction.io wntr.reaction.library wntr.reaction.model wntr.reaction.options wntr.reaction.toolkitmsx + wntr.reaction.variables diff --git a/documentation/apidoc/wntr.reaction.variables.rst b/documentation/apidoc/wntr.reaction.variables.rst new file mode 100644 index 000000000..9a7d32b2e --- /dev/null +++ b/documentation/apidoc/wntr.reaction.variables.rst @@ -0,0 +1,7 @@ +wntr.reaction.variables module +============================== + +.. automodule:: wntr.reaction.variables + :members: + :undoc-members: + :show-inheritance: diff --git a/wntr/reaction/__init__.py b/wntr/reaction/__init__.py index 71fab1e33..d8a87d3b8 100644 --- a/wntr/reaction/__init__.py +++ b/wntr/reaction/__init__.py @@ -5,8 +5,4 @@ # pyomo.dae # sympy -from . import model, io, options, toolkitmsx -# from . import library -# from . import msx_toolkit -# from . import MSXPY_toolkit -# from . import msx_tools \ No newline at end of file +from . import base, dynamics, model, io, options, toolkitmsx, variables, library diff --git a/wntr/reaction/base.py b/wntr/reaction/base.py index c95521f03..c01012af6 100644 --- a/wntr/reaction/base.py +++ b/wntr/reaction/base.py @@ -1,17 +1,47 @@ +# -*- coding: utf-8 -*- + +""" +The base classes for the the wntr.reaction module. +Other than the enum classes, the classes in this module are all abstract +and/or mixin classes, and should not be instantiated directly. +""" + import abc -from abc import ABC, abstractmethod, abstractproperty -from collections.abc import MutableMapping import enum import logging -from dataclasses import InitVar, asdict, dataclass, field +from abc import ABC, abstractmethod, abstractproperty +from collections.abc import MutableMapping +from dataclasses import InitVar, dataclass from enum import Enum, IntFlag -from typing import Any, ClassVar, Dict, Generator, ItemsView, Iterator, KeysView, List, Set, Tuple, Union, ValuesView, Hashable -import datetime - -import sympy -from sympy import Float, Symbol, init_printing, symbols, Function -from sympy.parsing import parse_expr -from sympy.parsing.sympy_parser import convert_xor, standard_transformations +from typing import ( + Any, + ClassVar, + Dict, + Generator, + Hashable, + ItemsView, + Iterator, + KeysView, + List, + Set, + Tuple, + Union, + ValuesView, +) + +has_sympy = False +try: + from sympy import Float, Symbol, init_printing, symbols + from sympy.parsing import parse_expr + from sympy.parsing.sympy_parser import convert_xor, standard_transformations + + has_sympy = True +except ImportError: + sympy = None + logging.critical("This python installation does not have SymPy installed. Certain functionality will be disabled.") + standard_transformations = (None,) + convert_xor = None + has_sympy = False from wntr.network.model import WaterNetworkModel @@ -33,109 +63,52 @@ {"name": "Av", "note": "Surface area per unit volume (area units/L) "}, {"name": "Len", "note": "Pipe length (feet or meters)"}, ] -RESERVED_NAMES = tuple([v['name'] for v in HYDRAULIC_VARIABLES]) +"""The hydraulic variables defined in EPANET-MSX""" + +RESERVED_NAMES = tuple([v["name"] for v in HYDRAULIC_VARIABLES]) +"""The MSX reserved names as a tuple""" + SYMPY_RESERVED = ("E", "I", "pi") -EXPR_TRANSFORMS = standard_transformations + (convert_xor,) +"""Some extra names reserved by sympy""" -@dataclass -class Citation: - title: str - year: int - author: str = None - - # citation type/subtype (e.g., "report"/"tech. rep.") - citationtype: str = 'misc' - citationsubtype: str = None - - # document identifiers - doi: str = None - url: str = None - isrn: str = None - isbn: str = None - issn: str = None - eprint: str = None - - # container titles - journaltitle: str = None - maintitle: str = None - booktitle: str = None - issuetitle: str = None - - # conference/proceedings info - eventtitle: str = None - eventdate: datetime.date = None - venue: str = None - - # publishing info - institution: str = None - organization: str = None - publisher: str = None - location: str = None - howpublished: str = None - language: str = None - origlanguage: str = None - - # additional people - editor: str = None - bookauthor: str = None - translator: str = None - annotator: str = None - commentator: str = None - introduction: str = None - foreword: str = None - afterword: str = None - - # identifying info - issue: str = None - series: str = None - volume: str = None - number: str = None - part: str = None - edition: str = None - version: str = None - chapter: str = None - pages: str = None - volumes: str = None - pagetotal: str = None - - # dates - month: str = None - fulldate: datetime.date = None - urldate: datetime.date = None - - # extra - note: str = None - addendum: str = None - abstract: str = None - annotation: str = None +EXPR_TRANSFORMS = standard_transformations + (convert_xor,) +"""The sympy transforms to use in expression parsing""" class KeyInOtherGroupError(KeyError): + """The key exists but is in a different disjoint group""" + pass class VariableNameExistsError(KeyError): + """The name already exists in the reaction model""" + pass -class RxnVarType(Enum): +class RxnVariableType(Enum): """The type of reaction variable. - .. rubric:: Valid Values - - The following types are defined, and aliases of the first character + The following types are defined, and aliases of just the first character are also defined. + .. rubric:: Valid Values + .. autosummary:: - Bulk - Wall - Constant - Parameter - Term + BULK + WALL + CONSTANT + PARAMETER + TERM + INTERNAL - Species - Coeff + .. rubric:: Class methods + + .. autosummary:: + + factory """ @@ -150,27 +123,46 @@ class RxnVarType(Enum): TERM = 16 """A term that is aliased for ease of writing expressions""" INTERNAL = 32 - """An internal variable - see RESERVED_NAMES""" + """An internal variable - see :attr:`~wntr.reaction.base.RESERVED_NAMES`""" B = BULK - """Alias for :attr:`Bulk`""" + """Alias for :attr:`BULK`""" W = WALL - """Alias for :attr:`Wall`""" + """Alias for :attr:`WALL`""" C = CONSTANT - """Alias for :attr:`Constant`""" + """Alias for :attr:`CONSTANT`""" P = PARAMETER - """Alias for :attr:`Parameter`""" + """Alias for :attr:`PARAMETER`""" T = TERM - """Alias for :attr:`Term`""" + """Alias for :attr:`TERM`""" I = INTERNAL - """Alias for :attr:`Internal`""" + """Alias for :attr:`INTERNAL`""" CONST = CONSTANT - """Alias for :attr:`Constant`""" + """Alias for :attr:`CONSTANT`""" PARAM = PARAMETER - """Alias for :attr:`Parameter`""" + """Alias for :attr:`PARAMETER`""" @classmethod - def make(cls, value: Union[str, int, "RxnVarType"]): + def factory(cls, value: Union[str, int, "RxnVariableType"]) -> "RxnVariableType": + """Convert a value to a valid RxnVariableType. + + Parameters + ---------- + value : str or int or RxnVariableType + the value to change + + Returns + ------- + RxnVariableType + the equivalent variable type enum + + Raises + ------ + KeyError + the value is unknown/undefined + TypeError + the type of the value is wrong + """ if value is None: return if isinstance(value, cls): @@ -185,18 +177,26 @@ def make(cls, value: Union[str, int, "RxnVarType"]): raise TypeError("Invalid type '{}'".format(type(value))) -class RxnLocType(Enum): +class RxnLocationType(Enum): """What type of network component does this reaction occur in + The following types are defined, and aliases of just the first character + are also defined. + + .. rubric:: Valid values - The following types are defined, and aliases of the first character - are also defined. + .. autosummary:: + + PIPE + TANK + + .. rubric:: Class methods .. autosummary:: - Pipes - Tanks + factory + """ PIPE = 1 @@ -204,12 +204,31 @@ class RxnLocType(Enum): TANK = 2 """The expression describes a reaction in tanks""" P = PIPE - """Alias for :attr:`Pipes`""" + """Alias for :attr:`PIPE`""" T = TANK - """Alias for :attr:`Tanks`""" + """Alias for :attr:`TANK`""" @classmethod - def make(cls, value: Union[str, int, "RxnLocType"]): + def factory(cls, value: Union[str, int, "RxnLocationType"]) -> "RxnLocationType": + """Convert a value to a valid RxnLocationType. + + Parameters + ---------- + value : str or int or RxnLocationType + the value to process + + Returns + ------- + RxnLocationType + the equivalent enum object + + Raises + ------ + KeyError + the value is unknown/undefined + TypeError + the type of the value is wrong + """ if value is None: return if isinstance(value, cls): @@ -224,19 +243,26 @@ def make(cls, value: Union[str, int, "RxnLocType"]): raise TypeError("Invalid type '{}'".format(type(value))) -class RxnExprType(Enum): +class RxnDynamicsType(Enum): """The type of reaction expression. + The following types are defined, and aliases of just the first character + are also defined. + .. rubric:: Valid values - The following types are defined, and aliases of the first character - are also defined. + .. autosummary:: + + EQUIL + RATE + FORMULA + + .. rubric:: Class methods .. autosummary:: - Equil - Rate - Formula + factory + """ EQUIL = 1 @@ -246,14 +272,33 @@ class RxnExprType(Enum): FORMULA = 3 """used when the concentration of the named species is a simple function of the remaining species""" E = EQUIL - """Alias for :attr:`Equil`""" + """Alias for :attr:`EQUIL`""" R = RATE - """Alias for :attr:`Rate`""" + """Alias for :attr:`RATE`""" F = FORMULA - """Alias for :attr:`Formula`""" + """Alias for :attr:`FORMULA`""" @classmethod - def make(cls, value: Union[str, int, "RxnExprType"]): + def factory(cls, value: Union[str, int, "RxnDynamicsType"]) -> "RxnDynamicsType": + """Convert a value to a RxnDynamicsType. + + Parameters + ---------- + value : str or int or RxnDynamicsType + the value to convert + + Returns + ------- + RxnDynamicsType + the enum value + + Raises + ------ + KeyError + the value is unknown/undefined + TypeError + the type of the value is wrong + """ if value is None: return if isinstance(value, cls): @@ -450,80 +495,161 @@ def __repr__(self) -> str: @dataclass -class ReactionVariable(ABC): +class RxnVariable(ABC): + """The base for a reaction variable. + + Parameters + ---------- + name : str + the name/symbol of the variable + """ name: str + """The name (symbol) for the variable, must be a valid MSX name""" + + def __str__(self) -> str: + """Returns the name of the variable""" + return self.name + + def __hash__(self) -> int: + """Makes the variable hashable by hashing the `str` representation""" + return hash(str(self)) @abstractproperty - def var_type(self) -> RxnVarType: + def var_type(self) -> RxnVariableType: + """The variable type.""" raise NotImplementedError - @abstractmethod - def to_msx_string(self) -> str: - raise NotImplementedError + def is_species(self) -> bool: + """Check to see if this variable represents a species (bulk or wall). + + Returns + ------- + bool + True if this is a species object, False otherwise + """ + return self.var_type == RxnVariableType.BULK or self.var_type == RxnVariableType.WALL + + def is_coeff(self) -> bool: + """Check to see if this variable represents a coefficient (constant or parameter). + + Returns + ------- + bool + True if this is a coefficient object, False otherwise + """ + return self.var_type == RxnVariableType.CONST or self.var_type == RxnVariableType.PARAM + + def is_term_function(self) -> bool: + """Check to see if this variable represents a function (MSX term). + + Returns + ------- + bool + True if this is a term/function object, False otherwise + """ + return self.var_type == RxnVariableType.TERM @property def symbol(self): - return sympy.Symbol(self.name) - - def __str__(self) -> str: - return self.name - - def __hash__(self) -> int: - return hash(str(self)) + """Representation of the variable's name as a sympy.Symbol""" + return Symbol(self.name) @dataclass -class ReactionDynamics(ABC): - - species: str - location: RxnLocType +class RxnReaction(ABC): + """The base for a reaction. - @abstractproperty - def expr_type(self) -> RxnExprType: - raise NotImplementedError + Parameters + ---------- + species : str + the name of the species whose reaction dynamics is being described + location : RxnLocationType or str + the location the reaction occurs (pipes or tanks) + expression : str + the expression for the reaction dynamics (right-hand-side) + """ - @abstractmethod - def to_msx_string(self) -> str: - raise NotImplementedError + species: str + """The name of the species that this reaction describes""" + location: RxnLocationType + """The location this reaction occurs (pipes vs tanks)""" + expression: str + """The expression for the reaction dynamics (or, the right-hand-side of the equation)""" def __str__(self) -> str: + """Names the reaction with the format `species-dot-location` (for example, ``PB2.pipe``)""" return self.to_key(self.species, self.location) - @classmethod - def to_key(cls, species, location): - location = RxnLocType.make(location) - return species + "." + location.name.lower() - def __hash__(self) -> int: + """Makes the reaction hashable by hashing the `str` representation""" return hash(str(self)) + @abstractproperty + def expr_type(self) -> RxnDynamicsType: + """The type of reaction dynamics being described (or, the left-hand-side of the equation)""" + raise NotImplementedError -class VariableRegistry(ABC): + @classmethod + def to_key(cls, species, location): + """Generate a dictionary key (equivalent to the ``str`` casting of a reaction) + without having the object itself. + + Parameters + ---------- + species : str + the species for the reaction + location : RxnLocationType or str + the location of the reaction + + Returns + ------- + str + a species/location unique name + """ + location = RxnLocationType.factory(location) + return str(species) + "." + location.name.lower() + + +class RxnModelRegistry(ABC): @abstractmethod def variables(self, var_type=None): + """Generator over all defined variables, optionally limited by variable type""" raise NotImplementedError @abstractmethod - def get_variable(self, name: str) -> ReactionVariable: + def add_variable(self, __variable: RxnVariable): + """Add a variable *object* to the model""" raise NotImplementedError @abstractmethod - def del_variable(self, name: str): + def get_variable(self, name: str) -> RxnVariable: + """Get a specific variable by name""" raise NotImplementedError + @abstractmethod + def remove_variable(self, name: str): + """Delete a specified variable from the model""" + raise NotImplementedError -class ReactionRegistry(ABC): @abstractmethod def reactions(self, location=None): + """Generator over all defined reactions, optionally limited by reaction location""" + raise NotImplementedError + + @abstractmethod + def add_reaction(self, __reaction: RxnReaction): + """Add a reaction *object* to the model""" raise NotImplementedError @abstractmethod - def get_reaction(self, species, location=None) -> List[ReactionDynamics]: + def get_reaction(self, species, location=None) -> List[RxnReaction]: + """Get reaction(s) for a species, optionally only for one location""" raise NotImplementedError @abstractmethod - def del_reaction(self, species, location=None): + def remove_reaction(self, species, location=None): + """Remove reaction(s) for a species, optionally only for one location""" raise NotImplementedError @@ -532,21 +658,55 @@ class LinkedVariablesMixin: __variable_registry = None @property - def _variable_registry(self) -> VariableRegistry: + def _variable_registry(self) -> RxnModelRegistry: return self.__variable_registry @_variable_registry.setter def _variable_registry(self, value): - if value is not None and not isinstance(value, VariableRegistry): - raise TypeError("Linked model must be a RxnModel, got {}".format(type(value))) + if value is not None and not isinstance(value, RxnModelRegistry): + raise TypeError("Linked model must be a RxnModelRegistry, got {}".format(type(value))) self.__variable_registry = value + def validate(self): + """Validate that this object is a member of the RxnModelRegistry + + Raises + ------ + TypeError + if the model registry isn't linked + """ + if not isinstance(self._variable_registry, RxnModelRegistry): + raise TypeError("This object is not connected to any RxnModelRegistry") + @dataclass class ExpressionMixin(ABC): - - expression: str + """A mixin class for converting an expression to a sympy Expr""" @abstractmethod - def sympify(self): + def to_symbolic(self, transformations=EXPR_TRANSFORMS): + """Convert to a symbolic expression. + + Parameters + ---------- + transformations : tuple of sympy transformations + transformations to apply to the expression, by default EXPR_TRANSFORMS + + Returns + ------- + sympy.Expr + the expression parsed by sympy + """ + return parse_expr(self.expression, transformations=transformations) + + +class MSXObject: + def to_msx_string(self) -> str: + """Get the expression as an EPANET-MSX input-file style string. + + Returns + ------- + str + the expression for use in an EPANET-MSX input file + """ raise NotImplementedError diff --git a/wntr/reaction/dynamics.py b/wntr/reaction/dynamics.py index 06de1feb1..bb1ddce74 100644 --- a/wntr/reaction/dynamics.py +++ b/wntr/reaction/dynamics.py @@ -1,78 +1,213 @@ +# -*- coding: utf-8 -*- + +r""" +Classes for the species reactions used in reaction models. +Defines a reaction based on the type of reaction dynamics, e.g., equilibrium +or rate-of-change. The dynamics, or ``expr_type`` determine the left-hand-side of a reaction +equation, while the ``expression`` provides the right-hand-side. + +In other words, the ``expr_type``, ``species`` and ``expression`` attributes of all +reaction class objects can be read as: + +.. math:: + + expr\_type(species) = expression(vars,...). + + +For a ``RATE`` reaction, this equates to: + +.. math:: + + \frac{d}{dt}C(species) = f(vars,...) + + +The classes in this module can be created directly. However, they are more +powerful when either, a) created using API calls on a :class:`~wntr.reaction.model.WaterNetworkModel`, +or, b) linked to a :class:`~wntr.reaction.model.WaterNetworkModel` model object after creation. +This allows for expressions to be validated against the variables defined in the model. + +If :class:`sympy` is installed, then there are functions available +that will convert object instances of these classes into sympy expressions +and symbols. If the instances are linked to a model, then expressions can +be expanded, validated, and even evaluated or simplified symbolically. +""" import enum import logging from dataclasses import InitVar, asdict, dataclass, field from enum import Enum, IntFlag from typing import Any, ClassVar, Dict, List, Set, Tuple, Union -import sympy -from sympy import Float, Function, Symbol, init_printing, symbols -from sympy.parsing import parse_expr -from sympy.parsing.sympy_parser import convert_xor, standard_transformations +has_sympy = False +try: + from sympy import Float, Symbol, init_printing, symbols + from sympy.parsing import parse_expr + from sympy.parsing.sympy_parser import convert_xor, standard_transformations -from wntr.network.model import WaterNetworkModel -from wntr.reaction.base import RxnVarType + has_sympy = True +except ImportError: + sympy = None + logging.critical("This python installation does not have SymPy installed. Certain functionality will be disabled.") + standard_transformations = (None,) + convert_xor = None + has_sympy = False -from .base import ExpressionMixin, LinkedVariablesMixin, RxnExprType, RxnLocType, VariableRegistry, ReactionDynamics, RxnVarType -from .variables import Coefficient, OtherTerm, Species +from wntr.network.model import WaterNetworkModel +from wntr.reaction.base import EXPR_TRANSFORMS, MSXObject, RxnVariableType + +from .base import ( + ExpressionMixin, + LinkedVariablesMixin, + RxnDynamicsType, + RxnLocationType, + RxnModelRegistry, + RxnReaction, + RxnVariableType, +) +from .variables import Coefficient, Species, OtherTerm logger = logging.getLogger(__name__) -class MSXDefinedDynamicsMixin: - def to_msx_string(self) -> str: - """Get the expression as an EPANET-MSX input-file style string. - - Returns - ------- - str - the expression for use in an EPANET-MSX input file - """ - return "{} {} {} ;{}".format(self.expr_type.name.upper(), str(self.species), self.expression, self.note if self.note else "") - - @dataclass(repr=False) -class RateDynamics(MSXDefinedDynamicsMixin, LinkedVariablesMixin, ExpressionMixin, ReactionDynamics): +class RateDynamics(MSXObject, LinkedVariablesMixin, ExpressionMixin, RxnReaction): + r"""Used to supply the equation that expresses the rate of change of the given species + with respect to time as a function of the other species in the model. + + .. math:: + + \frac{d}{dt} C(species) = expression + + + Parameters + ---------- + species : str + the name of the species whose reaction dynamics is being described + location : RxnLocationType or str + the location the reaction occurs (pipes or tanks) + expression : str + the expression for the reaction dynamics, which is the rate-of-change of the species concentration + note : str, optional + a note about this reaction + variable_registry : RxnModelRegistry, optional + a link to the remainder of the larger model + """ note: str = None - variable_registry: InitVar[VariableRegistry] = field(default=None, compare=False) + """A note or comment about this species reaction dynamics""" + variable_registry: InitVar[RxnModelRegistry] = field(default=None, compare=False) + """A link to the reaction model with variables""" def __post_init__(self, variable_registry): self._variable_registry = variable_registry @property - def expr_type(self) -> RxnExprType: - return RxnExprType.RATE + def expr_type(self) -> RxnDynamicsType: + return RxnDynamicsType.RATE + + def to_symbolic(self, transformations=...): + return super().to_symbolic(transformations) + + def to_msx_string(self) -> str: + return "{} {} {} ;{}".format(self.expr_type.name.upper(), str(self.species), self.expression, self.note if self.note else "") + + def to_dict(self) -> dict: + rep = dict(species=self.species, expr_type=self.expr_type.name.lower(), expression=self.expression) + if self.note is not None: + rep['note'] = self.note + return rep - def sympify(self): - raise NotImplementedError @dataclass(repr=False) -class EquilibriumDynamics(MSXDefinedDynamicsMixin, LinkedVariablesMixin, ExpressionMixin, ReactionDynamics): +class EquilibriumDynamics(MSXObject, LinkedVariablesMixin, ExpressionMixin, RxnReaction): + """Used for equilibrium expressions where it is assumed that the expression supplied is being equated to zero. + + .. math:: + + 0 = expression + + + Parameters + ---------- + species : str + the name of the species whose reaction dynamics is being described + location : RxnLocationType or str + the location the reaction occurs (pipes or tanks) + expression : str + the expression for the reaction dynamics, which should equal to zero + note : str, optional + a note about this reaction + variable_registry : RxnModelRegistry, optional + a link to the remainder of the larger model + """ + note: str = None - variable_registry: InitVar[VariableRegistry] = field(default=None, compare=False) + """A note or comment about this species reaction dynamics""" + variable_registry: InitVar[RxnModelRegistry] = field(default=None, compare=False) + """A link to the reaction model with variables""" def __post_init__(self, variable_registry): self._variable_registry = variable_registry @property - def expr_type(self) -> RxnExprType: - return RxnExprType.EQUIL + def expr_type(self) -> RxnDynamicsType: + return RxnDynamicsType.EQUIL + + def to_symbolic(self, transformations=...): + return super().to_symbolic(transformations) + + def to_msx_string(self) -> str: + return "{} {} {} ;{}".format(self.expr_type.name.upper(), str(self.species), self.expression, self.note if self.note else "") - def sympify(self): - raise NotImplementedError + def to_dict(self) -> dict: + rep = dict(species=self.species, expr_type=self.expr_type.name.lower(), expression=self.expression) + if self.note is not None: + rep['note'] = self.note + return rep @dataclass(repr=False) -class FormulaDynamics(MSXDefinedDynamicsMixin, LinkedVariablesMixin, ExpressionMixin, ReactionDynamics): +class FormulaDynamics(MSXObject, LinkedVariablesMixin, ExpressionMixin, RxnReaction): + """Used when the concentration of the named species is a simple function of the remaining species. + + .. math:: + + C(species) = expression + + + Parameters + ---------- + species : str + the name of the species whose reaction dynamics is being described + location : RxnLocationType or str + the location the reaction occurs (pipes or tanks) + expression : str + the expression for the reaction formula, which is used to calculate the concentration of the species + note : str, optional + a note about this reaction + variable_registry : RxnModelRegistry, optional + a link to the remainder of the larger model + """ + note: str = None - variable_registry: InitVar[VariableRegistry] = field(default=None, compare=False) + """A note or comment about this species reaction dynamics""" + variable_registry: InitVar[RxnModelRegistry] = field(default=None, compare=False) + """A link to the reaction model with variables""" def __post_init__(self, variable_registry): self._variable_registry = variable_registry @property - def expr_type(self) -> RxnExprType: - return RxnExprType.FORMULA + def expr_type(self) -> RxnDynamicsType: + return RxnDynamicsType.FORMULA + + def to_symbolic(self, transformations=...): + return super().to_symbolic(transformations) + + def to_msx_string(self) -> str: + return "{} {} {} ;{}".format(self.expr_type.name.upper(), str(self.species), self.expression, self.note if self.note else "") - def sympify(self): - raise NotImplementedError + def to_dict(self) -> dict: + rep = dict(species=self.species, expr_type=self.expr_type.name.lower(), expression=self.expression) + if self.note is not None: + rep['note'] = self.note + return rep diff --git a/wntr/reaction/io.py b/wntr/reaction/io.py index fbb8cd302..4110db4bd 100644 --- a/wntr/reaction/io.py +++ b/wntr/reaction/io.py @@ -1,9 +1,9 @@ # coding: utf-8 -import sys import logging -from wntr.network.elements import Source +import sys +from wntr.network.elements import Source from wntr.reaction.model import WaterQualityReactionsModel from wntr.reaction.variables import Parameter, Species @@ -58,7 +58,17 @@ def read(self, msx_file, rxn_model=None): Read an EPANET-MSX input file (.msx) and load data into a water quality reactions model. Only MSX 2.0 files are recognized. - + Parameters + ---------- + msx_file : str + the filename of the .msx file to read in + rxn_model : WaterQualityReactionsModel, optional + the model to put data into, by default None (new model) + + Returns + ------- + WaterQualityReactionsModel + the model with the new species, reactions and other options added """ if rxn_model is None: rxn_model = WaterQualityReactionsModel() @@ -134,159 +144,256 @@ def read(self, msx_file, rxn_model=None): def _read_title(self): lines = [] - for lnum, line in self.sections['[TITLE]']: - line = line.split(';')[0] - current = line.split() - if current == []: - continue - lines.append(line) + title = None + comments = "" + for lnum, line in self.sections["[TITLE]"]: + vals, comment = _split_line(line) + if title is None and vals is not None: + title = " ".join(vals) + if comment: + lines.append(comment.strip()) + if self.top_comments: + comments = "\n".join(self.top_comments) if len(lines) > 0: - self.rxn.title = lines[0] - if len(lines) > 1: - self.rxn.desc = '\n'.join(lines[1:]) + comments = comments + ("\n" if comments else "") + "\n".join(lines) + self.rxn.title = title + self.rxn.desc = comments def _read_options(self): lines = [] - for lnum, line in self.sections['[OPTIONS]']: + prev_comment = None + for lnum, line in self.sections["[OPTIONS]"]: vals, comment = _split_line(line) - if len(vals) != 2: - raise RuntimeError('Invalid options line: "{}"'.format(line)) - name, val = vals[0].upper(), vals[1].upper() try: - if name == 'AREA_UNITS': + if len(vals) != 2: + raise SyntaxError("Invalid [OPTIONS] entry") + name, val = vals[0].upper(), vals[1].upper() + if name == "AREA_UNITS": self.rxn._options.quality.area_units = val - elif name == 'RATE_UNITS': + elif name == "RATE_UNITS": self.rxn._options.quality.rate_units = val - elif name == 'SOLVER': + elif name == "SOLVER": self.rxn._options.quality.solver = val - elif name == 'COUPLING': + elif name == "COUPLING": self.rxn._options.quality.coupling = val - elif name == 'TIMESTEP': - self.rxn._options.time.timestep = int(val) - elif name == 'ATOL': + elif name == "TIMESTEP": + self.rxn._options.quality.timestep = int(val) + elif name == "ATOL": self.rxn._options.quality.atol = float(val) - elif name == 'RTOL': + elif name == "RTOL": self.rxn._options.quality.rtol = float(val) - elif name == 'COMPILER': + elif name == "COMPILER": self.rxn._options.quality.compiler = val - elif name == 'SEGMENTS': + elif name == "SEGMENTS": self.rxn._options.quality.segments = int(val) - elif name == 'PECLET': + elif name == "PECLET": self.rxn._options.quality.peclet = int(val) except Exception as e: - raise ('Error in options line: "{}"'.format(line)) from e - + raise RuntimeError('Error on line {} of file "{}": {}'.format(lnum, self.rxn.filename, line)) from e + def _read_species(self): lines = [] - for lnum, line in self.sections['[SPECIES]']: + prev_comment = None + for lnum, line in self.sections["[SPECIES]"]: vals, comment = _split_line(line) - if len(vals) not in [3, 5]: - raise RuntimeError('Invalid species line: "{}"'.format(line)) + if vals is None: + prev_comment = comment + continue + if prev_comment is not None and comment is None: + comment = prev_comment + prev_comment = None try: + if len(vals) not in [3, 5]: + raise SyntaxError("Invalid [SPECIES] entry") if len(vals) == 3: species = self.rxn.add_species(vals[0], vals[1], vals[2], note=comment) elif len(vals) == 5: species = self.rxn.add_species(vals[0], vals[1], vals[2], float(vals[3]), float(vals[4]), note=comment) except Exception as e: - raise RuntimeError('Invalid species line: "{}"'.format(line)) from e + raise RuntimeError('Error on line {} of file "{}": {}'.format(lnum, self.rxn.filename, line)) from e def _read_coefficients(self): lines = [] - for lnum, line in self.sections['[COEFFICIENTS]']: + prev_comment = None + for lnum, line in self.sections["[COEFFICIENTS]"]: vals, comment = _split_line(line) - if len(vals) != 3: - raise RuntimeError('Invalid coefficient line: "{}"'.format(line)) + if vals is None: + prev_comment = comment + continue + if prev_comment is not None and comment is None: + comment = prev_comment + prev_comment = None try: + if len(vals) != 3: + raise SyntaxError("Invalid [COEFFICIENTS] entry") coeff = self.rxn.add_coefficient(vals[0], vals[1], float(vals[2]), note=comment) except Exception as e: - raise RuntimeError('Invalid coefficient line: "{}"'.format(line)) from e + raise RuntimeError('Error on line {} of file "{}": {}'.format(lnum, self.rxn.filename, line)) from e def _read_terms(self): lines = [] - for lnum, line in self.sections['[TERMS]']: + prev_comment = None + for lnum, line in self.sections["[TERMS]"]: vals, comment = _split_line(line) - if len(vals) < 2: - raise RuntimeError('Invalid term line: "{}"'.format(line)) - term = self.rxn.add_other_term(vals[0], ' '.join(vals[1:]), note=comment) + if vals is None: + prev_comment = comment + continue + if prev_comment is not None and comment is None: + comment = prev_comment + prev_comment = None + try: + if len(vals) < 2: + raise SyntaxError("Invalid [TERMS] entry") + term = self.rxn.add_other_term(vals[0], " ".join(vals[1:]), note=comment) + except Exception as e: + raise RuntimeError('Error on line {} of file "{}": {}'.format(lnum, self.rxn.filename, line)) from e def _read_pipes(self): lines = [] - for lnum, line in self.sections['[PIPES]']: + prev_comment = None + for lnum, line in self.sections["[PIPES]"]: vals, comment = _split_line(line) - if len(vals) < 3: - raise RuntimeError('Invalid tanks line: "{}"'.format(line)) - reaction = self.rxn.add_pipe_reaction(vals[0], vals[1], vals[2:], note=comment) + if vals is None: + prev_comment = comment + continue + if prev_comment is not None and comment is None: + comment = prev_comment + prev_comment = None + try: + if len(vals) < 3: + raise SyntaxError("Invalid [PIPES] entry") + reaction = self.rxn.add_pipe_reaction(vals[1], vals[0], " ".join(vals[2:]), note=comment) + except Exception as e: + raise RuntimeError('Error on line {} of file "{}": {}'.format(lnum, self.rxn.filename, line)) from e def _read_tanks(self): lines = [] - for lnum, line in self.sections['[TANKS]']: + prev_comment = None + for lnum, line in self.sections["[TANKS]"]: vals, comment = _split_line(line) - if len(vals) < 3: - raise RuntimeError('Invalid tanks line: "{}"'.format(line)) - reaction = self.rxn.add_tank_reaction(vals[0], vals[1], vals[2:], note=comment) + if vals is None: + prev_comment = comment + continue + if prev_comment is not None and comment is None: + comment = prev_comment + prev_comment = None + try: + if len(vals) < 3: + raise SyntaxError("Invalid [TANKS] entry") + reaction = self.rxn.add_tank_reaction(vals[1], vals[0], " ".join(vals[2:]), note=comment) + except Exception as e: + raise RuntimeError('Error on line {} of file "{}": {}'.format(lnum, self.rxn.filename, line)) from e def _read_sources(self): lines = [] - for lnum, line in self.sections['[SOURCES]']: + prev_comment = None + for lnum, line in self.sections["[SOURCES]"]: vals, comment = _split_line(line) + if vals is None: + prev_comment = comment + continue + if prev_comment is not None and comment is None: + comment = prev_comment + prev_comment = None try: if len(vals) == 4: typ, node, spec, strength = vals pat = None else: typ, node, spec, strength, pat = vals + if not self.rxn.has_variable(spec): + raise ValueError('Undefined species in [QUALITY] section: {}'.format(spec)) + if spec not in self.rxn._sources.keys(): + self.rxn._sources[spec] = dict() source = Source(None, name=spec, node_name=node, source_type=typ, strength=strength, pattern=pat) - self.rxn._sources['{}:{}:{}'.format(typ,node,spec)] = source + self.rxn._sources[spec][node] = source except Exception as e: - raise RuntimeError('Invalid sources line: "{}"'.format(line)) from e + raise RuntimeError('Error on line {} of file "{}": {}'.format(lnum, self.rxn.filename, line)) from e def _read_quality(self): lines = [] - for lnum, line in self.sections['[QUALITY]']: + prev_comment = None + for lnum, line in self.sections["[QUALITY]"]: vals, comment = _split_line(line) - self.rxn._inital_quality.extend(lines) + if len(vals) == 0: continue + if vals is None: + prev_comment = comment + continue + if prev_comment is not None and comment is None: + comment = prev_comment + prev_comment = None + try: + if len(vals) == 4: + cmd, netid, spec, concen = vals + else: + cmd, spec, concen = vals + if cmd[0].lower() not in ['g', 'n', 'l']: + raise SyntaxError('Unknown first word in [QUALITY] section') + if not self.rxn.has_variable(spec): + raise ValueError('Undefined species in [QUALITY] section: {}'.format(spec)) + if spec not in self.rxn._inital_quality.keys(): + self.rxn._inital_quality[spec] = dict(global_value=None, nodes=dict(), links=dict()) + if cmd[0].lower() == 'g': + self.rxn._inital_quality[spec]['global_value'] = float(concen) + elif cmd[0].lower() == 'n': + self.rxn._inital_quality[spec]['nodes'][netid] = float(concen) + elif cmd[1].lower() == 'l': + self.rxn._inital_quality[spec]['links'][netid] = float(concen) + except Exception as e: + raise RuntimeError('Error on line {} of file "{}": {}'.format(lnum, self.rxn.filename, line)) from e def _read_parameters(self): lines = [] - for lnum, line in self.sections['[PARAMETERS]']: + prev_comment = None + for lnum, line in self.sections["[PARAMETERS]"]: vals, comment = _split_line(line) + if vals is None: + prev_comment = comment + continue + if prev_comment is not None and comment is None: + comment = prev_comment + prev_comment = None try: typ, netid, paramid, value = vals coeff = self.rxn.get_variable(paramid) if not isinstance(coeff, Parameter): - raise RuntimeError('Invalid parameter {}'.format(paramid)) + raise RuntimeError("Invalid parameter {}".format(paramid)) value = float(value) - if typ.lower()[0] == 'p': + if typ.lower()[0] == "p": coeff.pipe_values[netid] = vals - elif typ.lower()[0] == 't': + elif typ.lower()[0] == "t": coeff.tank_values[netid] = vals else: - raise RuntimeError('Invalid parameter type {}'.format(typ)) + raise RuntimeError("Invalid parameter type {}".format(typ)) except Exception as e: - raise RuntimeError('Invalid parameters line: "{}"'.format(line)) from e + raise RuntimeError('Error on line {} of file "{}": {}'.format(lnum, self.rxn.filename, line)) from e def _read_diffusivity(self): lines = [] - for lnum, line in self.sections['[DIFFUSIVITY]']: + prev_comment = None + for lnum, line in self.sections["[DIFFUSIVITY]"]: vals, comment = _split_line(line) - if len(vals) != 2: - raise RuntimeError('Error in diffusivity line: "{}"'.format(line)) + if vals is None: + prev_comment = comment + continue + if prev_comment is not None and comment is None: + comment = prev_comment + prev_comment = None try: + if len(vals) != 2: + raise SyntaxError("Invalid [DIFFUSIVITIES] entry") species = self.rxn.get_variable(vals[0]) - except: - raise RuntimeError('Invalid species {} in diffusivity line: "{}"'.format(vals[0], line)) - if not isinstance(species, Species): - raise RuntimeError('Invalid species {} in diffusivity line: "{}"'.format(vals[0], line)) - try: + if not isinstance(species, Species): + raise RuntimeError("Invalid species {} in diffusivity".format(vals[0])) species.diffusivity = float(vals[1]) except Exception as e: - raise RuntimeError('Error in diffusivity line: "{}"'.format(line)) from e + raise RuntimeError('Error on line {} of file "{}": {}'.format(lnum, self.rxn.filename, line)) from e def _read_patterns(self): _patterns = dict() - for lnum, line in self.sections['[PATTERNS]']: + for lnum, line in self.sections["[PATTERNS]"]: # read the lines for each pattern -- patterns can be multiple lines of arbitrary length - line = line.split(';')[0] + line = line.split(";")[0] current = line.split() if current == []: continue @@ -301,13 +408,62 @@ def _read_patterns(self): for pattern_name, pattern in _patterns.items(): # add the patterns to the water newtork model self.rxn.add_pattern(pattern_name, pattern) - def _read_report(self): lines = [] - for lnum, line in self.sections['[REPORT]']: + prev_comment = None + for lnum, line in self.sections["[REPORT]"]: vals, comment = _split_line(line) - self.rxn._report.extend(lines) + if vals is None: + prev_comment = comment + continue + if prev_comment is not None and comment is None: + comment = prev_comment + prev_comment = None + try: + if len(vals) == 0: + continue + if len(vals) < 2: + raise SyntaxError('Invalid number of arguments in [REPORT] section') + cmd = vals[0][0].lower() + if cmd == 'n': # NODES + if self.rxn._options.report.nodes is None: + if vals[1].upper() == 'ALL': + self.rxn._options.report.nodes = 'ALL' + else: + self.rxn._options.report.nodes = list() + self.rxn._options.report.nodes.extend(vals[1:]) + elif isinstance(self.rxn._options.report.nodes, list): + if vals[1].upper() == 'ALL': + self.rxn._options.report.nodes = 'ALL' + else: + self.rxn._options.report.nodes.extend(vals[1:]) + elif cmd == 'l': # LINKS + if self.rxn._options.report.links is None: + if vals[1].upper() == 'ALL': + self.rxn._options.report.links = 'ALL' + else: + self.rxn._options.report.links = list() + self.rxn._options.report.links.extend(vals[1:]) + elif isinstance(self.rxn._options.report.links, list): + if vals[1].upper() == 'ALL': + self.rxn._options.report.links = 'ALL' + else: + self.rxn._options.report.links.extend(vals[1:]) + elif cmd == 'f': + self.rxn._options.report.report_filename = vals[1] + elif cmd == 'p': + self.rxn._options.report.pagesize = vals[1] + elif cmd == 's': + if not self.rxn.has_variable(vals[1]): + raise ValueError('Undefined species in [REPORT] section: {}'.format(vals[1])) + self.rxn._options.report.species[vals[1]] = True if vals[2].lower().startswith('y') else False + if len(vals) == 4: + self.rxn._options.report.species_precision[vals[1]] = int(vals[3]) + else: + raise SyntaxError('Invalid syntax in [REPORT] section: unknown first word') + except Exception as e: + raise RuntimeError('Error on line {} of file "{}": {}'.format(lnum, self.rxn.filename, line)) from e def write(self, filename, rxn_model): pass diff --git a/wntr/reaction/library.py b/wntr/reaction/library.py index 16c692e67..feacbac13 100644 --- a/wntr/reaction/library.py +++ b/wntr/reaction/library.py @@ -1,25 +1,45 @@ # -*- coding: utf-8 -*- +# @Contributors: +# Jonathan Burkhardt, U.S. Environmental Protection Agency, Office of Research and Development + """ -Library of common reactions. +A library of common reactions. +Values in libarary are for test purposes ONLY. These highlight the reaction form/relationship +but not necessarily the specific system kinetics. Citations are provided where appropriate for +sources of values or models. In most cases updates will be necessary to use for different +models - that is, sources, pipes, nodes are for a given network, and must be updated for different +models. + +.. autosummary:: + + nicotine + nicotine_ri + lead_ppm -@author: John Burkhart, US EPA ORD """ +import logging -from .base import Citation +from ..utils.citations import Citation from .model import WaterQualityReactionsModel +logger = logging.getLogger(__name__) + +# ===================== Nicotine-chlorine model +# nicotine = WaterQualityReactionsModel( title="Nicotine - Chlorine reaction", - desc="Values in libarary are for test purposes ONLY. These highlight the reaction form/relationship but not necessarily the specific system kinetics. Citations are provided where appropriate for sources of values or models. In most cases updates will be necessary to use for different models -- That is, sources, pipes, nodes are for a given network, and must be updated for different models.", + desc="Values in libarary are for test purposes ONLY.", ) +"""A nicotine-chlorine reaction model""" + nicotine.options.quality.area_units = "M2" nicotine.options.quality.rate_units = "MIN" -nicotine.options.time.timestep = 1 -nicotine.add_bulk_species("Nx", unit="MG", note="Nicotine") -nicotine.add_bulk_species("HOCL", unit="MG", note="Free chlorine") -nicotine.add_constant_coeff("kd", global_value=2.33e-3, unit="min^(-1)", note="decay rate") -nicotine.add_constant_coeff("K1", global_value=5.92e-2, unit="L * min^(-1) * mg^(-1)", note="decay constant for chlorine as function of mass(Nic)") -nicotine.add_constant_coeff("K2", global_value=1.84e-1, unit="L * min^(-1) * mg^(-1)", note="decay constant for nicotine as function of mass(Cl)") +nicotine.options.quality.timestep = 1 +nicotine.add_bulk_species("Nx", units="MG", note="Nicotine") +nicotine.add_bulk_species("HOCL", units="MG", note="Free chlorine") +nicotine.add_constant_coeff("kd", global_value=2.33e-3, units="min^(-1)", note="decay rate") +nicotine.add_constant_coeff("K1", global_value=5.92e-2, units="L * min^(-1) * mg^(-1)", note="decay constant for chlorine as function of mass(Nic)") +nicotine.add_constant_coeff("K2", global_value=1.84e-1, units="L * min^(-1) * mg^(-1)", note="decay constant for nicotine as function of mass(Cl)") nicotine.add_other_term("RXCL", expression="kd * HOCL + K1 * Nx * HOCL") nicotine.add_other_term("RXN", expression="K2 * Nx * HOCL") nicotine.add_pipe_reaction("Nx", "rate", expression="-RXN") @@ -27,49 +47,48 @@ nicotine.add_tank_reaction("Nx", "rate", "0") nicotine.add_tank_reaction("HOCL", "rate", "0") - +# ===================== Nicotine-chlorine reactive intermediate species +# nicotine_ri = WaterQualityReactionsModel( title="Nicotine - Chlorine reaction with reactive intermediate", + desc="Values in libarary are for test purposes ONLY.", ) -# Set options +"""A nicotine-chlorine reaction with a reactive intermediate""" +# Set the options nicotine_ri.options.quality.area_units = "M2" nicotine_ri.options.quality.rate_units = "MIN" -nicotine_ri.options.time.timestep = 1 +nicotine_ri.options.quality.timestep = 1 nicotine_ri.options.quality.atol = 1.0e-10 nicotine_ri.options.quality.rtol = 1.0e-10 - # Add species -nicotine_ri.add_bulk_species("Nx", unit="MG", note="Nicotine") -nicotine_ri.add_bulk_species("HOCL", unit="MG", note="Free Chlorine") -nicotine_ri.add_bulk_species("NX2", unit="MG", note="Intermediate Nicotine Reactive") - +nicotine_ri.add_bulk_species("Nx", units="MG", note="Nicotine") +nicotine_ri.add_bulk_species("HOCL", units="MG", note="Free Chlorine") +nicotine_ri.add_bulk_species("NX2", units="MG", note="Intermediate Nicotine Reactive") # Add coefficients -nicotine_ri.add_constant_coeff("kd", 3.0e-5, note="decay rate", unit="1/min") -nicotine_ri.add_constant_coeff("K1", global_value=9.75e-2, unit="L * min^(-1) * mg^(-1)", note="decay constant for chlorine as function of mass(Nic)") -nicotine_ri.add_constant_coeff("K2", global_value=5.73e-1, unit="L * min^(-1) * mg^(-1)", note="decay constant for nicotine as function of mass(Cl)") -nicotine_ri.add_constant_coeff("K3", global_value=1.34e-2, unit="L * min^(-1) * mg^(-1)", note="decay constant for nicotine as function of mass(N2)") -nicotine_ri.add_constant_coeff("K4", global_value=2.19e-2, unit="L * min^(-1) * mg^(-1)", note="decay constant for nicotine as function of mass(Cl)") - +nicotine_ri.add_constant_coeff("kd", 3.0e-5, note="decay rate", units="1/min") +nicotine_ri.add_constant_coeff("K1", global_value=9.75e-2, units="L * min^(-1) * mg^(-1)", note="decay constant for chlorine as function of mass(Nic)") +nicotine_ri.add_constant_coeff("K2", global_value=5.73e-1, units="L * min^(-1) * mg^(-1)", note="decay constant for nicotine as function of mass(Cl)") +nicotine_ri.add_constant_coeff("K3", global_value=1.34e-2, units="L * min^(-1) * mg^(-1)", note="decay constant for nicotine as function of mass(N2)") +nicotine_ri.add_constant_coeff("K4", global_value=2.19e-2, units="L * min^(-1) * mg^(-1)", note="decay constant for nicotine as function of mass(Cl)") # Add terms (named subexpressions) nicotine_ri.add_other_term("RXCL", expression="kd*HOCL + K1*Nx*HOCL + K3*NX2*HOCL") nicotine_ri.add_other_term("RXN", expression="K2*Nx*HOCL") nicotine_ri.add_other_term("RXNX2", expression="K2*Nx*HOCL - K4*NX2*HOCL") - # Add pipe reactions, one per species nicotine_ri.add_pipe_reaction("Nx", "RATE", expression="-RXN") nicotine_ri.add_pipe_reaction("HOCL", "RATE", expression="-RXCL") nicotine_ri.add_pipe_reaction("NX2", "RATE", expression="RXNX2") - # Tank reactions actually aren't necessary since there aren't any wall species nicotine_ri.add_tank_reaction("Nx", "RATE", expression="-RXN") nicotine_ri.add_tank_reaction("HOCL", "RATE", expression="-RXCL") nicotine_ri.add_tank_reaction("NX2", "RATE", expression="RXNX2") - +# ===================== Lead plumbosolvency model +# lead_ppm = WaterQualityReactionsModel( title="Lead Plumbosolvency Model (from Burkhardt et al 2020)", desc="Parameters for EPA HPS Simulator Model", - citations=Citation( + citations=[Citation( title="Framework for Modeling Lead in Premise Plumbing Systems Using EPANET", year=2020, author=[ @@ -82,7 +101,7 @@ "Darren Lytle", "Regan Murray", ], - citationtype="article", + citation_class="article", journaltitle="J Water Resour Plan Manag", volume=146, number=12, @@ -93,10 +112,9 @@ "PMCID:PMC7898126", "NIHMSID:NIHMS1664627", ], - ), + )], allow_sympy_reserved_names=True, options={ - "time": {"timestep": 1}, "report": { "species": {"PB2": "YES"}, "species_precision": {"PB2": 5}, @@ -104,6 +122,7 @@ "links": "all", }, "quality": { + "timestep": 1, "area_units": "M2", "rate_units": "SEC", "rtol": 1e-08, @@ -111,15 +130,20 @@ }, }, ) -lead_ppm.options.quality.area_units = "M2" -lead_ppm.options.quality.rate_units = "SEC" -lead_ppm.options.quality.rtol = 1.0e-8 -lead_ppm.options.quality.atol = 1.0e-8 -lead_ppm.options.time.timestep = 1 +"""A lead plumbosolvency model [BEMS20]_. + +.. [BEMS20] + J. B. Burkhardt, et al. (2020) + "Framework for Modeling Lead in Premise Plumbing Systems Using EPANET". + `Journal of water resources planning and management`. + **146** (12). + https://doi.org/10.1061/(asce)wr.1943-5452.0001304 +""" +# add the species, coefficients and reactions lead_ppm.add_bulk_species("PB2", "ug", note="dissolved lead (Pb)") -lead_ppm.add_constant_coeff("M", global_value=0.117, note="Desorption rate (ug/m^2/s)", unit="ug * m^(-1) * s^(-1)") -lead_ppm.add_constant_coeff("E", global_value=140.0, note="saturation/plumbosolvency level (ug/L)", unit="ug/L") +lead_ppm.add_constant_coeff("M", global_value=0.117, note="Desorption rate (ug/m^2/s)", units="ug * m^(-1) * s^(-1)") +lead_ppm.add_constant_coeff("E", global_value=140.0, note="saturation/plumbosolvency level (ug/L)", units="ug/L") lead_ppm.add_parameterized_coeff("F", global_value=0, note="determines which pipes have reactions") lead_ppm.add_pipe_reaction("PB2", "RATE", expression="F*Av*M*(E - PB2)/E") lead_ppm.add_tank_reaction("PB2", "RATE", expression="0") diff --git a/wntr/reaction/model.py b/wntr/reaction/model.py index 48581f534..ecee8cebc 100644 --- a/wntr/reaction/model.py +++ b/wntr/reaction/model.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- """ -Water quality reactions base classes +Water quality reactions model. """ @@ -9,54 +9,109 @@ from collections.abc import MutableMapping from dataclasses import InitVar, asdict, dataclass, field from enum import Enum, IntFlag -from typing import Any, ClassVar, Dict, Generator, Hashable, Iterator, List, Literal, Set, Tuple, Union - -import sympy -from sympy import Float, Symbol, init_printing, symbols -from sympy.parsing import parse_expr -from sympy.parsing.sympy_parser import convert_xor, standard_transformations +from typing import ( + Any, + ClassVar, + Dict, + Generator, + Hashable, + Iterator, + List, + Literal, + Set, + Tuple, + Union, +) +from wntr.network.elements import Source + +has_sympy = False +try: + from sympy import Float, Symbol, init_printing, symbols + from sympy.parsing import parse_expr + from sympy.parsing.sympy_parser import convert_xor, standard_transformations + + has_sympy = True +except ImportError: + sympy = None + logging.critical("This python installation does not have SymPy installed. Certain functionality will be disabled.") + standard_transformations = (None,) + convert_xor = None + has_sympy = False from wntr.network.model import WaterNetworkModel -from wntr.reaction.dynamics import EquilibriumDynamics, FormulaDynamics, RateDynamics +from ..utils.citations import Citation from .base import ( HYDRAULIC_VARIABLES, - RESERVED_NAMES, SYMPY_RESERVED, DisjointMapping, - DisjointMappingGroup, - ReactionDynamics, - ReactionRegistry, - ReactionVariable, - RxnExprType, - RxnLocType, - RxnVarType, + LinkedVariablesMixin, + RxnDynamicsType, + RxnLocationType, + RxnModelRegistry, + RxnReaction, + RxnVariable, + RxnVariableType, VariableNameExistsError, - VariableRegistry, ) +from .dynamics import EquilibriumDynamics, FormulaDynamics, RateDynamics from .options import RxnOptions -from .variables import BulkSpecies, Coefficient, Constant, InternalVariable, OtherTerm, Parameter, Species, WallSpecies +from .variables import ( + BulkSpecies, + Coefficient, + Constant, + InternalVariable, + Parameter, + Species, + OtherTerm, + WallSpecies, +) + +logger = logging.getLogger(__name__) @dataclass -class WaterQualityReactionsModel(ReactionRegistry, VariableRegistry): +class WaterQualityReactionsModel(RxnModelRegistry): """Water quality reactions model object. Parameters ---------- - title : str + title : str, optional The title of reaction model - desc : str + desc : str, optional A long description of the model - citations : + filename : str, optional + The original filename + citations : list of Citation or str, optional + It is appropriate to cite sources for water quality models + allow_sympy_reserved_names : bool, optional + Should the extra names from sympy be excluded, by default False + options : RxnOptions, optional + Reaction MSX options, by default a new object + _wn : WaterNetworkModel + The water network model to use, by default None """ - filename: str = None + title: str = None + """A one-line title for the model""" + desc: str = None - citations: Union[List[str], str] = "you ought to provide citations for this model" + """A multi-line string describing the model""" + + filename: str = None + """The original filename""" + + citations: List[Union[Citation, str]] = "you ought to provide citations for your model" + """A list of citations for the sources of this model's dynamics""" + allow_sympy_reserved_names: InitVar[bool] = False + """Allow sympy reserved names (I, E, pi)""" + options: InitVar[RxnOptions] = None + """A link to the options object""" + _wn: WaterNetworkModel = None + """A link to a water network model""" def __post_init__(self, allow_sympy_reserved_names=False, options=None): if self._wn is not None and not isinstance(self._wn, WaterNetworkModel): @@ -68,179 +123,497 @@ def __post_init__(self, allow_sympy_reserved_names=False, options=None): self._options = options if isinstance(self.citations, str): self.citations = [self.citations] + elif isinstance(self.citations, Citation): + self.citations = [self.citations] + self._variables: DisjointMapping = DisjointMapping() - self._species = self._variables.add_disjoint_group('species') - self._coeff = self._variables.add_disjoint_group('coeff') - self._terms = self._variables.add_disjoint_group('terms') + self._species = self._variables.add_disjoint_group("species") + self._coeffs = self._variables.add_disjoint_group("coeffs") + self._terms = self._variables.add_disjoint_group("funcs") self._dynamics: DisjointMapping = DisjointMapping() - self._pipe_dynamics = self._dynamics.add_disjoint_group('pipe') - self._tank_dynamics = self._dynamics.add_disjoint_group('tank') + self._pipe_dynamics = self._dynamics.add_disjoint_group("pipe") + self._tank_dynamics = self._dynamics.add_disjoint_group("tank") - self._usage: Dict[str, Set[str]] = dict() + self._usage: Dict[str, Set[str]] = dict() # FIXME: currently no usage tracking - self._sources: Dict[str, float] = dict() - self._inital_quality = list() - self._wn: WaterNetworkModel = None + self._sources: Dict[str, Dict[str, Dict[str, Source]]] = dict() + self._inital_quality: Dict[str, Dict[str, Dict[str, Source]]] = dict() self._patterns: Dict[str, Any] = dict() self._report = list() for v in HYDRAULIC_VARIABLES: - self._variables[v['name']] = InternalVariable(v['name'], note=v['note']) + self._variables[v["name"]] = InternalVariable(v["name"], note=v["note"]) if not allow_sympy_reserved_names: for name in SYMPY_RESERVED: self._variables[name] = InternalVariable(name, note="sympy reserved name") - def _is_variable_registered(self, var_or_name: Union[str, ReactionVariable]) -> bool: + def _is_variable_registered(self, var_or_name: Union[str, RxnVariable]) -> bool: name = str(var_or_name) - if name in self._variables: + if name in self._variables.keys(): return True return False + def has_variable(self, name: str) -> bool: + """Check to see if there is a variable by this name. + + Parameters + ---------- + name : str + a variable name to check + + Returns + ------- + bool + ``True`` if there is a variable by this name, ``False`` otherwise + """ + return name in self._variables.keys() + @property def variable_name_list(self) -> List[str]: + """A list of all defined variable names""" return list(self._variables.keys()) @property def species_name_list(self) -> List[str]: + """A list of all defined species names""" return list(self._species.keys()) @property def coefficient_name_list(self) -> List[str]: - return list(self._coeff.keys()) + """A list of all defined coefficient names""" + return list(self._coeffs.keys()) @property - def other_term_name_list(self) -> List[str]: + def function_name_list(self) -> List[str]: + """A list of all defined function (MSX 'terms') names""" return list(self._terms.keys()) - def variables(self, var_type=None): - var_type = RxnVarType.make(var_type) - for k, v in self._variables.items(): + def variables(self, var_type: RxnVariableType = None): + """A generator to loop over the variables. + + Parameters + ---------- + var_type : RxnVariableType, optional + limit results to a specific type, by default None + + Yields + ------ + RxnVariable + a variable defined within the model + """ + var_type = RxnVariableType.factory(var_type) + for v in self._variables.values(): if var_type is not None and v.var_type != var_type: continue - yield k, v + yield v + + def add_variable(self, var_or_type: Union[RxnVariable, RxnVariableType], name: str = None, **kwargs): + """Add an new variable to the model, or add an existing, unlinked variable object to the model. + + Parameters + ---------- + var_or_type : RxnVariable or RxnVariableType + the variable object to add to the model, or the type if creating a new variable object + name : str or None + the name of a new variable, must be None if adding an existing object, by default None + kwargs + any keyword arguments to pass to a new object constructor + + Raises + ------ + TypeError + if var_or_type is not a valid object, or if trying to create a new internal/hydraulic variable + ValueError + if var_or_type is an object, but name is supplied, or if var_or_type is a type, but no name is supplied + VariableNameExistsError + if the variable or name uses the same name an existing variable already uses + """ + if not isinstance(var_or_type, (RxnVariable,)): + try: + var_or_type = RxnVariableType.factory(var_or_type) + except Exception as e: + raise TypeError("Cannot add an object that is not a RxnVariable subclass or create a new object without a valid var_type") from e + if name is None: + raise ValueError("When adding a new variable, a name must be supplied") + typ = var_or_type + if typ is RxnVariableType.BULK or typ is RxnVariableType.WALL: + self.add_species(var_or_type, name, **kwargs) + elif typ is RxnVariableType.CONST or typ is RxnVariableType.PARAM: + self.add_coefficient(var_or_type, name, **kwargs) + elif typ is RxnVariableType.TERM: + self.add_other_term(var_or_type, name, **kwargs) + else: + raise TypeError("Cannot create new objects of the INTERNAL type using this function") + else: + if name is None or len(kwargs) > 0: + raise ValueError("When adding an existing variable object, no other arguments may be supplied") + __variable = var_or_type + if self._is_variable_registered(__variable): + raise VariableNameExistsError("A variable with this name already exists in the model") + typ = __variable.var_type + name = __variable.name + if isinstance(__variable, LinkedVariablesMixin): + __variable._variable_registry = self + if typ is RxnVariableType.BULK or typ is RxnVariableType.WALL: + self._variables.add_item_to_group("species", name, __variable) + self._inital_quality[name] = dict(global_value=None, nodes=dict(), links=dict()) + self._sources[name] = dict() + elif typ is RxnVariableType.CONST or typ is RxnVariableType.PARAM: + self._variables.add_item_to_group("coeffs", name, __variable) + elif typ is RxnVariableType.TERM: + self._variables.add_item_to_group("funcs", name, __variable) + else: + self._variables.add_item_to_group(None, name, __variable) def add_species( - self, species_type: Union[str, Literal[RxnVarType.BULK], Literal[RxnVarType.WALL]], name: str, unit: str, atol: float = None, rtol: float = None, note: str = None + self, + species_type: Union[str, Literal[RxnVariableType.BULK], Literal[RxnVariableType.WALL]], + name: str, + units: str, + atol: float = None, + rtol: float = None, + note: str = None, ) -> Species: - species_type = RxnVarType.make(species_type) - if species_type not in [RxnVarType.BULK, RxnVarType.WALL]: + """Add a new species to the model. + The atol and rtol parameters must either both be omitted or both be provided. + + Parameters + ---------- + species_type : BULK or WALL + the type of species + name : str + the name/symbol of the species + units : str + the unit of concentration used + atol : float, optional + the absolute tolerance for the solver for this species, by default None (global value) + rtol : float, optional + the relative tolerance fot the solver for this species, by default None (global value) + note : str, optional + a note or comment about this species, by default None + + Returns + ------- + Species + the new species object + + Raises + ------ + ValueError + if species_type is invalid + VariableNameExistsError + if a variable with this name already exists in the model + TypeError + if atol and rtol are not both None or both a float + """ + species_type = RxnVariableType.factory(species_type) + if species_type not in [RxnVariableType.BULK, RxnVariableType.WALL]: raise ValueError("Species must be BULK or WALL, got {:s}".format(species_type)) if self._is_variable_registered(name): raise VariableNameExistsError("The variable {} already exists in this model".format(name)) if (atol is None) ^ (rtol is None): raise TypeError("atol and rtol must be the same type, got {} and {}".format(atol, rtol)) - if species_type is RxnVarType.BULK: - var = BulkSpecies(name, unit, atol, rtol, note, self) - elif species_type is RxnVarType.WALL: - var = WallSpecies(name, unit, atol, rtol, note, self) + if species_type is RxnVariableType.BULK: + var = BulkSpecies(name, units, atol, rtol, note, self) + elif species_type is RxnVariableType.WALL: + var = WallSpecies(name, units, atol, rtol, note, self) self._species[name] = var + self._inital_quality[name] = dict([('global', None), ('nodes', dict()), ('links', dict())]) + self._sources[name] = dict() return var - def add_bulk_species(self, name: str, unit: str, atol: float = None, rtol: float = None, note: str = None) -> BulkSpecies: - return self.add_species(RxnVarType.BULK, name, unit, atol, rtol, note) - - def add_wall_species(self, name: str, unit: str, atol: float = None, rtol: float = None, note: str = None) -> WallSpecies: - return self.add_species(RxnVarType.WALL, name, unit, atol, rtol, note) + def add_bulk_species(self, name: str, units: str, atol: float = None, rtol: float = None, note: str = None) -> BulkSpecies: + """Add a new bulk species to the model. + The atol and rtol parameters must either both be omitted or both be provided. + + Parameters + ---------- + name : str + the name/symbol of the species + units : str + the unit of concentration used + atol : float, optional + the absolute tolerance for the solver for this species, by default None (global value) + rtol : float, optional + the relative tolerance fot the solver for this species, by default None (global value) + note : str, optional + a note or comment about this species, by default None + + Returns + ------- + Species + the new species object + + Raises + ------ + VariableNameExistsError + if a variable with this name already exists in the model + TypeError + if atol and rtol are not both None or both a float + """ + return self.add_species(RxnVariableType.BULK, name, units, atol, rtol, note) + + def add_wall_species(self, name: str, units: str, atol: float = None, rtol: float = None, note: str = None) -> WallSpecies: + """Add a new wall species to the model. + The atol and rtol parameters must either both be omitted or both be provided. + + Parameters + ---------- + name : str + the name/symbol of the species + units : str + the unit of concentration used + atol : float, optional + the absolute tolerance for the solver for this species, by default None (global value) + rtol : float, optional + the relative tolerance fot the solver for this species, by default None (global value) + note : str, optional + a note or comment about this species, by default None + + Returns + ------- + Species + the new species object + + Raises + ------ + VariableNameExistsError + if a variable with this name already exists in the model + TypeError + if atol and rtol are not both None or both a float + """ + return self.add_species(RxnVariableType.WALL, name, units, atol, rtol, note) def add_coefficient( - self, coeff_type: Union[str, Literal[RxnVarType.CONST], Literal[RxnVarType.PARAM]], name: str, global_value: float, note: str = None, unit: str = None, **kwargs + self, coeff_type: Union[str, Literal[RxnVariableType.CONST], Literal[RxnVariableType.PARAM]], name: str, global_value: float, note: str = None, units: str = None, **kwargs ) -> Coefficient: - coeff_type = RxnVarType.make(coeff_type) - if coeff_type not in [RxnVarType.CONST, RxnVarType.PARAM]: - raise ValueError("Species must be CONST or PARAM, got {:s}".format(coeff_type)) + """Add a new coefficient to the model. + + Parameters + ---------- + coeff_type : CONST or PARAM + the type of coefficient to add + name : str + the name/symbol of the coefficient + global_value : float + the global value for the coefficient + note : str, optional + a note or comment about this coefficient, by default None + units : str, optional + a unit for this coefficient, by default None + kwargs : other keyword arguments + certain coefficient classes have additional arguments. If specified, + these will be passed to the constructor for the relevant class. + + Returns + ------- + Coefficient + the new coefficient object + + Raises + ------ + ValueError + if the coeff_type is invalid + VariableNameExistsError + if a variable with this name already exists in the model + """ + coeff_type = RxnVariableType.factory(coeff_type) + if coeff_type not in [RxnVariableType.CONST, RxnVariableType.PARAM]: + raise ValueError("coeff_type must be CONST or PARAM, got {:s}".format(coeff_type)) if self._is_variable_registered(name): raise VariableNameExistsError("The variable {} already exists in this model".format(name)) - if coeff_type is RxnVarType.CONST: - var = Constant(name=name, global_value=global_value, note=note, unit=unit, variable_registry=self) - elif coeff_type is RxnVarType.PARAM: - var = Parameter(name=name, global_value=global_value, note=note, unit=unit, variable_registry=self, **kwargs) - self._coeff[name] = var + if coeff_type is RxnVariableType.CONST: + var = Constant(name=name, global_value=global_value, note=note, units=units, variable_registry=self) + elif coeff_type is RxnVariableType.PARAM: + var = Parameter(name=name, global_value=global_value, note=note, units=units, variable_registry=self, **kwargs) + self._coeffs[name] = var return var - def add_constant_coeff(self, name: str, global_value: float, note: str = None, unit: str = None) -> Constant: - return self.add_coefficient(RxnVarType.CONST, name=name, global_value=global_value, note=note, unit=unit) + def add_constant_coeff(self, name: str, global_value: float, note: str = None, units: str = None) -> Constant: + """Add a new constant coefficient to the model. + + Parameters + ---------- + coeff_type : CONST or PARAM + the type of coefficient to add + name : str + the name/symbol of the coefficient + global_value : float + the global value for the coefficient + note : str, optional + a note or comment about this coefficient, by default None + units : str, optional + units for this coefficient, by default None + + Returns + ------- + Coefficient + the new coefficient object + + Raises + ------ + ValueError + if the coeff_type is invalid + VariableNameExistsError + if a variable with this name already exists in the model + """ + return self.add_coefficient(RxnVariableType.CONST, name=name, global_value=global_value, note=note, units=units) def add_parameterized_coeff( - self, name: str, global_value: float, note: str = None, unit: str = None, pipe_values: Dict[str, float] = None, tank_values: Dict[str, float] = None + self, name: str, global_value: float, note: str = None, units: str = None, pipe_values: Dict[str, float] = None, tank_values: Dict[str, float] = None ) -> Parameter: - return self.add_coefficient(RxnVarType.PARAM, name=name, global_value=global_value, note=note, unit=unit, _pipe_values=pipe_values, _tank_values=tank_values) + """Add a new parameterized coefficient (based on pipe/tank name) to the model. + + Parameters + ---------- + coeff_type : CONST or PARAM + the type of coefficient to add + name : str + the name/symbol of the coefficient + global_value : float + the global value for the coefficient + note : str, optional + a note or comment about this coefficient, by default None + units: str, optional + a unit for this coefficient, by default None + pipe_values : dict, optional + values for this coefficient in specifically named pipes + tank_values : dict, optional + values for this coefficient in specifically named tanks + + Returns + ------- + Coefficient + the new coefficient object + + Raises + ------ + ValueError + if the coeff_type is invalid + VariableNameExistsError + if a variable with this name already exists in the model + """ + return self.add_coefficient(RxnVariableType.PARAM, name=name, global_value=global_value, note=note, units=units, _pipe_values=pipe_values, _tank_values=tank_values) def add_other_term(self, name: str, expression: str, note: str = None) -> OtherTerm: + """Add a new user-defined function to the model. + In EPANET-MSX, these variables are called 'TERMS', and serve as shortcut aliases + to simplify reaction expressions that would otherwise become very hard to read/write + on a single line (a requirement in EPANET-MSX input files). Because 'term' is + ambiguous, this will be referred to as a 'other term' or 'simplifying term'. + + Parameters + ---------- + name : str + the name/symbol for this function (an MSX 'term') + expression : str + the symbolic expression for this function + note : str, optional + a note or comment about this function, by default None + + Returns + ------- + UserFunction + the new function or simplyifying term object + + Raises + ------ + VariableNameExistsError + if a variable with this name already exists in the model + """ if self._is_variable_registered(name): raise VariableNameExistsError("The variable {} already exists in this model".format(name)) var = OtherTerm(name=name, expression=expression, note=note, variable_registry=self) self._terms[name] = var return var - def del_variable(self, name: str): + def remove_variable(self, name: str): + if name in self._inital_quality.keys(): + self._inital_quality.__delitem__(name) + if name in self._sources.keys(): + self._sources.__delitem__(name) return self._variables.__delitem__(name) - def get_variable(self, name: str) -> ReactionVariable: + def get_variable(self, name: str) -> RxnVariable: return self._variables[name] - def reactions(self, location=None): - location = RxnLocType.make(location) - for k, v in self._dynamics.items(): + def reactions(self, location: RxnLocationType = None): + """A generator for iterating through reactions in the model. + + Parameters + ---------- + location : RxnLocationType, optional + limit results to reactions within location, by default None + + Yields + ------ + RxnReaction + a reaction defined within the model + """ + location = RxnLocationType.factory(location) + for v in self._dynamics.values(): if location is not None and v.location != location: continue - yield k, v + yield v - def add_reaction(self, location: RxnLocType, species: Union[str, Species], dynamics: Union[str, int, RxnExprType], expression: str, note: str = None): - location = RxnLocType.make(location) + def add_reaction(self, location: RxnLocationType, species: Union[str, Species], dynamics: Union[str, int, RxnDynamicsType], expression: str, note: str = None): + location = RxnLocationType.factory(location) species = str(species) - _key = ReactionDynamics.to_key(species, location) + if species not in self._species.keys(): + raise ValueError("The species {} does not exist in the model, failed to add reaction.".format(species)) + _key = RxnReaction.to_key(species, location) if _key in self._dynamics.keys(): raise RuntimeError("The species {} already has a {} reaction defined. Use set_reaction instead.") - dynamics = RxnExprType.make(dynamics) + dynamics = RxnDynamicsType.factory(dynamics) new = None - if dynamics is RxnExprType.EQUIL: + if dynamics is RxnDynamicsType.EQUIL: new = EquilibriumDynamics(species=species, location=location, expression=expression, note=note, variable_registry=self) - elif dynamics is RxnExprType.RATE: + elif dynamics is RxnDynamicsType.RATE: new = RateDynamics(species=species, location=location, expression=expression, note=note, variable_registry=self) - elif dynamics is RxnExprType.FORMULA: + elif dynamics is RxnDynamicsType.FORMULA: new = FormulaDynamics(species=species, location=location, expression=expression, note=note, variable_registry=self) else: raise ValueError("Invalid dynamics type, {}".format(dynamics)) - if location is RxnLocType.PIPE: + if location is RxnLocationType.PIPE: self._pipe_dynamics[str(new)] = new - elif location is RxnLocType.TANK: + elif location is RxnLocationType.TANK: self._tank_dynamics[str(new)] = new else: raise ValueError("Invalid location type, {}".format(location)) return new - def add_pipe_reaction(self, species: Union[str, Species], dynamics: Union[str, int, RxnExprType], expression: str, note: str = None) -> ReactionDynamics: - return self.add_reaction(RxnLocType.PIPE, species=species, dynamics=dynamics, expression=expression, note=note) + def add_pipe_reaction(self, species: Union[str, Species], dynamics: Union[str, int, RxnDynamicsType], expression: str, note: str = None) -> RxnReaction: + return self.add_reaction(RxnLocationType.PIPE, species=species, dynamics=dynamics, expression=expression, note=note) - def add_tank_reaction(self, species: Union[str, Species], dynamics: Union[str, int, RxnExprType], expression: str, note: str = None) -> ReactionDynamics: - return self.add_reaction(RxnLocType.TANK, species=species, dynamics=dynamics, expression=expression, note=note) + def add_tank_reaction(self, species: Union[str, Species], dynamics: Union[str, int, RxnDynamicsType], expression: str, note: str = None) -> RxnReaction: + return self.add_reaction(RxnLocationType.TANK, species=species, dynamics=dynamics, expression=expression, note=note) - def del_reaction(self, species: Union[str, Species], location: Union[str, int, RxnLocType, Literal["all"]]): + def remove_reaction(self, species: Union[str, Species], location: Union[str, int, RxnLocationType, Literal["all"]]): if location != "all": - location = RxnLocType.make(location) + location = RxnLocationType.factory(location) species = str(species) if location is None: raise TypeError('location cannot be None when removing a reaction. Use "all" for all locations.') elif location == "all": - name = ReactionDynamics.to_key(species, RxnLocType.PIPE) + name = RxnReaction.to_key(species, RxnLocationType.PIPE) try: self._pipe_dynamics.__delitem__(name) except KeyError: pass - name = ReactionDynamics.to_key(species, RxnLocType.TANK) + name = RxnReaction.to_key(species, RxnLocationType.TANK) try: self._tank_dynamics.__delitem__(name) except KeyError: pass - elif location is RxnLocType.PIPE: - name = ReactionDynamics.to_key(species, RxnLocType.PIPE) + elif location is RxnLocationType.PIPE: + name = RxnReaction.to_key(species, RxnLocationType.PIPE) try: self._pipe_dynamics.__delitem__(name) except KeyError: pass - elif location is RxnLocType.TANK: - name = ReactionDynamics.to_key(species, RxnLocType.TANK) + elif location is RxnLocationType.TANK: + name = RxnReaction.to_key(species, RxnLocationType.TANK) try: self._tank_dynamics.__delitem__(name) except KeyError: @@ -250,14 +623,14 @@ def del_reaction(self, species: Union[str, Species], location: Union[str, int, R def get_reaction(self, species, location): species = str(species) - location = RxnLocType.make(location) - if location == RxnLocType.PIPE: + location = RxnLocationType.factory(location) + if location == RxnLocationType.PIPE: return self._pipe_dynamics.get(species, None) - elif location == RxnLocType.TANK: + elif location == RxnLocationType.TANK: return self._tank_dynamics.get(species, None) def init_printing(self, *args, **kwargs): - """Call sympy.init_printing(*args, **kwargs)""" + """Call sympy.init_printing""" init_printing(*args, **kwargs) @property @@ -275,4 +648,29 @@ def link_water_network_model(self, wn: WaterNetworkModel): self._wn = wn def add_pattern(self, name, pat): - self._patterns[name] = pat \ No newline at end of file + self._patterns[name] = pat + + def to_dict(self) -> dict: + rep = dict() + rep["version"] = 'wntr.reactions-0.0.1' + rep["title"] = self.title + rep["desc"] = self.desc + rep["original_filename"] = self.filename + rep["citations"] = [(c.to_dict() if isinstance(c, Citation) else c) for c in self.citations] + rep["options"] = self._options.to_dict() + rep["variables"] = dict() + rep["variables"]["species"] = [v.to_dict() for v in self._species.values()] + rep["variables"]["coefficients"] = [v.to_dict() for v in self._coeffs.values()] + rep["variables"]["other_terms"] = [v.to_dict() for v in self._terms.values()] + rep["reactions"] = dict() + rep["reactions"]["pipes"] = [v.to_dict() for v in self._pipe_dynamics.values()] + rep["reactions"]["tanks"] = [v.to_dict() for v in self._tank_dynamics.values()] + rep["patterns"] = self._patterns.copy() + rep["initial_quality"] = self._inital_quality.copy() + rep["sources"] = dict() + for sp, v in self._sources: + if v is not None and len(v) > 0: + rep["sources"][sp] = dict() + for node, source in v: + rep["sources"][sp][node] = source.to_dict() + return rep diff --git a/wntr/reaction/options.py b/wntr/reaction/options.py index 2c2e226ee..69eb722a4 100644 --- a/wntr/reaction/options.py +++ b/wntr/reaction/options.py @@ -1,44 +1,13 @@ import re import logging import copy +from typing import Dict, List, Literal, Union from wntr.network.options import _float_or_None, _int_or_None, _OptionsBase logger = logging.getLogger(__name__) -class TimeOptions(_OptionsBase): - """ - Options related to reaction simulation. - - Parameters - ---------- - timestep : int >= 1 - Water quality timestep (seconds), by default 60 (one minute). - - """ - - _pattern1 = re.compile(r"^(\d+):(\d+):(\d+)$") - _pattern2 = re.compile(r"^(\d+):(\d+)$") - _pattern3 = re.compile(r"^(\d+)$") - - def __init__( - self, - timestep: int = 60, - ): - self.timestep = timestep - - def __setattr__(self, name, value): - if name in {"timestep"}: - try: - value = max(1, int(value)) - except ValueError: - raise ValueError("%s must be an integer >= 1" % name) - elif name not in {"timestep"}: - raise AttributeError("%s is not a valid attribute in TimeOptions" % name) - self.__dict__[name] = value - - class QualityOptions(_OptionsBase): """ Options related to water quality modeling. These options come from @@ -46,11 +15,14 @@ class QualityOptions(_OptionsBase): Parameters ---------- + timestep : int >= 1 + Water quality timestep (seconds), by default 60 (one minute). + area_units : str, optional The units of area to use in surface concentration forms, by default ``M2``. Valid values are ``FT2``, ``M2``, or ``CM2``. rate_units : str, optional - The timee units to use in rate reactions, by default ``MIN``. Valid values are ``SEC``, ``MIN``, ``HR``, or ``DAY``. + The time units to use in all rate reactions, by default ``MIN``. Valid values are ``SEC``, ``MIN``, ``HR``, or ``DAY``. solver : str, optional The solver to use, by default ``RK5``. Options are ``RK5`` (5th order Runge-Kutta method), ``ROS2`` (2nd order Rosenbrock method), or ``EUL`` (Euler method). @@ -58,11 +30,11 @@ class QualityOptions(_OptionsBase): coupling : str, optional Use coupling method for solution, by default ``NONE``. Valid options are ``FULL`` or ``NONE``. - rtol : float, optional - Relative concentration tolerance, by default 1.0e-4. - atol : float, optional - Absolute concentration tolerance, by default 1.0e-4. + Absolute concentration tolerance, by default 0.01 (regardless of species concentration units). + + rtol : float, optional + Relative concentration tolerance, by default 0.001 (±0.1%). compiler : str, optional Whether to use a compiler, by default ``NONE``. Valid options are ``VC``, ``GC``, or ``NONE`` @@ -76,28 +48,46 @@ class QualityOptions(_OptionsBase): def __init__( self, + timestep: int = 360, area_units: str = "M2", rate_units: str = "MIN", solver: str = "RK5", coupling: str = "NONE", - rtol: float = 1.0e-4, atol: float = 1.0e-4, - compiler: str = "", + rtol: float = 1.0e-4, + compiler: str = "NONE", segments: int = 5000, peclet: int = 1000, + global_initial_quality: Dict[str, float] = None ): + self.timestep = timestep + """The timestep, in seconds, by default 360""" self.area_units = area_units + """The units used to express pipe wall surface area where, by default FT2. Valid values are FT2, M2, and CM2.""" self.rate_units = rate_units + """The units in which all reaction rate terms are expressed, by default HR. Valid values are HR, MIN, SEC, and DAY.""" self.solver = solver + """The solver to use, by default EUL. Valid values are EUL, RK5, and ROS2.""" self.coupling = coupling + """Whether coupling should occur during solving, by default NONE. Valid values are NONE and FULL.""" self.rtol = rtol + """The relative tolerance used during solvers ROS2 and RK5, by default 0.001 for all species. Can be overridden on a per-species basis.""" self.atol = atol + """The absolute tolerance used by the solvers, by default 0.01 for all species regardless of concentration units. Can be overridden on a per-species basis.""" self.compiler = compiler + """A compier to use if the equations should be compiled by EPANET-MSX, by default NONE. Valid options are VC, GC and NONE.""" self.segments = segments + """The number of segments per-pipe to use, by default 5000.""" self.peclet = peclet + """The threshold for applying dispersion, by default 1000.""" def __setattr__(self, name, value): - if name in ["atol", "rtol"]: + if name in {"timestep"}: + try: + value = max(1, int(value)) + except ValueError: + raise ValueError("%s must be an integer >= 1" % name) + elif name in ["atol", "rtol"]: try: value = float(value) except ValueError: @@ -125,14 +115,11 @@ class ReportOptions(_OptionsBase): Provides the filename to use for outputting an EPANET report file, by default this will be the prefix plus ".rpt". - status : str - Output solver status ("YES", "NO", "FULL"). "FULL" is only useful for debugging - - summary : str - Output summary information ("YES" or "NO") + species : dict[str, bool] + Output species concentrations - energy : str - Output energy information + species_precision : dict[str, float] + Output species concentrations with the specified precision nodes : None, "ALL", or list Output node information in report file. If a list of node names is provided, @@ -152,17 +139,23 @@ def __init__( self, pagesize: list = None, report_filename: str = None, - species: dict = None, - species_precision: dict = None, - nodes: bool = False, - links: bool = False, + species: Dict[str, bool] = None, + species_precision: Dict[str, float] = None, + nodes: Union[Literal['ALL'], List[str]] = None, + links: Union[Literal['ALL'], List[str]] = None, ): self.pagesize = pagesize + """The pagesize for the report""" self.report_filename = report_filename + """The prefix of the report filename (will add .rpt)""" self.species = species if species is not None else dict() + """Turn individual species outputs on and off, by default no species are output""" self.species_precision = species_precision if species_precision is not None else dict() + """Set the output precision for the concentration of a specific species""" self.nodes = nodes + """A list of nodes to print output for, or 'ALL' for all nodes, by default None""" self.links = links + """A list of links to print output for, or 'ALL' for all links, by default None""" def __setattr__(self, name, value): if name not in ["pagesize", "report_filename", "species", "nodes", "links", "species_precision"]: @@ -215,18 +208,13 @@ class RxnOptions(_OptionsBase): """ - def __init__(self, time: TimeOptions = None, report: ReportOptions = None, quality: QualityOptions = None, user: UserOptions = None): - self.time = TimeOptions.factory(time) + def __init__(self, report: ReportOptions = None, quality: QualityOptions = None, user: UserOptions = None): self.report = ReportOptions.factory(report) self.quality = QualityOptions.factory(quality) self.user = UserOptions.factory(user) def __setattr__(self, name, value): - if name == "time": - if not isinstance(value, (TimeOptions, dict, tuple, list)): - raise ValueError("time must be a TimeOptions or convertable object") - value = TimeOptions.factory(value) - elif name == "report": + if name == "report": if not isinstance(value, (ReportOptions, dict, tuple, list)): raise ValueError("report must be a ReportOptions or convertable object") value = ReportOptions.factory(value) diff --git a/wntr/reaction/toolkitmsx.py b/wntr/reaction/toolkitmsx.py index 3eba00e1b..6429066ff 100644 --- a/wntr/reaction/toolkitmsx.py +++ b/wntr/reaction/toolkitmsx.py @@ -16,10 +16,12 @@ import platform import sys from ctypes import byref -from ..epanet.toolkit import EpanetException, ENepanet -from ..epanet.util import SizeLimits + from pkg_resources import resource_filename +from ..epanet.toolkit import ENepanet, EpanetException +from ..epanet.util import SizeLimits + epanet_toolkit = "wntr.epanet.toolkit" if os.name in ["nt", "dos"]: @@ -472,7 +474,7 @@ def MSXgetcount(self, type): def MSXgetspecies(self, spe): """Retrieves the attributes of a chemical species given its internal index number. - species is the sequence number of the species (starting from 1 as listed in teh MSX input file_ + species is the sequence number of the species (starting from 1 as listed in the MSX input file type: MSX_BULK (defined as 0) and MSX_WALL (defined as 1) units: C_style character string array that is returned with the mass units that were defined for the species in question(hold max 15 characters) aTol returned with absolute concentration tolerance defined for the species diff --git a/wntr/reaction/variables.py b/wntr/reaction/variables.py index 1037d7d5b..b290cd056 100644 --- a/wntr/reaction/variables.py +++ b/wntr/reaction/variables.py @@ -1,31 +1,75 @@ +# -*- coding: utf-8 -*- + +""" +Classes for variables used in reaction dynamics definitions. +Defines species (chemical or biological), coefficients for equations, +"term-functions", i.e., named functions that are called "terms" in +EPANET-MSX, and internal variables, such as hydraulic variables. + +The classes in this module can be created directly. However, they are more +powerful when either, a) created using API calls on a :class:`~wntr.reaction.model.WaterNetworkModel`, +or, b) linked to a :class:`~wntr.reaction.model.WaterNetworkModel` model object after creation. +This allows for variables to be validated against other variables in the model, +avoiding naming conflicts and checking that terms used in a term-function have +been defined. + +If :class:`sympy` is installed, then there are functions available +that will convert object instances of these classes into sympy expressions +and symbols. If the instances are linked to a model, then expressions can +be expanded, validated, and even evaluated or simplified symbolically. +""" + import enum import logging +import warnings from dataclasses import InitVar, asdict, dataclass, field from enum import Enum, IntFlag from typing import Any, ClassVar, Dict, List, Set, Tuple, Union -import warnings -import sympy -from sympy import Float, Function, Symbol, init_printing, symbols -from sympy.parsing import parse_expr -from sympy.parsing.sympy_parser import convert_xor, standard_transformations +has_sympy = False +try: + from sympy import Float, Symbol, init_printing, symbols + from sympy.parsing import parse_expr + from sympy.parsing.sympy_parser import convert_xor, standard_transformations -from wntr.network.model import WaterNetworkModel + has_sympy = True +except ImportError: + sympy = None + logging.critical("This python installation does not have SymPy installed. Certain functionality will be disabled.") + standard_transformations = (None,) + convert_xor = None + has_sympy = False -from .base import ExpressionMixin, LinkedVariablesMixin, VariableRegistry, ReactionVariable, RxnVarType, RESERVED_NAMES +from wntr.network.model import WaterNetworkModel +from wntr.reaction.base import EXPR_TRANSFORMS + +from .base import ( + RESERVED_NAMES, + ExpressionMixin, + LinkedVariablesMixin, + MSXObject, + RxnModelRegistry, + RxnVariable, + RxnVariableType, +) logger = logging.getLogger(__name__) @dataclass(repr=False) -class Species(LinkedVariablesMixin, ReactionVariable): +class Species(MSXObject, LinkedVariablesMixin, RxnVariable): - unit: str + units: str + """The unit used for this species""" atol: InitVar[float] = None + """The absolute tolerance to use when solving for this species, by default None""" rtol: InitVar[float] = None + """The relative tolerance to use when solving for this species, by default None""" note: str = None + """A note about this species, by default None""" diffusivity: float = None - variable_registry: InitVar[VariableRegistry] = None + """The diffusivity value for this species, by default None""" + variable_registry: InitVar[RxnModelRegistry] = None def __post_init__(self, atol=None, rtol=None, reaction_model=None): if isinstance(atol, property): @@ -44,38 +88,58 @@ def __post_init__(self, atol=None, rtol=None, reaction_model=None): self._rtol = rtol self._variable_registry = reaction_model - @property - def atol(self) -> float: - return self._atol + def __repr__(self): + return "{}(name={}, unit={}, atol={}, rtol={}, note={})".format(self.__class__.__name__, repr(self.name), repr(self.units), self._atol, self._rtol, repr(self.note)) - @property - def rtol(self) -> float: - return self._rtol + def get_tolerances(self) -> Tuple[float, float]: + """Get the species-specific solver tolerances. - def get_tolerances(self) -> Union[Tuple[float, float], None]: + Returns + ------- + two-tuple or None + the absolute and relative tolerances, or None if the global values should be used + """ if self._atol is not None and self._rtol is not None: return (self._atol, self._rtol) return None - def set_tolerances(self, atol: float, rtol: float): - if atol is None and rtol is None: + def set_tolerances(self, absolute: float, relative: float): + """Set the species-specific solver tolerances. Using ``None`` for both will + clear the tolerances, though using :func:`clear_tolerances` is clearer code. + + Parameters + ---------- + absolute : float + the absolute solver tolerance + relative : float + the relative solver tolerance + + Raises + ------ + TypeError + if both absolute and relative are not the same type + ValueError + if either value is less-than-or-equal-to zero + """ + if absolute is None and relative is None: self._atol = self._rtol = None return try: - if not isinstance(atol, float): - atol = float(atol) - if not isinstance(rtol, float): - rtol = float(rtol) + if not isinstance(absolute, float): + absolute = float(absolute) + if not isinstance(relative, float): + relative = float(relative) except Exception as e: - raise TypeError("atol and rtol must be the same type, got {} and {}".format(atol, rtol)) - if atol <= 0: - raise ValueError("Absolute tolerance atol must be greater than 0") - if rtol <= 0: - raise ValueError("Relative tolerance rtol must be greater than 0") - self._atol = atol - self._rtol = rtol + raise TypeError("absolute and relative must be the same type, got {} and {}".format(absolute, relative)) + if absolute <= 0: + raise ValueError("Absolute tolerance must be greater than 0") + if relative <= 0: + raise ValueError("Relative tolerance must be greater than 0") + self._atol = absolute + self._rtol = relative def clear_tolerances(self): + """Resets both tolerances to ``None`` to use the global values.""" self._atol = self._rtol = None def to_msx_string(self) -> str: @@ -90,36 +154,45 @@ def to_msx_string(self) -> str: return "{:s} {:s} {:s} {:s} ;{:s}".format( self.var_type.name.upper(), self.name, - self.unit, + self.units, tolstr, self.note if self.note is not None else "", ) - def __repr__(self): - return "{}(name={}, unit={}, atol={}, rtol={}, note={})".format(self.__class__.__name__, repr(self.name), repr(self.unit), self.atol, self.rtol, repr(self.note)) + def to_dict(self): + rep = dict(name=self.name, unist=self.units) + tols = self.get_tolerances() + if tols is not None: + rep['atol'] = tols[0] + rep['rtol'] = tols[1] + if self.note: + rep['note'] = self.note + if self.diffusivity is not None: + rep['diffusivity'] = self.diffusivity + return rep @dataclass(repr=False) class BulkSpecies(Species): @property - def var_type(self) -> RxnVarType: - return RxnVarType.BULK + def var_type(self) -> RxnVariableType: + return RxnVariableType.BULK @dataclass(repr=False) class WallSpecies(Species): @property - def var_type(self) -> RxnVarType: - return RxnVarType.WALL + def var_type(self) -> RxnVariableType: + return RxnVariableType.WALL @dataclass(repr=False) -class Coefficient(LinkedVariablesMixin, ReactionVariable): +class Coefficient(MSXObject, LinkedVariablesMixin, RxnVariable): global_value: float note: str = None - unit: str = None - variable_registry: InitVar[VariableRegistry] = None + units: str = None + variable_registry: InitVar[RxnModelRegistry] = None def __post_init__(self, reaction_model): if self.name in RESERVED_NAMES: @@ -127,6 +200,9 @@ def __post_init__(self, reaction_model): self.global_value = float(self.global_value) self._variable_registry = reaction_model + def __repr__(self): + return "{}(name={}, global_value={}, units={}, note={})".format(self.__class__.__name__, repr(self.name), repr(self.global_value), repr(self.units), repr(self.note)) + def get_value(self) -> float: return self.global_value @@ -139,26 +215,40 @@ def to_msx_string(self) -> str: self.note if self.note is not None else "", ) - def __repr__(self): - return "{}(name={}, global_value={}, unit={}, note={})".format(self.__class__.__name__, repr(self.name), repr(self.global_value), repr(self.unit), repr(self.note)) + def to_dict(self): + rep = dict(name=self.name, global_value=self.global_value) + if self.note is not None: + rep['note'] = self.note + if self.units is not None: + rep['units'] = self.units + return rep @dataclass(repr=False) class Constant(Coefficient): @property - def var_type(self) -> RxnVarType: - return RxnVarType.CONST + def var_type(self) -> RxnVariableType: + return RxnVariableType.CONST @dataclass(repr=False) class Parameter(Coefficient): _pipe_values: Dict[str, float] = field(default_factory=dict) + """A dictionary of parameter values for various pipes""" _tank_values: Dict[str, float] = field(default_factory=dict) + """A dictionary of parameter values for various tanks""" + + def __post_init__(self, reaction_model): + super().__post_init__(reaction_model) + if self._pipe_values is None: + self._pipe_values = dict() + if self._tank_values is None: + self._tank_values = dict() @property - def var_type(self) -> RxnVarType: - return RxnVarType.PARAM + def var_type(self) -> RxnVariableType: + return RxnVariableType.PARAM def get_value(self, pipe: str = None, tank: str = None) -> float: if pipe is not None and tank is not None: @@ -176,45 +266,74 @@ def pipe_values(self) -> Dict[str, float]: @property def tank_values(self) -> Dict[str, float]: return self._tank_values + + def to_dict(self): + rep = super().to_dict() + rep['pipe_values'] = self._pipe_values.copy() + rep['tank_values'] = self._tank_values.copy() + return rep @dataclass(repr=False) -class OtherTerm(LinkedVariablesMixin, ExpressionMixin, ReactionVariable): - +class OtherTerm(MSXObject, LinkedVariablesMixin, ExpressionMixin, RxnVariable): + """A function definition used as a shortcut in reaction expressions (called a 'term' in EPANET-MSX) + + Parameters + ---------- + name : str + the name/symbol of the function (term) + expression : str + the mathematical expression described by this function + note : str, optional + a note for this function, by default None + variable_registry : RxnModelRegistry + the reaction model this function is a part of + """ + + expression: str + """The expression this named-function is equivalent to""" note: str = None - variable_registry: InitVar[VariableRegistry] = field(default=None, compare=False) + """A note about this function/term""" + variable_registry: InitVar[RxnModelRegistry] = field(default=None, compare=False) def __post_init__(self, reaction_model): if self.name in RESERVED_NAMES: raise ValueError("Name cannot be a reserved name") self._variable_registry = reaction_model - @property - def var_type(self) -> RxnVarType: - return RxnVarType.TERM + def __repr__(self): + return "{}(name={}, expression={}, note={})".format(self.__class__.__name__, repr(self.name), repr(self.expression), repr(self.note)) - def sympify(self): - raise NotImplementedError + @property + def var_type(self) -> RxnVariableType: + return RxnVariableType.TERM def to_msx_string(self) -> str: return "{:s} {:s} ;{:s}".format(self.name, self.expression, self.note if self.note is not None else "") - def __repr__(self): - return "{}(name={}, expression={}, note={})".format(self.__class__.__name__, repr(self.name), repr(self.expression), repr(self.note)) + def to_symbolic(self, transformations=...): + return super().to_symbolic(transformations) + def to_dict(self): + rep = dict(name=self.name, expression=self.expression) + if self.note is not None: + rep['note'] = self.note + return rep -@dataclass(repr=False) -class InternalVariable(ReactionVariable): - note: str = "internal variable - not output to MSX" - unit: str = None +@dataclass(repr=False) +class InternalVariable(RxnVariable): + """A hydraulic variable or a placeholder for a built-in reserved word. - @property - def var_type(self) -> RxnVarType: - return RxnVarType.INTERNAL + For example, "Len" is the EPANET-MSX name for the length of a pipe, and "I" is a sympy + reserved symbol for the imaginary number.""" - def to_msx_string(self) -> str: - raise TypeError("An InternalVariable is not part of an MSX input file") + note: str = "internal variable - not output to MSX" + units: str = None def __repr__(self): - return "{}(name={}, note={})".format(self.__class__.__name__, repr(self.name), repr(self.note)) + return "{}(name={}, note={}, units={})".format(self.__class__.__name__, repr(self.name), repr(self.note), repr(self.units)) + + @property + def var_type(self) -> RxnVariableType: + return RxnVariableType.INTERNAL diff --git a/wntr/tests/test_reactions.py b/wntr/tests/test_reactions.py index 75cc7fcc3..41d07b098 100644 --- a/wntr/tests/test_reactions.py +++ b/wntr/tests/test_reactions.py @@ -105,15 +105,15 @@ def test_BulkSpecies_creation(self): self.assertRaises(TypeError, wntr.reaction.model.BulkSpecies, "Cl", "mg", None, 0.01) species = wntr.reaction.model.BulkSpecies("Cl", "mg") self.assertEqual(species.name, "Cl") - self.assertEqual(species.unit, "mg") - self.assertEqual(species.var_type, wntr.reaction.model.RxnVarType.BULK) + self.assertEqual(species.units, "mg") + self.assertEqual(species.var_type, wntr.reaction.model.RxnVariableType.BULK) self.assertIsNone(species.atol) self.assertIsNone(species.rtol) self.assertIsNone(species.note) species = wntr.reaction.model.BulkSpecies("Cl", "mg", 0.01, 0.0001, note="Testing stuff") - self.assertEqual(species.var_type, wntr.reaction.model.RxnVarType.BULK) + self.assertEqual(species.var_type, wntr.reaction.model.RxnVariableType.BULK) self.assertEqual(species.name, "Cl") - self.assertEqual(species.unit, "mg") + self.assertEqual(species.units, "mg") self.assertEqual(species.atol, 0.01) self.assertEqual(species.rtol, 0.0001) self.assertEqual(species.note, "Testing stuff") @@ -126,15 +126,15 @@ def test_WallSpecies_creation(self): self.assertRaises(TypeError, wntr.reaction.model.WallSpecies, "Cl", "mg", None, 0.01) species = wntr.reaction.model.WallSpecies("Cl", "mg") self.assertEqual(species.name, "Cl") - self.assertEqual(species.unit, "mg") - self.assertEqual(species.var_type, wntr.reaction.model.RxnVarType.WALL) + self.assertEqual(species.units, "mg") + self.assertEqual(species.var_type, wntr.reaction.model.RxnVariableType.WALL) self.assertIsNone(species.atol) self.assertIsNone(species.rtol) self.assertIsNone(species.note) species = wntr.reaction.model.WallSpecies("Cl", "mg", 0.01, 0.0001, note="Testing stuff") - self.assertEqual(species.var_type, wntr.reaction.model.RxnVarType.WALL) + self.assertEqual(species.var_type, wntr.reaction.model.RxnVariableType.WALL) self.assertEqual(species.name, "Cl") - self.assertEqual(species.unit, "mg") + self.assertEqual(species.units, "mg") self.assertEqual(species.atol, 0.01) self.assertEqual(species.rtol, 0.0001) self.assertEqual(species.note, "Testing stuff") @@ -148,7 +148,7 @@ def test_Constant_creation(self): self.assertEqual(const1.name, "Kb") self.assertEqual(const1.global_value, 0.482) self.assertEqual(const1.get_value(), const1.global_value) - self.assertEqual(const1.var_type, wntr.reaction.model.RxnVarType.CONST) + self.assertEqual(const1.var_type, wntr.reaction.model.RxnVariableType.CONST) self.assertEqual(const1.note, "test") def test_Parameter_creation(self): @@ -158,7 +158,7 @@ def test_Parameter_creation(self): self.assertEqual(param1.name, "Kb") self.assertEqual(param1.global_value, 0.482) self.assertEqual(param1.get_value(), param1.global_value) - self.assertEqual(param1.var_type, wntr.reaction.model.RxnVarType.PARAM) + self.assertEqual(param1.var_type, wntr.reaction.model.RxnVariableType.PARAM) self.assertEqual(param1.note, "test") test_pipe_dict = {"PIPE": 0.38} test_tank_dict = {"TANK": 222.23} @@ -172,35 +172,35 @@ def test_RxnTerm_creation(self): term1 = wntr.reaction.model.OtherTerm("T0", "-3.2 * Kb * Cl^2", note="bar") self.assertEqual(term1.name, "T0") self.assertEqual(term1.expression, "-3.2 * Kb * Cl^2") - self.assertEqual(term1.var_type, wntr.reaction.model.RxnVarType.TERM) + self.assertEqual(term1.var_type, wntr.reaction.model.RxnVariableType.TERM) self.assertEqual(term1.note, "bar") def test_RxnExpression_strings(self): - equil1 = wntr.reaction.model.EquilibriumDynamics("Cl", wntr.reaction.model.RxnLocType.PIPE, "-Ka + Kb * Cl + T0") - rate1 = wntr.reaction.model.RateDynamics("Cl", wntr.reaction.model.RxnLocType.TANK, "-Ka + Kb * Cl + T0", note="Foo Bar") - formula1 = wntr.reaction.model.FormulaDynamics("Cl", wntr.reaction.model.RxnLocType.PIPE, "-Ka + Kb * Cl + T0") + equil1 = wntr.reaction.model.EquilibriumDynamics("Cl", wntr.reaction.model.RxnLocationType.PIPE, "-Ka + Kb * Cl + T0") + rate1 = wntr.reaction.model.RateDynamics("Cl", wntr.reaction.model.RxnLocationType.TANK, "-Ka + Kb * Cl + T0", note="Foo Bar") + formula1 = wntr.reaction.model.FormulaDynamics("Cl", wntr.reaction.model.RxnLocationType.PIPE, "-Ka + Kb * Cl + T0") self.assertEqual(equil1.to_msx_string(), "EQUIL Cl -Ka + Kb * Cl + T0 ;") self.assertEqual(rate1.to_msx_string(), "RATE Cl -Ka + Kb * Cl + T0 ;Foo Bar") self.assertEqual(formula1.to_msx_string(), "FORMULA Cl -Ka + Kb * Cl + T0 ;") def test_Equilibrium_creation(self): - equil1 = wntr.reaction.model.EquilibriumDynamics("Cl", wntr.reaction.model.RxnLocType.PIPE, "-Ka + Kb * Cl + T0") + equil1 = wntr.reaction.model.EquilibriumDynamics("Cl", wntr.reaction.model.RxnLocationType.PIPE, "-Ka + Kb * Cl + T0") self.assertEqual(equil1.species, "Cl") self.assertEqual(equil1.expression, "-Ka + Kb * Cl + T0") - self.assertEqual(equil1.expr_type, wntr.reaction.model.RxnExprType.EQUIL) + self.assertEqual(equil1.expr_type, wntr.reaction.model.RxnDynamicsType.EQUIL) def test_Rate_creation(self): - rate1 = wntr.reaction.model.RateDynamics("Cl", wntr.reaction.model.RxnLocType.TANK, "-Ka + Kb * Cl + T0", note="Foo Bar") + rate1 = wntr.reaction.model.RateDynamics("Cl", wntr.reaction.model.RxnLocationType.TANK, "-Ka + Kb * Cl + T0", note="Foo Bar") self.assertEqual(rate1.species, "Cl") self.assertEqual(rate1.expression, "-Ka + Kb * Cl + T0") - self.assertEqual(rate1.expr_type, wntr.reaction.model.RxnExprType.RATE) + self.assertEqual(rate1.expr_type, wntr.reaction.model.RxnDynamicsType.RATE) self.assertEqual(rate1.note, "Foo Bar") def test_Formula_creation(self): - formula1 = wntr.reaction.model.FormulaDynamics("Cl", wntr.reaction.model.RxnLocType.PIPE, "-Ka + Kb * Cl + T0") + formula1 = wntr.reaction.model.FormulaDynamics("Cl", wntr.reaction.model.RxnLocationType.PIPE, "-Ka + Kb * Cl + T0") self.assertEqual(formula1.species, "Cl") self.assertEqual(formula1.expression, "-Ka + Kb * Cl + T0") - self.assertEqual(formula1.expr_type, wntr.reaction.model.RxnExprType.FORMULA) + self.assertEqual(formula1.expr_type, wntr.reaction.model.RxnDynamicsType.FORMULA) def test_WaterQualityReactionsModel_creation_specific_everything(self): rxn_model1 = wntr.reaction.model.WaterQualityReactionsModel() @@ -209,9 +209,9 @@ def test_WaterQualityReactionsModel_creation_specific_everything(self): const1 = wntr.reaction.model.Constant("Kb", 0.482) param1 = wntr.reaction.model.Parameter("Ka", 0.482, note="foo") term1 = wntr.reaction.model.OtherTerm("T0", "-3.2 * Kb * Cl^2", note="bar") - equil1 = wntr.reaction.model.EquilibriumDynamics(bulk1, wntr.reaction.model.RxnLocType.PIPE, "-Ka + Kb * Cl + T0") - rate1 = wntr.reaction.model.RateDynamics(bulk1, wntr.reaction.model.RxnLocType.TANK, "-Ka + Kb * Cl + T0", note="Foo Bar") - formula1 = wntr.reaction.model.FormulaDynamics(wall1, wntr.reaction.model.RxnLocType.PIPE, "-Ka + Kb * Cl + T0") + equil1 = wntr.reaction.model.EquilibriumDynamics(bulk1, wntr.reaction.model.RxnLocationType.PIPE, "-Ka + Kb * Cl + T0") + rate1 = wntr.reaction.model.RateDynamics(bulk1, wntr.reaction.model.RxnLocationType.TANK, "-Ka + Kb * Cl + T0", note="Foo Bar") + formula1 = wntr.reaction.model.FormulaDynamics(wall1, wntr.reaction.model.RxnLocationType.PIPE, "-Ka + Kb * Cl + T0") bulk2 = rxn_model1.add_bulk_species("Cl", "mg") wall2 = rxn_model1.add_wall_species("ClOH", "mg", 0.01, 0.0001, note="Testing stuff") @@ -219,7 +219,7 @@ def test_WaterQualityReactionsModel_creation_specific_everything(self): param2 = rxn_model1.add_parameterized_coeff("Ka", 0.482, note="foo") term2 = rxn_model1.add_other_term("T0", "-3.2 * Kb * Cl^2", note="bar") equil2 = rxn_model1.add_pipe_reaction("Cl", "equil", "-Ka + Kb * Cl + T0") - rate2 = rxn_model1.add_tank_reaction("Cl", wntr.reaction.model.RxnExprType.R, "-Ka + Kb * Cl + T0", note="Foo Bar") + rate2 = rxn_model1.add_tank_reaction("Cl", wntr.reaction.model.RxnDynamicsType.R, "-Ka + Kb * Cl + T0", note="Foo Bar") formula2 = rxn_model1.add_reaction("PIPE", "ClOH", "formula", "-Ka + Kb * Cl + T0") self.assertEqual(bulk1, bulk2) self.assertEqual(wall1, wall2) @@ -239,14 +239,14 @@ def test_WaterQualityReactionsModel_creation_generic_species_coeffs(self): rxn_model2 = wntr.reaction.model.WaterQualityReactionsModel() - self.assertRaises(ValueError, rxn_model2.add_species, wntr.reaction.model.RxnVarType.CONST, "Cl", "mg") + self.assertRaises(ValueError, rxn_model2.add_species, wntr.reaction.model.RxnVariableType.CONST, "Cl", "mg") self.assertRaises(TypeError, rxn_model2.add_coefficient, None, "Kb", 0.482) self.assertRaises(ValueError, rxn_model2.add_coefficient, "Wall", "Kb", 0.482) bulk3 = rxn_model2.add_species("BULK", "Cl", "mg") - wall3 = rxn_model2.add_species(wntr.reaction.model.RxnVarType.WALL, "ClOH", "mg", 0.01, 0.0001, note="Testing stuff") + wall3 = rxn_model2.add_species(wntr.reaction.model.RxnVariableType.WALL, "ClOH", "mg", 0.01, 0.0001, note="Testing stuff") const3 = rxn_model2.add_coefficient("Consolation", "Kb", 0.482) - param3 = rxn_model2.add_coefficient(wntr.reaction.model.RxnVarType.P, "Ka", 0.482, note="foo") + param3 = rxn_model2.add_coefficient(wntr.reaction.model.RxnVariableType.P, "Ka", 0.482, note="foo") self.assertEqual(bulk3, bulk1) self.assertEqual(wall3, wall1) diff --git a/wntr/utils/citations.py b/wntr/utils/citations.py new file mode 100644 index 000000000..d5b970b19 --- /dev/null +++ b/wntr/utils/citations.py @@ -0,0 +1,116 @@ +# coding: utf-8 +"""Contains a dataclass that can be used to store citations. +Will output the class +""" +import datetime +from dataclasses import asdict, dataclass +from typing import Any, Dict + + +@dataclass(repr=False) +class Citation: + """A dataclass for citations, most attribute names match biblatex names. + The exceptions are :attr:`citation_class`, which is the "@..." type of an entry, + :attr:`fulldate`, which is the "date" element of a bibliography entry, + and :attr:`report_type`, which is the "type" element of a bib(la)tex entry. + + This class makes no attempt to format or represent the citation in any form + other than as a dictionary. + """ + + title: str + year: int + key: str = None + author: str = None + + # citation type/subtype (e.g., "report"/"tech. rep.") + citation_class: str = 'misc' + report_type: str = None + + # document identifiers + doi: str = None + url: str = None + isrn: str = None + isbn: str = None + issn: str = None + eprint: str = None + + # container titles + journaltitle: str = None + maintitle: str = None + booktitle: str = None + issuetitle: str = None + + # conference/proceedings info + eventtitle: str = None + eventdate: datetime.date = None + venue: str = None + + # publishing info + institution: str = None + organization: str = None + publisher: str = None + location: str = None + howpublished: str = None + language: str = None + origlanguage: str = None + + # additional people + editor: str = None + bookauthor: str = None + translator: str = None + annotator: str = None + commentator: str = None + introduction: str = None + foreword: str = None + afterword: str = None + + # identifying info + issue: str = None + series: str = None + volume: str = None + number: str = None + part: str = None + edition: str = None + version: str = None + chapter: str = None + pages: str = None + volumes: str = None + pagetotal: str = None + + # dates + month: str = None + fulldate: datetime.date = None + urldate: datetime.date = None + + # extra + note: str = None + addendum: str = None + abstract: str = None + annotation: str = None + + def to_dict(self) -> Dict[str, Any]: + """Return a dictionary representation of the citation. + All blank (None) values will be removed from the dictionary + so that it is minimal. + + Returns + ------- + Dict[str, Any] + minimal dictionary representation of the Citation + """ + d = asdict(self) + for k in list(d.keys()): + if d[k] is None: + del d[k] + return d + + def __repr__(self) -> str: + d = asdict(self) + for k in list(d.keys()): + if d[k] is None: + del d[k] + rep = self(self.__class__.__name__) + '(' + rep = rep + ', '.join(['{}={}'.format(k, repr(v)) for k, v in d.items()]) + rep = rep + ')' + return rep \ No newline at end of file From 25f18a94aee30208f0aba8922574686766c3125e Mon Sep 17 00:00:00 2001 From: dbhart Date: Thu, 31 Aug 2023 13:03:20 -0600 Subject: [PATCH 11/75] Completed MSX-input file IO --- wntr/reaction/base.py | 19 +- wntr/reaction/dynamics.py | 31 ++- wntr/reaction/io.py | 431 +++++++++++++++++++++++++++++-------- wntr/reaction/model.py | 20 +- wntr/reaction/variables.py | 53 +++-- wntr/utils/citations.py | 24 ++- 6 files changed, 441 insertions(+), 137 deletions(-) diff --git a/wntr/reaction/base.py b/wntr/reaction/base.py index c01012af6..bd4e4c407 100644 --- a/wntr/reaction/base.py +++ b/wntr/reaction/base.py @@ -11,7 +11,7 @@ import logging from abc import ABC, abstractmethod, abstractproperty from collections.abc import MutableMapping -from dataclasses import InitVar, dataclass +from dataclasses import InitVar, dataclass, field from enum import Enum, IntFlag from typing import ( Any, @@ -710,3 +710,20 @@ def to_msx_string(self) -> str: the expression for use in an EPANET-MSX input file """ raise NotImplementedError + +@dataclass +class MSXComment: + pre: List[str] = field(default_factory=list) + post: str = None + + def wrap_msx_string(self, string) -> str: + if self.pre is None or len(self.pre) == 0: + if self.post is None: + return ' ' + string + else: + return ' ' + string + ' ; ' + self.post + elif self.post is None: + return '\n; ' + '\n\n; '.join(self.pre) + '\n\n ' + string + else: + return '\n; ' + '\n\n; '.join(self.pre) + '\n\n ' + string + ' ; ' + self.post + diff --git a/wntr/reaction/dynamics.py b/wntr/reaction/dynamics.py index bb1ddce74..b7e50f3ac 100644 --- a/wntr/reaction/dynamics.py +++ b/wntr/reaction/dynamics.py @@ -57,6 +57,7 @@ from .base import ( ExpressionMixin, LinkedVariablesMixin, + MSXComment, RxnDynamicsType, RxnLocationType, RxnModelRegistry, @@ -91,7 +92,7 @@ class RateDynamics(MSXObject, LinkedVariablesMixin, ExpressionMixin, RxnReaction variable_registry : RxnModelRegistry, optional a link to the remainder of the larger model """ - note: str = None + note: Union[str, Dict[str, str]] = None """A note or comment about this species reaction dynamics""" variable_registry: InitVar[RxnModelRegistry] = field(default=None, compare=False) """A link to the reaction model with variables""" @@ -107,12 +108,16 @@ def to_symbolic(self, transformations=...): return super().to_symbolic(transformations) def to_msx_string(self) -> str: - return "{} {} {} ;{}".format(self.expr_type.name.upper(), str(self.species), self.expression, self.note if self.note else "") + return "{:<12s} {:<8s} {:<32s}".format(self.expr_type.name.upper(), str(self.species), self.expression) def to_dict(self) -> dict: rep = dict(species=self.species, expr_type=self.expr_type.name.lower(), expression=self.expression) - if self.note is not None: + if isinstance(self.note, str): rep['note'] = self.note + elif isinstance(self.note, MSXComment): + rep['note'] = asdict(self.note) if self.note.pre else self.note.post + else: + rep['note'] = None return rep @@ -140,7 +145,7 @@ class EquilibriumDynamics(MSXObject, LinkedVariablesMixin, ExpressionMixin, RxnR a link to the remainder of the larger model """ - note: str = None + note: Union[str, Dict[str, str]] = None """A note or comment about this species reaction dynamics""" variable_registry: InitVar[RxnModelRegistry] = field(default=None, compare=False) """A link to the reaction model with variables""" @@ -156,12 +161,16 @@ def to_symbolic(self, transformations=...): return super().to_symbolic(transformations) def to_msx_string(self) -> str: - return "{} {} {} ;{}".format(self.expr_type.name.upper(), str(self.species), self.expression, self.note if self.note else "") + return "{:<12s} {:<8s} {:<32s}".format(self.expr_type.name.upper(), str(self.species), self.expression) def to_dict(self) -> dict: rep = dict(species=self.species, expr_type=self.expr_type.name.lower(), expression=self.expression) - if self.note is not None: + if isinstance(self.note, str): rep['note'] = self.note + elif isinstance(self.note, MSXComment): + rep['note'] = asdict(self.note) if self.note.pre else self.note.post + else: + rep['note'] = None return rep @@ -188,7 +197,7 @@ class FormulaDynamics(MSXObject, LinkedVariablesMixin, ExpressionMixin, RxnReact a link to the remainder of the larger model """ - note: str = None + note: Union[str, Dict[str, str]] = None """A note or comment about this species reaction dynamics""" variable_registry: InitVar[RxnModelRegistry] = field(default=None, compare=False) """A link to the reaction model with variables""" @@ -204,10 +213,14 @@ def to_symbolic(self, transformations=...): return super().to_symbolic(transformations) def to_msx_string(self) -> str: - return "{} {} {} ;{}".format(self.expr_type.name.upper(), str(self.species), self.expression, self.note if self.note else "") + return "{:<12s} {:<8s} {:<32s}".format(self.expr_type.name.upper(), str(self.species), self.expression) def to_dict(self) -> dict: rep = dict(species=self.species, expr_type=self.expr_type.name.lower(), expression=self.expression) - if self.note is not None: + if isinstance(self.note, str): rep['note'] = self.note + elif isinstance(self.note, MSXComment): + rep['note'] = asdict(self.note) if self.note.pre else self.note.post + else: + rep['note'] = None return rep diff --git a/wntr/reaction/io.py b/wntr/reaction/io.py index 4110db4bd..8844321aa 100644 --- a/wntr/reaction/io.py +++ b/wntr/reaction/io.py @@ -1,11 +1,15 @@ # coding: utf-8 +import datetime +from io import FileIO, TextIOWrapper import logging import sys from wntr.network.elements import Source +from wntr.reaction.base import MSXComment, RxnLocationType, RxnVariableType from wntr.reaction.model import WaterQualityReactionsModel from wntr.reaction.variables import Parameter, Species +from wntr.utils.citations import Citation sys_default_enc = sys.getdefaultencoding() @@ -38,10 +42,10 @@ def _split_line(line): elif len(_vc) == 1: _vals = _vc[0].split() elif _vc[0] == "": - _cmnt = _vc[1] + _cmnt = _vc[1].strip() else: _vals = _vc[0].split() - _cmnt = _vc[1] + _cmnt = _vc[1].strip() return _vals, _cmnt @@ -161,7 +165,7 @@ def _read_title(self): def _read_options(self): lines = [] - prev_comment = None + note = MSXComment() for lnum, line in self.sections["[OPTIONS]"]: vals, comment = _split_line(line) try: @@ -193,193 +197,209 @@ def _read_options(self): def _read_species(self): lines = [] - prev_comment = None + note = MSXComment() for lnum, line in self.sections["[SPECIES]"]: vals, comment = _split_line(line) if vals is None: - prev_comment = comment + if comment is not None: + note.pre.append(comment) continue - if prev_comment is not None and comment is None: - comment = prev_comment - prev_comment = None try: + if comment is not None: + note.post = comment if len(vals) not in [3, 5]: raise SyntaxError("Invalid [SPECIES] entry") + if len(vals) == 3: - species = self.rxn.add_species(vals[0], vals[1], vals[2], note=comment) + species = self.rxn.add_species(vals[0], vals[1], vals[2], note=note) elif len(vals) == 5: - species = self.rxn.add_species(vals[0], vals[1], vals[2], float(vals[3]), float(vals[4]), note=comment) + species = self.rxn.add_species(vals[0], vals[1], vals[2], float(vals[3]), float(vals[4]), note=note) except Exception as e: raise RuntimeError('Error on line {} of file "{}": {}'.format(lnum, self.rxn.filename, line)) from e + else: + note = MSXComment() def _read_coefficients(self): lines = [] - prev_comment = None + note = MSXComment() for lnum, line in self.sections["[COEFFICIENTS]"]: vals, comment = _split_line(line) if vals is None: - prev_comment = comment + if comment is not None: + note.pre.append(comment) continue - if prev_comment is not None and comment is None: - comment = prev_comment - prev_comment = None try: + if comment is not None: + note.post = comment if len(vals) != 3: raise SyntaxError("Invalid [COEFFICIENTS] entry") - coeff = self.rxn.add_coefficient(vals[0], vals[1], float(vals[2]), note=comment) + coeff = self.rxn.add_coefficient(vals[0], vals[1], float(vals[2]), note=note) except Exception as e: raise RuntimeError('Error on line {} of file "{}": {}'.format(lnum, self.rxn.filename, line)) from e + else: + note = MSXComment() def _read_terms(self): lines = [] - prev_comment = None + note = MSXComment() for lnum, line in self.sections["[TERMS]"]: vals, comment = _split_line(line) if vals is None: - prev_comment = comment + if comment is not None: + note.pre.append(comment) continue - if prev_comment is not None and comment is None: - comment = prev_comment - prev_comment = None try: + if comment is not None: + note.post = comment if len(vals) < 2: raise SyntaxError("Invalid [TERMS] entry") - term = self.rxn.add_other_term(vals[0], " ".join(vals[1:]), note=comment) + term = self.rxn.add_other_term(vals[0], " ".join(vals[1:]), note=note) except Exception as e: raise RuntimeError('Error on line {} of file "{}": {}'.format(lnum, self.rxn.filename, line)) from e + else: + note = MSXComment() def _read_pipes(self): lines = [] - prev_comment = None + note = MSXComment() for lnum, line in self.sections["[PIPES]"]: vals, comment = _split_line(line) if vals is None: - prev_comment = comment + if comment is not None: + note.pre.append(comment) continue - if prev_comment is not None and comment is None: - comment = prev_comment - prev_comment = None try: + if comment is not None: + note.post = comment if len(vals) < 3: raise SyntaxError("Invalid [PIPES] entry") - reaction = self.rxn.add_pipe_reaction(vals[1], vals[0], " ".join(vals[2:]), note=comment) + reaction = self.rxn.add_pipe_reaction(vals[1], vals[0], " ".join(vals[2:]), note=note) except Exception as e: raise RuntimeError('Error on line {} of file "{}": {}'.format(lnum, self.rxn.filename, line)) from e + else: + note = MSXComment() def _read_tanks(self): lines = [] - prev_comment = None + note = MSXComment() for lnum, line in self.sections["[TANKS]"]: vals, comment = _split_line(line) if vals is None: - prev_comment = comment + if comment is not None: + note.pre.append(comment) continue - if prev_comment is not None and comment is None: - comment = prev_comment - prev_comment = None try: + if comment is not None: + note.post = comment if len(vals) < 3: raise SyntaxError("Invalid [TANKS] entry") - reaction = self.rxn.add_tank_reaction(vals[1], vals[0], " ".join(vals[2:]), note=comment) + reaction = self.rxn.add_tank_reaction(vals[1], vals[0], " ".join(vals[2:]), note=note) except Exception as e: raise RuntimeError('Error on line {} of file "{}": {}'.format(lnum, self.rxn.filename, line)) from e + else: + note = MSXComment() def _read_sources(self): lines = [] - prev_comment = None + note = MSXComment() for lnum, line in self.sections["[SOURCES]"]: vals, comment = _split_line(line) if vals is None: - prev_comment = comment + if comment is not None: + note.pre.append(comment) continue - if prev_comment is not None and comment is None: - comment = prev_comment - prev_comment = None try: + if comment is not None: + note.post = comment if len(vals) == 4: typ, node, spec, strength = vals pat = None else: typ, node, spec, strength, pat = vals if not self.rxn.has_variable(spec): - raise ValueError('Undefined species in [QUALITY] section: {}'.format(spec)) + raise ValueError("Undefined species in [QUALITY] section: {}".format(spec)) if spec not in self.rxn._sources.keys(): self.rxn._sources[spec] = dict() - source = Source(None, name=spec, node_name=node, source_type=typ, strength=strength, pattern=pat) + source = dict(source_type=typ, strength=strength, pattern=pat, note=note) self.rxn._sources[spec][node] = source except Exception as e: raise RuntimeError('Error on line {} of file "{}": {}'.format(lnum, self.rxn.filename, line)) from e + else: + note = MSXComment() def _read_quality(self): lines = [] - prev_comment = None + note = MSXComment() for lnum, line in self.sections["[QUALITY]"]: vals, comment = _split_line(line) - if len(vals) == 0: continue if vals is None: - prev_comment = comment + if comment is not None: + note.pre.append(comment) continue - if prev_comment is not None and comment is None: - comment = prev_comment - prev_comment = None try: + if comment is not None: + note.post = comment if len(vals) == 4: cmd, netid, spec, concen = vals else: cmd, spec, concen = vals - if cmd[0].lower() not in ['g', 'n', 'l']: - raise SyntaxError('Unknown first word in [QUALITY] section') + if cmd[0].lower() not in ["g", "n", "l"]: + raise SyntaxError("Unknown first word in [QUALITY] section") if not self.rxn.has_variable(spec): - raise ValueError('Undefined species in [QUALITY] section: {}'.format(spec)) + raise ValueError("Undefined species in [QUALITY] section: {}".format(spec)) if spec not in self.rxn._inital_quality.keys(): self.rxn._inital_quality[spec] = dict(global_value=None, nodes=dict(), links=dict()) - if cmd[0].lower() == 'g': - self.rxn._inital_quality[spec]['global_value'] = float(concen) - elif cmd[0].lower() == 'n': - self.rxn._inital_quality[spec]['nodes'][netid] = float(concen) - elif cmd[1].lower() == 'l': - self.rxn._inital_quality[spec]['links'][netid] = float(concen) + if cmd[0].lower() == "g": + self.rxn._inital_quality[spec]["global_value"] = float(concen) + elif cmd[0].lower() == "n": + self.rxn._inital_quality[spec]["nodes"][netid] = float(concen) + elif cmd[1].lower() == "l": + self.rxn._inital_quality[spec]["links"][netid] = float(concen) except Exception as e: raise RuntimeError('Error on line {} of file "{}": {}'.format(lnum, self.rxn.filename, line)) from e + else: + note = MSXComment() def _read_parameters(self): lines = [] - prev_comment = None + note = MSXComment() for lnum, line in self.sections["[PARAMETERS]"]: vals, comment = _split_line(line) if vals is None: - prev_comment = comment + if comment is not None: + note.pre.append(comment) continue - if prev_comment is not None and comment is None: - comment = prev_comment - prev_comment = None try: + if comment is not None: + note.post = comment typ, netid, paramid, value = vals coeff = self.rxn.get_variable(paramid) if not isinstance(coeff, Parameter): raise RuntimeError("Invalid parameter {}".format(paramid)) value = float(value) if typ.lower()[0] == "p": - coeff.pipe_values[netid] = vals + coeff.pipe_values[netid] = value elif typ.lower()[0] == "t": - coeff.tank_values[netid] = vals + coeff.tank_values[netid] = value else: raise RuntimeError("Invalid parameter type {}".format(typ)) except Exception as e: raise RuntimeError('Error on line {} of file "{}": {}'.format(lnum, self.rxn.filename, line)) from e + else: + note = MSXComment() def _read_diffusivity(self): lines = [] - prev_comment = None + note = MSXComment() for lnum, line in self.sections["[DIFFUSIVITY]"]: vals, comment = _split_line(line) if vals is None: - prev_comment = comment + if comment is not None: + note.pre.append(comment) continue - if prev_comment is not None and comment is None: - comment = prev_comment - prev_comment = None try: + if comment is not None: + note.post = comment if len(vals) != 2: raise SyntaxError("Invalid [DIFFUSIVITIES] entry") species = self.rxn.get_variable(vals[0]) @@ -388,6 +408,8 @@ def _read_diffusivity(self): species.diffusivity = float(vals[1]) except Exception as e: raise RuntimeError('Error on line {} of file "{}": {}'.format(lnum, self.rxn.filename, line)) from e + else: + note = MSXComment() def _read_patterns(self): _patterns = dict() @@ -411,62 +433,285 @@ def _read_patterns(self): def _read_report(self): lines = [] - prev_comment = None + note = MSXComment() for lnum, line in self.sections["[REPORT]"]: vals, comment = _split_line(line) if vals is None: - prev_comment = comment + if comment is not None: + note.pre.append(comment) continue - if prev_comment is not None and comment is None: - comment = prev_comment - prev_comment = None try: + if comment is not None: + note.post = comment if len(vals) == 0: continue if len(vals) < 2: - raise SyntaxError('Invalid number of arguments in [REPORT] section') + raise SyntaxError("Invalid number of arguments in [REPORT] section") cmd = vals[0][0].lower() - if cmd == 'n': # NODES + if cmd == "n": # NODES if self.rxn._options.report.nodes is None: - if vals[1].upper() == 'ALL': - self.rxn._options.report.nodes = 'ALL' + if vals[1].upper() == "ALL": + self.rxn._options.report.nodes = "ALL" else: self.rxn._options.report.nodes = list() self.rxn._options.report.nodes.extend(vals[1:]) elif isinstance(self.rxn._options.report.nodes, list): - if vals[1].upper() == 'ALL': - self.rxn._options.report.nodes = 'ALL' + if vals[1].upper() == "ALL": + self.rxn._options.report.nodes = "ALL" else: self.rxn._options.report.nodes.extend(vals[1:]) - elif cmd == 'l': # LINKS + elif cmd == "l": # LINKS if self.rxn._options.report.links is None: - if vals[1].upper() == 'ALL': - self.rxn._options.report.links = 'ALL' + if vals[1].upper() == "ALL": + self.rxn._options.report.links = "ALL" else: self.rxn._options.report.links = list() self.rxn._options.report.links.extend(vals[1:]) elif isinstance(self.rxn._options.report.links, list): - if vals[1].upper() == 'ALL': - self.rxn._options.report.links = 'ALL' + if vals[1].upper() == "ALL": + self.rxn._options.report.links = "ALL" else: self.rxn._options.report.links.extend(vals[1:]) - elif cmd == 'f': + elif cmd == "f": self.rxn._options.report.report_filename = vals[1] - elif cmd == 'p': + elif cmd == "p": self.rxn._options.report.pagesize = vals[1] - elif cmd == 's': + elif cmd == "s": if not self.rxn.has_variable(vals[1]): - raise ValueError('Undefined species in [REPORT] section: {}'.format(vals[1])) - self.rxn._options.report.species[vals[1]] = True if vals[2].lower().startswith('y') else False + raise ValueError("Undefined species in [REPORT] section: {}".format(vals[1])) + self.rxn._options.report.species[vals[1]] = True if vals[2].lower().startswith("y") else False if len(vals) == 4: self.rxn._options.report.species_precision[vals[1]] = int(vals[3]) else: - raise SyntaxError('Invalid syntax in [REPORT] section: unknown first word') + raise SyntaxError("Invalid syntax in [REPORT] section: unknown first word") except Exception as e: raise RuntimeError('Error on line {} of file "{}": {}'.format(lnum, self.rxn.filename, line)) from e - - def write(self, filename, rxn_model): - pass + else: + note = MSXComment() + + def write(self, filename: str, rxn: WaterQualityReactionsModel): + self.rxn = rxn + with open(filename, "w") as fout: + + fout.write("; WNTR-reactions MSX file generated {}\n".format(datetime.datetime.now())) + fout.write("\n") + self._write_title(fout) + self._write_options(fout) + self._write_species(fout) + self._write_coefficients(fout) + self._write_terms(fout) + self._write_pipes(fout) + self._write_tanks(fout) + self._write_sources(fout) + self._write_quality(fout) + self._write_diffusivity(fout) + self._write_parameters(fout) + self._write_patterns(fout) + self._write_report(fout) + fout.write("; END of MSX file generated by WNTR\n") + + def _write_title(self, fout): + fout.write("[TITLE]\n") + fout.write(" {}\n".format(self.rxn.title)) + fout.write("\n") + # if self.rxn.desc is not None: + # desc = self.rxn.desc.splitlines() + # desc = " ".join(desc) + # fout.write("; @desc={}\n".format(desc)) + # fout.write("\n") + # if self.rxn.citations is not None: + # if isinstance(self.rxn.citations, list): + # for citation in self.rxn.citations: + # fout.write("; @cite={}\n".format(citation.to_dict() if isinstance(citation, Citation) else str(citation))) + # fout.write("\n") + # else: + # citation = self.rxn.citations + # fout.write("; @cite={}\n".format(citation.to_dict() if isinstance(citation, Citation) else str(citation))) + # fout.write("\n") + + def _write_options(self, fout): + opts = self.rxn._options + fout.write("[OPTIONS]\n") + fout.write(" AREA_UNITS {}\n".format(opts.quality.area_units.upper())) + fout.write(" RATE_UNITS {}\n".format(opts.quality.rate_units.upper())) + fout.write(" SOLVER {}\n".format(opts.quality.solver.upper())) + fout.write(" COUPLING {}\n".format(opts.quality.coupling.upper())) + fout.write(" TIMESTEP {}\n".format(opts.quality.timestep)) + fout.write(" ATOL {}\n".format(opts.quality.atol)) + fout.write(" RTOL {}\n".format(opts.quality.rtol)) + fout.write(" COMPILER {}\n".format(opts.quality.compiler.upper())) + fout.write(" SEGMENTS {}\n".format(opts.quality.segments)) + fout.write(" PECLET {}\n".format(opts.quality.peclet)) + fout.write("\n") + + def _write_species(self, fout): + fout.write("[SPECIES]\n") + for var in self.rxn.variables(var_type=RxnVariableType.BULK): + if isinstance(var.note, MSXComment): + fout.write("{}\n".format(var.note.wrap_msx_string(var.to_msx_string()))) + elif isinstance(var.note, str): + fout.write(" {} ; {}\n".format(var.to_msx_string(), var.note)) + else: + fout.write(" {}\n".format(var.to_msx_string())) + for var in self.rxn.variables(var_type=RxnVariableType.WALL): + if isinstance(var.note, MSXComment): + fout.write("{}\n".format(var.note.wrap_msx_string(var.to_msx_string()))) + elif isinstance(var.note, str): + fout.write(" {} ; {}\n".format(var.to_msx_string(), var.note)) + else: + fout.write(" {}\n".format(var.to_msx_string())) + fout.write("\n") + + def _write_coefficients(self, fout): + fout.write("[COEFFICIENTS]\n") + for var in self.rxn.variables(var_type=RxnVariableType.CONST): + if isinstance(var.note, MSXComment): + fout.write("{}\n".format(var.note.wrap_msx_string(var.to_msx_string()))) + elif isinstance(var.note, str): + fout.write(" {} ; {}\n".format(var.to_msx_string(), var.note)) + else: + fout.write(" {}\n".format(var.to_msx_string())) + for var in self.rxn.variables(var_type=RxnVariableType.PARAM): + if isinstance(var.note, MSXComment): + fout.write("{}\n".format(var.note.wrap_msx_string(var.to_msx_string()))) + elif isinstance(var.note, str): + fout.write(" {} ; {}\n".format(var.to_msx_string(), var.note)) + else: + fout.write(" {}\n".format(var.to_msx_string())) + fout.write("\n") + + def _write_terms(self, fout): + fout.write("[TERMS]\n") + for var in self.rxn.variables(var_type=RxnVariableType.TERM): + if isinstance(var.note, MSXComment): + fout.write("{}\n".format(var.note.wrap_msx_string(var.to_msx_string()))) + elif isinstance(var.note, str): + fout.write(" {} ; {}\n".format(var.to_msx_string(), var.note)) + else: + fout.write(" {}\n".format(var.to_msx_string())) + fout.write("\n") + + def _write_pipes(self, fout): + fout.write("[PIPES]\n") + for var in self.rxn.reactions(location=RxnLocationType.PIPE): + if isinstance(var.note, MSXComment): + fout.write("{}\n".format(var.note.wrap_msx_string(var.to_msx_string()))) + elif isinstance(var.note, str): + fout.write(" {} ; {}\n".format(var.to_msx_string(), var.note)) + else: + fout.write(" {}\n".format(var.to_msx_string())) + fout.write("\n") + + def _write_tanks(self, fout): + fout.write("[TANKS]\n") + for var in self.rxn.reactions(location=RxnLocationType.TANK): + if isinstance(var.note, MSXComment): + fout.write("{}\n".format(var.note.wrap_msx_string(var.to_msx_string()))) + elif isinstance(var.note, str): + fout.write(" {} ; {}\n".format(var.to_msx_string(), var.note)) + else: + fout.write(" {}\n".format(var.to_msx_string())) + fout.write("\n") + + def _write_sources(self, fout): + fout.write("[SOURCES]\n") + for species in self.rxn._sources.keys(): + for node, src in self.rxn._sources[species].items(): + if isinstance(src["note"], MSXComment): + fout.write( + src["note"].wrap_msx_string( + "{:<10s} {:<8s} {:<8s} {:12s} {:<12s}".format(src["source_type"], node, species, src["strength"], src["pattern"] if src["pattern"] is not None else "") + ) + ) + elif isinstance(src["note"], str): + fout.write( + " {:<10s} {:<8s} {:<8s} {} {:<12s} ; {}\n".format( + src["source_type"], node, species, src["strength"], src["pattern"] if src["pattern"] is not None else "", src["note"] + ) + ) + else: + fout.write( + " {:<10s} {:<8s} {:<8s} {} {:<12s}\n".format(src["source_type"], node, species, src["strength"], src["pattern"] if src["pattern"] is not None else "") + ) + if src["note"] is not None: + fout.write("\n") + fout.write("\n") + + def _write_quality(self, fout): + fout.write("[QUALITY]\n") + for species in self.rxn._inital_quality.keys(): + for typ, val in self.rxn._inital_quality[species].items(): + if typ == "global_value": + fout.write(" {:<8s} {:<8s} {}\n".format("GLOBAL", species, val)) + elif typ in ["nodes", "links"]: + for node, conc in val.items(): + fout.write(" {:<8s} {:<8s} {:<8s} {}\n".format(typ.upper()[0:4], node, species, conc)) + fout.write("\n") + + def _write_parameters(self, fout): + fout.write("[PARAMETERS]\n") + for var in self.rxn.variables(var_type=RxnVariableType.PARAM): + had_entries = False + if not isinstance(var, Parameter): + pass + paramID = var.name + for pipeID, value in var.pipe_values.items(): + fout.write(" PIPE {:<8s} {:<8s} {}\n".format(pipeID, paramID, value)) + had_entries = True + for tankID, value in var.tank_values.items(): + fout.write(" PIPE {:<8s} {:<8s} {}\n".format(tankID, paramID, value)) + had_entries = True + if had_entries: + fout.write("\n") + fout.write("\n") + + def _write_patterns(self, fout): + fout.write("[PATTERNS]\n") + for pattern_name, pattern in self.rxn._patterns.items(): + num_columns = 10 + count = 0 + for i in pattern: # .multipliers: + if count % num_columns == 0: + fout.write("\n {:<8s} {:g}".format(pattern_name, i)) + else: + fout.write(" {:g}".format(i)) + count += 1 + fout.write("\n") + fout.write("\n") + + def _write_diffusivity(self, fout): + fout.write("[DIFFUSIVITY]\n") + for name in self.rxn.species_name_list: + spec: Species = self.rxn.get_variable(name) + if spec.diffusivity is not None: + fout.write(" {:<8s} {}\n".format(name, spec.diffusivity)) + fout.write("\n") + + def _write_report(self, fout): + fout.write("[REPORT]\n") + if self.rxn._options.report.nodes is not None: + if isinstance(self.rxn._options.report.nodes, str): + fout.write(" NODES {}\n".format(self.rxn.options.report.nodes)) + else: + fout.write(" NODES {}\n".format(" ".join(self.rxn.options.report.nodes))) + if self.rxn._options.report.links is not None: + if isinstance(self.rxn._options.report.links, str): + fout.write(" LINKS {}\n".format(self.rxn.options.report.links)) + else: + fout.write(" LINKS {}\n".format(" ".join(self.rxn.options.report.links))) + for spec, val in self.rxn._options.report.species.items(): + fout.write( + " SPECIES {:<8s} {:<3s} {}\n".format( + spec, + "YES" if val else "NO", + self.rxn._options.report.species_precision[spec] if spec in self.rxn._options.report.species_precision.keys() else "", + ) + ) + if self.rxn._options.report.report_filename: + fout.write(" FILE {}\n".format(self.rxn._options.report.report_filename)) + if self.rxn._options.report.pagesize: + fout.write(" PAGESIZE {}\n".format(self.rxn._options.report.pagesize)) + fout.write("\n") class MsxBinFile(object): diff --git a/wntr/reaction/model.py b/wntr/reaction/model.py index ecee8cebc..be20fb3ae 100644 --- a/wntr/reaction/model.py +++ b/wntr/reaction/model.py @@ -137,8 +137,8 @@ def __post_init__(self, allow_sympy_reserved_names=False, options=None): self._usage: Dict[str, Set[str]] = dict() # FIXME: currently no usage tracking - self._sources: Dict[str, Dict[str, Dict[str, Source]]] = dict() - self._inital_quality: Dict[str, Dict[str, Dict[str, Source]]] = dict() + self._sources: Dict[str, Dict[str, Source]] = dict() + self._inital_quality: Dict[str, Dict[str, Dict[str, float]]] = dict() self._patterns: Dict[str, Any] = dict() self._report = list() @@ -315,9 +315,9 @@ def add_species( if (atol is None) ^ (rtol is None): raise TypeError("atol and rtol must be the same type, got {} and {}".format(atol, rtol)) if species_type is RxnVariableType.BULK: - var = BulkSpecies(name, units, atol, rtol, note, self) + var = BulkSpecies(name=name, units=units, atol=atol, rtol=rtol, note=note, variable_registry=self) elif species_type is RxnVariableType.WALL: - var = WallSpecies(name, units, atol, rtol, note, self) + var = WallSpecies(name=name, units=units, atol=atol, rtol=rtol, note=note, variable_registry=self) self._species[name] = var self._inital_quality[name] = dict([('global', None), ('nodes', dict()), ('links', dict())]) self._sources[name] = dict() @@ -667,10 +667,10 @@ def to_dict(self) -> dict: rep["reactions"]["tanks"] = [v.to_dict() for v in self._tank_dynamics.values()] rep["patterns"] = self._patterns.copy() rep["initial_quality"] = self._inital_quality.copy() - rep["sources"] = dict() - for sp, v in self._sources: - if v is not None and len(v) > 0: - rep["sources"][sp] = dict() - for node, source in v: - rep["sources"][sp][node] = source.to_dict() + # rep["sources"] = dict() + # for sp, v in self._sources: + # if v is not None and len(v) > 0: + # rep["sources"][sp] = dict() + # for node, source in v.items(): + # rep["sources"][sp][node] = source.to_dict() return rep diff --git a/wntr/reaction/variables.py b/wntr/reaction/variables.py index b290cd056..a29ff9b55 100644 --- a/wntr/reaction/variables.py +++ b/wntr/reaction/variables.py @@ -47,6 +47,7 @@ RESERVED_NAMES, ExpressionMixin, LinkedVariablesMixin, + MSXComment, MSXObject, RxnModelRegistry, RxnVariable, @@ -65,7 +66,7 @@ class Species(MSXObject, LinkedVariablesMixin, RxnVariable): """The absolute tolerance to use when solving for this species, by default None""" rtol: InitVar[float] = None """The relative tolerance to use when solving for this species, by default None""" - note: str = None + note: Union[str, Dict[str, str]] = None """A note about this species, by default None""" diffusivity: float = None """The diffusivity value for this species, by default None""" @@ -145,18 +146,14 @@ def clear_tolerances(self): def to_msx_string(self) -> str: tols = self.get_tolerances() if tols is None: - # tolstr = "{:<12s} {:<12s}".format("", "") tolstr = "" else: - # tolstr = "{:12.6g} {:12.6g}".format(*tols) - tolstr = "{} {}".format(*tols) - # return "{:<4s} {:<32s} {:s} {:s} ;{:s}".format( - return "{:s} {:s} {:s} {:s} ;{:s}".format( + tolstr = " {:12.6g} {:12.6g}".format(*tols) + return "{:<12s} {:<8s} {:<8s}{:s}".format( self.var_type.name.upper(), self.name, self.units, tolstr, - self.note if self.note is not None else "", ) def to_dict(self): @@ -165,10 +162,13 @@ def to_dict(self): if tols is not None: rep['atol'] = tols[0] rep['rtol'] = tols[1] - if self.note: + rep['diffusivity'] = self.diffusivity + if isinstance(self.note, str): rep['note'] = self.note - if self.diffusivity is not None: - rep['diffusivity'] = self.diffusivity + elif isinstance(self.note, MSXComment): + rep['note'] = asdict(self.note) if self.note.pre else self.note.post + else: + rep['note'] = None return rep @@ -190,7 +190,7 @@ def var_type(self) -> RxnVariableType: class Coefficient(MSXObject, LinkedVariablesMixin, RxnVariable): global_value: float - note: str = None + note: Union[str, Dict[str, str]] = None units: str = None variable_registry: InitVar[RxnModelRegistry] = None @@ -207,20 +207,25 @@ def get_value(self) -> float: return self.global_value def to_msx_string(self) -> str: - # return "{:<6s} {:<32s} {:g};{:s}".format( - return "{:s} {:s} {} ;{:s}".format( + # if self.units is not None: + # post = r' ; {"units"="' + str(self.units) + r'"}' + # else: + post = '' + return "{:<12s} {:<8s} {:<16s}{}".format( self.var_type.name.upper(), self.name, - self.global_value, - self.note if self.note is not None else "", + str(self.global_value), + post ) def to_dict(self): - rep = dict(name=self.name, global_value=self.global_value) - if self.note is not None: + rep = dict(name=self.name, global_value=self.global_value, units=self.units) + if isinstance(self.note, str): rep['note'] = self.note - if self.units is not None: - rep['units'] = self.units + elif isinstance(self.note, MSXComment): + rep['note'] = asdict(self.note) if self.note.pre else self.note.post + else: + rep['note'] = None return rep @@ -292,7 +297,7 @@ class OtherTerm(MSXObject, LinkedVariablesMixin, ExpressionMixin, RxnVariable): expression: str """The expression this named-function is equivalent to""" - note: str = None + note: Union[str, Dict[str, str]] = None """A note about this function/term""" variable_registry: InitVar[RxnModelRegistry] = field(default=None, compare=False) @@ -309,15 +314,19 @@ def var_type(self) -> RxnVariableType: return RxnVariableType.TERM def to_msx_string(self) -> str: - return "{:s} {:s} ;{:s}".format(self.name, self.expression, self.note if self.note is not None else "") + return "{:<8s} {:<64s}".format(self.name, self.expression) def to_symbolic(self, transformations=...): return super().to_symbolic(transformations) def to_dict(self): rep = dict(name=self.name, expression=self.expression) - if self.note is not None: + if isinstance(self.note, str): rep['note'] = self.note + elif isinstance(self.note, MSXComment): + rep['note'] = asdict(self.note) if self.note.pre else self.note.post + else: + rep['note'] = None return rep diff --git a/wntr/utils/citations.py b/wntr/utils/citations.py index d5b970b19..6306b2055 100644 --- a/wntr/utils/citations.py +++ b/wntr/utils/citations.py @@ -110,7 +110,27 @@ def __repr__(self) -> str: for k in list(d.keys()): if d[k] is None: del d[k] - rep = self(self.__class__.__name__) + '(' + rep = str(self.__class__.__name__) + '(' rep = rep + ', '.join(['{}={}'.format(k, repr(v)) for k, v in d.items()]) rep = rep + ')' - return rep \ No newline at end of file + return rep + + def shorten(self, maxlen=None) -> str: + auth = str(self.author) + if len(auth) > 48: + auth = auth[0:44] + '...' + if isinstance(self.author, list): + if len(self.author) > 3: + auth = self.author[0] + ' et al' + else: + auth = ', '.join(self.author) + year = str(self.year) + titl = str(self.title) + ref = ('doi:' + str(self.doi)) if self.doi else (str(self.url) if self.url else (str(self.eprint) if self.eprint else '')) + line = ref + (' // ' if ref else '') + auth + ' // ' + '{}'.format(year) + ' // ' + titl + if maxlen and len(line) > maxlen: + line = line[0:maxlen-3] + '...' + if maxlen and maxlen-3 < len(ref): + return ref + return line + \ No newline at end of file From bb3ec899925b36f2c8aa06edbd961f86351b8e91 Mon Sep 17 00:00:00 2001 From: dbhart Date: Mon, 11 Sep 2023 10:33:51 -0600 Subject: [PATCH 12/75] Citations update --- wntr/utils/citations.py | 276 ++++++++++++++++++++++++++-------------- 1 file changed, 179 insertions(+), 97 deletions(-) diff --git a/wntr/utils/citations.py b/wntr/utils/citations.py index 6306b2055..bee7f33d1 100644 --- a/wntr/utils/citations.py +++ b/wntr/utils/citations.py @@ -3,91 +3,163 @@ Will output the class """ import datetime -from dataclasses import asdict, dataclass -from typing import Any, Dict - +from dataclasses import asdict, dataclass, field +from typing import Any, Dict, Union, List, TypeAlias, Tuple + +Literal: TypeAlias = str +Name: TypeAlias = str +NameList: TypeAlias = Union[Name, List[Name]] +LiteralList: TypeAlias = Union[Literal, List[Literal]] +Key: TypeAlias = str +KeyList: TypeAlias = Union[Key, List[Key]] +Verbatim: TypeAlias = str +Special: TypeAlias = Any +URI: TypeAlias = str +Date: TypeAlias = Union[str, datetime.date] +Range: TypeAlias = Union[str, Tuple[Any, Any]] +SeparatedValues: TypeAlias = Union[str, List[str]] @dataclass(repr=False) -class Citation: +class CitationFields: """A dataclass for citations, most attribute names match biblatex names. - The exceptions are :attr:`citation_class`, which is the "@..." type of an entry, - :attr:`fulldate`, which is the "date" element of a bibliography entry, - and :attr:`report_type`, which is the "type" element of a bib(la)tex entry. + The exceptions are :attr:`entry_type`, which is the "@..." type of an entry + :attr:`fulldate`, which is the "date" element of a bibliography entry + and :attr:`reporttype`, which is the "type" element of a bib(la)tex entry. This class makes no attempt to format or represent the citation in any form other than as a dictionary. """ - - title: str - year: int - key: str = None - author: str = None - - # citation type/subtype (e.g., "report"/"tech. rep.") - citation_class: str = 'misc' - report_type: str = None - - # document identifiers - doi: str = None - url: str = None - isrn: str = None - isbn: str = None - issn: str = None - eprint: str = None - - # container titles - journaltitle: str = None - maintitle: str = None - booktitle: str = None - issuetitle: str = None - - # conference/proceedings info - eventtitle: str = None - eventdate: datetime.date = None - venue: str = None - - # publishing info - institution: str = None - organization: str = None - publisher: str = None - location: str = None - howpublished: str = None - language: str = None - origlanguage: str = None - - # additional people - editor: str = None - bookauthor: str = None - translator: str = None - annotator: str = None - commentator: str = None - introduction: str = None - foreword: str = None - afterword: str = None - - # identifying info - issue: str = None - series: str = None - volume: str = None - number: str = None - part: str = None - edition: str = None - version: str = None - chapter: str = None - pages: str = None - volumes: str = None - pagetotal: str = None - - # dates - month: str = None - fulldate: datetime.date = None - urldate: datetime.date = None - - # extra - note: str = None - addendum: str = None - abstract: str = None - annotation: str = None + title: Literal + author: NameList = None + editor: NameList = None + date: Date = None + year: Literal = None + + abstract: Literal = None + addendum: Literal = None + afterword: NameList = None + annotation: Literal = None + annotator: NameList = None + authortype: Key = None + bookauthor: NameList = None + bookpagination: Key = None + chapter: Literal = None + commentator: NameList = None + doi: Verbatim = None + edition: Union[int, Literal] = None + editora: NameList = None + editorb: NameList = None + editorc: NameList = None + editortype: Key = None + editoratype: Key = None + editorbtype: Key = None + editorctype: Key = None + eid: Literal = None + entrysubtype: Literal = None + eprint: Verbatim = None + eprintclass: Literal = None + eprinttype: Literal = None + eventdate: Date = None + file: Verbatim = None + foreword: NameList = None + holder: NameList = None + howpublished: Literal = None + institution: LiteralList = None + introduction: NameList = None + isan: Literal = None + isbn: Literal = None + ismn: Literal = None + isrn: Literal = None + issn: Literal = None + issue: Literal = None + iswc: Literal = None + # Titles + eventtitle: Literal = None + eventtitleaddon: Literal = None + subtitle: Literal = None + titleaddon: Literal = None + journalsubtitle: Literal = None + journaltitle: Literal = None + journaltitleaddon: Literal = None + issuesubtitle: Literal = None + issuetitle: Literal = None + issuetitleaddon: Literal = None + booksubtitle: Literal = None + booktitle: Literal = None + booktitleaddon: Literal = None + mainsubtitle: Literal = None + maintitle: Literal = None + maintitleaddon: Literal = None + origtitle: Literal = None + reprinttitle: Literal = None + shorttitle: Literal = None + shortjournal: Literal = None + indextitle: Literal = None + indexsorttitle: Literal = None + sorttitle: Literal = None + # Continued + label: Literal = None + language: KeyList = None + library: Literal = None + location: LiteralList = None + month: Literal = None + nameaddon: Literal = None + note: Literal = None + number: Literal = None + organization: LiteralList = None + origdate: Date = None + origlanguage: KeyList = None + origlocation: LiteralList = None + origpublisher: LiteralList = None + pages: Range = None + pagetotal: Literal = None + pagination: Key = None + part: Literal = None + publisher: LiteralList = None + pubstate: Key = None + series: Literal = None + shortauthor: NameList = None + shorteditor: NameList = None + shorthand: Literal = None + shorthandintro: Literal = None + shortseries: Literal = None + translator: NameList = None + type: Key = None + url: URI = None + urldate: Date = None + venue: Literal = None + version: Literal = None + volume: int = None + volumes: int = None + # SPECIAL FIELDS + crossref: Key = None + entryset: SeparatedValues = None + execute: Special = None + gender: Key = None + langid: Key = None + langidopts: Special = None + ids: SeparatedValues = None + keywords: SeparatedValues = None + options: Special = None + presort: Special = None + related: SeparatedValues = None + relatedoptions: SeparatedValues = None + relatedtype: Special = None + relatedstring: Literal = None + sortkey: Literal = None + sortname: NameList = None + sortshorthand: Literal = None + sortyear: int = None + xdata: SeparatedValues = None + xref: Key = None + # FIELD ALIASES + address: LiteralList = None + annote: Literal = None + archiveprefix: Literal = None + journal: Literal = None + pdf: Verbatim = None + primaryclass: Literal = None + school: LiteralList = None def to_dict(self) -> Dict[str, Any]: """Return a dictionary representation of the citation. @@ -115,22 +187,32 @@ def __repr__(self) -> str: rep = rep + ')' return rep - def shorten(self, maxlen=None) -> str: - auth = str(self.author) - if len(auth) > 48: - auth = auth[0:44] + '...' - if isinstance(self.author, list): - if len(self.author) > 3: - auth = self.author[0] + ' et al' - else: - auth = ', '.join(self.author) - year = str(self.year) - titl = str(self.title) - ref = ('doi:' + str(self.doi)) if self.doi else (str(self.url) if self.url else (str(self.eprint) if self.eprint else '')) - line = ref + (' // ' if ref else '') + auth + ' // ' + '{}'.format(year) + ' // ' + titl - if maxlen and len(line) > maxlen: - line = line[0:maxlen-3] + '...' - if maxlen and maxlen-3 < len(ref): - return ref - return line - \ No newline at end of file + +@dataclass(repr=False) +class Citation: + entry_type: str + key: str + fields: CitationFields = field(default_factory=CitationFields) + + def __post_init__(self): + if isinstance(self.fields, dict): + self.fields = CitationFields(**self.fields) + elif isinstance(self.fields, list): + self.fields = CitationFields(*self.fields) + + def to_dict(self): + """Convert to a dictionary. + + Returns + ------- + dict + the citation dictionaries + """ + try: + ret = dict() + ret['entry_type'] = self.entry_type + ret['key'] = self.key + ret['fields'] = self.fields.to_dict() + return ret + except: + return asdict(self) From 455958d3e7a01ce28384e1ae3e600412c9723442 Mon Sep 17 00:00:00 2001 From: dbhart Date: Mon, 11 Sep 2023 10:34:41 -0600 Subject: [PATCH 13/75] Adding a (very basic) citations class --- wntr/utils/citations.py | 218 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 218 insertions(+) create mode 100644 wntr/utils/citations.py diff --git a/wntr/utils/citations.py b/wntr/utils/citations.py new file mode 100644 index 000000000..bee7f33d1 --- /dev/null +++ b/wntr/utils/citations.py @@ -0,0 +1,218 @@ +# coding: utf-8 +"""Contains a dataclass that can be used to store citations. +Will output the class +""" +import datetime +from dataclasses import asdict, dataclass, field +from typing import Any, Dict, Union, List, TypeAlias, Tuple + +Literal: TypeAlias = str +Name: TypeAlias = str +NameList: TypeAlias = Union[Name, List[Name]] +LiteralList: TypeAlias = Union[Literal, List[Literal]] +Key: TypeAlias = str +KeyList: TypeAlias = Union[Key, List[Key]] +Verbatim: TypeAlias = str +Special: TypeAlias = Any +URI: TypeAlias = str +Date: TypeAlias = Union[str, datetime.date] +Range: TypeAlias = Union[str, Tuple[Any, Any]] +SeparatedValues: TypeAlias = Union[str, List[str]] + +@dataclass(repr=False) +class CitationFields: + """A dataclass for citations, most attribute names match biblatex names. + The exceptions are :attr:`entry_type`, which is the "@..." type of an entry + :attr:`fulldate`, which is the "date" element of a bibliography entry + and :attr:`reporttype`, which is the "type" element of a bib(la)tex entry. + + This class makes no attempt to format or represent the citation in any form + other than as a dictionary. + """ + title: Literal + author: NameList = None + editor: NameList = None + date: Date = None + year: Literal = None + + abstract: Literal = None + addendum: Literal = None + afterword: NameList = None + annotation: Literal = None + annotator: NameList = None + authortype: Key = None + bookauthor: NameList = None + bookpagination: Key = None + chapter: Literal = None + commentator: NameList = None + doi: Verbatim = None + edition: Union[int, Literal] = None + editora: NameList = None + editorb: NameList = None + editorc: NameList = None + editortype: Key = None + editoratype: Key = None + editorbtype: Key = None + editorctype: Key = None + eid: Literal = None + entrysubtype: Literal = None + eprint: Verbatim = None + eprintclass: Literal = None + eprinttype: Literal = None + eventdate: Date = None + file: Verbatim = None + foreword: NameList = None + holder: NameList = None + howpublished: Literal = None + institution: LiteralList = None + introduction: NameList = None + isan: Literal = None + isbn: Literal = None + ismn: Literal = None + isrn: Literal = None + issn: Literal = None + issue: Literal = None + iswc: Literal = None + # Titles + eventtitle: Literal = None + eventtitleaddon: Literal = None + subtitle: Literal = None + titleaddon: Literal = None + journalsubtitle: Literal = None + journaltitle: Literal = None + journaltitleaddon: Literal = None + issuesubtitle: Literal = None + issuetitle: Literal = None + issuetitleaddon: Literal = None + booksubtitle: Literal = None + booktitle: Literal = None + booktitleaddon: Literal = None + mainsubtitle: Literal = None + maintitle: Literal = None + maintitleaddon: Literal = None + origtitle: Literal = None + reprinttitle: Literal = None + shorttitle: Literal = None + shortjournal: Literal = None + indextitle: Literal = None + indexsorttitle: Literal = None + sorttitle: Literal = None + # Continued + label: Literal = None + language: KeyList = None + library: Literal = None + location: LiteralList = None + month: Literal = None + nameaddon: Literal = None + note: Literal = None + number: Literal = None + organization: LiteralList = None + origdate: Date = None + origlanguage: KeyList = None + origlocation: LiteralList = None + origpublisher: LiteralList = None + pages: Range = None + pagetotal: Literal = None + pagination: Key = None + part: Literal = None + publisher: LiteralList = None + pubstate: Key = None + series: Literal = None + shortauthor: NameList = None + shorteditor: NameList = None + shorthand: Literal = None + shorthandintro: Literal = None + shortseries: Literal = None + translator: NameList = None + type: Key = None + url: URI = None + urldate: Date = None + venue: Literal = None + version: Literal = None + volume: int = None + volumes: int = None + # SPECIAL FIELDS + crossref: Key = None + entryset: SeparatedValues = None + execute: Special = None + gender: Key = None + langid: Key = None + langidopts: Special = None + ids: SeparatedValues = None + keywords: SeparatedValues = None + options: Special = None + presort: Special = None + related: SeparatedValues = None + relatedoptions: SeparatedValues = None + relatedtype: Special = None + relatedstring: Literal = None + sortkey: Literal = None + sortname: NameList = None + sortshorthand: Literal = None + sortyear: int = None + xdata: SeparatedValues = None + xref: Key = None + # FIELD ALIASES + address: LiteralList = None + annote: Literal = None + archiveprefix: Literal = None + journal: Literal = None + pdf: Verbatim = None + primaryclass: Literal = None + school: LiteralList = None + + def to_dict(self) -> Dict[str, Any]: + """Return a dictionary representation of the citation. + All blank (None) values will be removed from the dictionary + so that it is minimal. + + Returns + ------- + Dict[str, Any] + minimal dictionary representation of the Citation + """ + d = asdict(self) + for k in list(d.keys()): + if d[k] is None: + del d[k] + return d + + def __repr__(self) -> str: + d = asdict(self) + for k in list(d.keys()): + if d[k] is None: + del d[k] + rep = str(self.__class__.__name__) + '(' + rep = rep + ', '.join(['{}={}'.format(k, repr(v)) for k, v in d.items()]) + rep = rep + ')' + return rep + + +@dataclass(repr=False) +class Citation: + entry_type: str + key: str + fields: CitationFields = field(default_factory=CitationFields) + + def __post_init__(self): + if isinstance(self.fields, dict): + self.fields = CitationFields(**self.fields) + elif isinstance(self.fields, list): + self.fields = CitationFields(*self.fields) + + def to_dict(self): + """Convert to a dictionary. + + Returns + ------- + dict + the citation dictionaries + """ + try: + ret = dict() + ret['entry_type'] = self.entry_type + ret['key'] = self.key + ret['fields'] = self.fields.to_dict() + return ret + except: + return asdict(self) From d746e4fa1e60428ebbd727d0e388ff854d66de4d Mon Sep 17 00:00:00 2001 From: dbhart Date: Mon, 11 Sep 2023 11:01:35 -0600 Subject: [PATCH 14/75] Update documentation --- wntr/utils/citations.py | 151 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 145 insertions(+), 6 deletions(-) diff --git a/wntr/utils/citations.py b/wntr/utils/citations.py index bee7f33d1..54aeab8b9 100644 --- a/wntr/utils/citations.py +++ b/wntr/utils/citations.py @@ -1,33 +1,170 @@ # coding: utf-8 """Contains a dataclass that can be used to store citations. -Will output the class """ import datetime from dataclasses import asdict, dataclass, field from typing import Any, Dict, Union, List, TypeAlias, Tuple Literal: TypeAlias = str +"""A literal string""" Name: TypeAlias = str +"""A name string, preferrably in order without commas""" NameList: TypeAlias = Union[Name, List[Name]] +"""A list of names, or a string with "and" between names""" LiteralList: TypeAlias = Union[Literal, List[Literal]] +"""A list of literals, or a string with "and" between literals""" Key: TypeAlias = str +"""A string that comes from a limited set of values""" KeyList: TypeAlias = Union[Key, List[Key]] +"""A list of keys, or a string with "and" between keys""" Verbatim: TypeAlias = str +"""A string that should not be interpreted (ie raw)""" Special: TypeAlias = Any +"""Anything that isn't a string or list of strings""" URI: TypeAlias = str +"""A valid URI""" Date: TypeAlias = Union[str, datetime.date] +"""A date or string in yyyy-mm-dd format (must be 0-padded, eg 2021-02-02 for February 2, 2021""" Range: TypeAlias = Union[str, Tuple[Any, Any]] +"""A 2-tuple of (start,stop) or a string with two values separated by '--' """ SeparatedValues: TypeAlias = Union[str, List[str]] +"""A list of strings, or a string that is delimited (the delimiter is not specified)""" @dataclass(repr=False) class CitationFields: """A dataclass for citations, most attribute names match biblatex names. - The exceptions are :attr:`entry_type`, which is the "@..." type of an entry - :attr:`fulldate`, which is the "date" element of a bibliography entry - and :attr:`reporttype`, which is the "type" element of a bib(la)tex entry. - This class makes no attempt to format or represent the citation in any form other than as a dictionary. + + Parameters + ---------- + title: Literal + The title is the only required field + author: NameList, optional + editor: NameList, optional + date: Date, optional + year: Literal, optional + abstract: Literal, optional + addendum: Literal, optional + afterword: NameList, optional + annotation: Literal, optional + annotator: NameList, optional + authortype: Key, optional + bookauthor: NameList, optional + bookpagination: Key, optional + chapter: Literal, optional + commentator: NameList, optional + doi: Verbatim, optional + edition: Union[int, Literal], optional + editora: NameList, optional + editorb: NameList, optional + editorc: NameList, optional + editortype: Key, optional + editoratype: Key, optional + editorbtype: Key, optional + editorctype: Key, optional + eid: Literal, optional + entrysubtype: Literal, optional + eprint: Verbatim, optional + eprintclass: Literal, optional + eprinttype: Literal, optional + eventdate: Date, optional + file: Verbatim, optional + foreword: NameList, optional + holder: NameList, optional + howpublished: Literal, optional + institution: LiteralList, optional + introduction: NameList, optional + isan: Literal, optional + isbn: Literal, optional + ismn: Literal, optional + isrn: Literal, optional + issn: Literal, optional + issue: Literal, optional + iswc: Literal, optional + eventtitle: Literal, optional + eventtitleaddon: Literal, optional + subtitle: Literal, optional + titleaddon: Literal, optional + journalsubtitle: Literal, optional + journaltitle: Literal, optional + journaltitleaddon: Literal, optional + issuesubtitle: Literal, optional + issuetitle: Literal, optional + issuetitleaddon: Literal, optional + booksubtitle: Literal, optional + booktitle: Literal, optional + booktitleaddon: Literal, optional + mainsubtitle: Literal, optional + maintitle: Literal, optional + maintitleaddon: Literal, optional + origtitle: Literal, optional + reprinttitle: Literal, optional + shorttitle: Literal, optional + shortjournal: Literal, optional + indextitle: Literal, optional + indexsorttitle: Literal, optional + sorttitle: Literal, optional + label: Literal, optional + language: KeyList, optional + library: Literal, optional + location: LiteralList, optional + month: Literal, optional + nameaddon: Literal, optional + note: Literal, optional + number: Literal, optional + organization: LiteralList, optional + origdate: Date, optional + origlanguage: KeyList, optional + origlocation: LiteralList, optional + origpublisher: LiteralList, optional + pages: Range, optional + pagetotal: Literal, optional + pagination: Key, optional + part: Literal, optional + publisher: LiteralList, optional + pubstate: Key, optional + series: Literal, optional + shortauthor: NameList, optional + shorteditor: NameList, optional + shorthand: Literal, optional + shorthandintro: Literal, optional + shortseries: Literal, optional + translator: NameList, optional + type: Key, optional + url: URI, optional + urldate: Date, optional + venue: Literal, optional + version: Literal, optional + volume: int, optional + volumes: int, optional + crossref: Key, optional + entryset: SeparatedValues, optional + execute: Special, optional + gender: Key, optional + langid: Key, optional + langidopts: Special, optional + ids: SeparatedValues, optional + keywords: SeparatedValues, optional + options: Special, optional + presort: Special, optional + related: SeparatedValues, optional + relatedoptions: SeparatedValues, optional + relatedtype: Special, optional + relatedstring: Literal, optional + sortkey: Literal, optional + sortname: NameList, optional + sortshorthand: Literal, optional + sortyear: int, optional + xdata: SeparatedValues, optional + xref: Key, optional + address: LiteralList, optional + annote: Literal, optional + archiveprefix: Literal, optional + journal: Literal, optional + pdf: Verbatim, optional + primaryclass: Literal, optional + school: LiteralList, optional """ title: Literal author: NameList = None @@ -190,6 +327,8 @@ def __repr__(self) -> str: @dataclass(repr=False) class Citation: + """A class to hold a citation to document the source of a model. + """ entry_type: str key: str fields: CitationFields = field(default_factory=CitationFields) @@ -206,7 +345,7 @@ def to_dict(self): Returns ------- dict - the citation dictionaries + the citation dictionary """ try: ret = dict() From 57a9d2f6523bb736b6a6ad548336ad4348543724 Mon Sep 17 00:00:00 2001 From: dbhart Date: Mon, 11 Sep 2023 15:31:23 -0600 Subject: [PATCH 15/75] Updates after internal discussion --- documentation/apidoc/wntr.utils.rst | 1 + wntr/reaction/library.py | 2 +- wntr/reaction/model.py | 7 +++++++ 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/documentation/apidoc/wntr.utils.rst b/documentation/apidoc/wntr.utils.rst index f613c8e99..749fda061 100644 --- a/documentation/apidoc/wntr.utils.rst +++ b/documentation/apidoc/wntr.utils.rst @@ -12,6 +12,7 @@ Submodules .. toctree:: + wntr.utils.citations wntr.utils.logger wntr.utils.ordered_set diff --git a/wntr/reaction/library.py b/wntr/reaction/library.py index feacbac13..6409cc017 100644 --- a/wntr/reaction/library.py +++ b/wntr/reaction/library.py @@ -88,7 +88,7 @@ lead_ppm = WaterQualityReactionsModel( title="Lead Plumbosolvency Model (from Burkhardt et al 2020)", desc="Parameters for EPA HPS Simulator Model", - citations=[Citation( + citations=[Citation( title="Framework for Modeling Lead in Premise Plumbing Systems Using EPANET", year=2020, author=[ diff --git a/wntr/reaction/model.py b/wntr/reaction/model.py index be20fb3ae..5b7b3cd13 100644 --- a/wntr/reaction/model.py +++ b/wntr/reaction/model.py @@ -2,6 +2,8 @@ """ Water quality reactions model. +TODO: FIXME: Make sure that we throw the same errors (text/number) as MSX would throw + """ import logging @@ -92,6 +94,10 @@ class WaterQualityReactionsModel(RxnModelRegistry): The water network model to use, by default None """ + # FIXME: Make the __init__ just minimal, with a filename + # do the rest of stuff directly on the MSX object, make it as + # close to WNM as possible + title: str = None """A one-line title for the model""" @@ -558,6 +564,7 @@ def reactions(self, location: RxnLocationType = None): yield v def add_reaction(self, location: RxnLocationType, species: Union[str, Species], dynamics: Union[str, int, RxnDynamicsType], expression: str, note: str = None): + # TODO: accept a "both" or "all" value for location location = RxnLocationType.factory(location) species = str(species) if species not in self._species.keys(): From 74a056f40920ed28b6fe26765fd225ea1d3f0d95 Mon Sep 17 00:00:00 2001 From: dbhart Date: Tue, 12 Sep 2023 15:16:33 -0600 Subject: [PATCH 16/75] Update to read/write citations on the WaterNetworkModel --- wntr/network/io.py | 2 + wntr/network/model.py | 4 + wntr/utils/citations.py | 386 +++++++++++++++++++--------------------- 3 files changed, 189 insertions(+), 203 deletions(-) diff --git a/wntr/network/io.py b/wntr/network/io.py index b8d009937..82ced0108 100644 --- a/wntr/network/io.py +++ b/wntr/network/io.py @@ -69,6 +69,7 @@ def to_dict(wn) -> dict: version="wntr-{}".format(__version__), comment="WaterNetworkModel - all values given in SI units", name=wn.name, + citations=wntr.utils.citations.to_dict(wn.citations), options=wn._options.to_dict(), curves=wn._curve_reg.to_list(), patterns=wn._pattern_reg.to_list(), @@ -103,6 +104,7 @@ def from_dict(d: dict, append=None): "version", "comment", "name", + "citations", "options", "curves", "patterns", diff --git a/wntr/network/model.py b/wntr/network/model.py index 938da1421..3c235e797 100644 --- a/wntr/network/model.py +++ b/wntr/network/model.py @@ -16,6 +16,7 @@ """ import logging from collections import OrderedDict +from typing import List, Union from warnings import warn import networkx as nx @@ -24,6 +25,7 @@ import six import wntr.epanet import wntr.network.io +from wntr.utils.citations import Citation from wntr.utils.ordered_set import OrderedSet from .base import AbstractModel, Link, LinkStatus, Registry @@ -71,6 +73,8 @@ def __init__(self, inp_file_name=None): # Network name self.name = None + self.citations: Union[str,Citation, List[Union[str,Citation]]] = list() + """A list of citations that document the source of this model. See also :class:`~wntr.utils.citations.Citation`.""" self._options = Options() self._node_reg = NodeRegistry(self) diff --git a/wntr/utils/citations.py b/wntr/utils/citations.py index 54aeab8b9..db0cba886 100644 --- a/wntr/utils/citations.py +++ b/wntr/utils/citations.py @@ -1,176 +1,154 @@ # coding: utf-8 """Contains a dataclass that can be used to store citations. """ +from __future__ import annotations +import dataclasses + import datetime -from dataclasses import asdict, dataclass, field -from typing import Any, Dict, Union, List, TypeAlias, Tuple +from dataclasses import asdict, dataclass, field, is_dataclass +from typing import Any, Dict, Union, List, Tuple -Literal: TypeAlias = str +Literal = str """A literal string""" -Name: TypeAlias = str +Name = str """A name string, preferrably in order without commas""" -NameList: TypeAlias = Union[Name, List[Name]] +NameList = Union[Name, List[Name]] """A list of names, or a string with "and" between names""" -LiteralList: TypeAlias = Union[Literal, List[Literal]] +LiteralList = Union[Literal, List[Literal]] """A list of literals, or a string with "and" between literals""" -Key: TypeAlias = str +Key = str """A string that comes from a limited set of values""" -KeyList: TypeAlias = Union[Key, List[Key]] +KeyList = Union[Key, List[Key]] """A list of keys, or a string with "and" between keys""" -Verbatim: TypeAlias = str +Verbatim = str """A string that should not be interpreted (ie raw)""" -Special: TypeAlias = Any +Special = Any """Anything that isn't a string or list of strings""" -URI: TypeAlias = str +URI = str """A valid URI""" -Date: TypeAlias = Union[str, datetime.date] +Date = Union[str, datetime.date] """A date or string in yyyy-mm-dd format (must be 0-padded, eg 2021-02-02 for February 2, 2021""" -Range: TypeAlias = Union[str, Tuple[Any, Any]] +Range = Union[str, Tuple[Any, Any]] """A 2-tuple of (start,stop) or a string with two values separated by '--' """ -SeparatedValues: TypeAlias = Union[str, List[str]] +SeparatedValues = Union[str, List[str]] """A list of strings, or a string that is delimited (the delimiter is not specified)""" -@dataclass(repr=False) -class CitationFields: - """A dataclass for citations, most attribute names match biblatex names. - This class makes no attempt to format or represent the citation in any form - other than as a dictionary. +@dataclass(repr=False) +class Citation: + """A class to hold a citation to document the source of a model. + Parameters ---------- - title: Literal - The title is the only required field - author: NameList, optional - editor: NameList, optional - date: Date, optional - year: Literal, optional - abstract: Literal, optional - addendum: Literal, optional - afterword: NameList, optional - annotation: Literal, optional - annotator: NameList, optional - authortype: Key, optional - bookauthor: NameList, optional - bookpagination: Key, optional - chapter: Literal, optional - commentator: NameList, optional - doi: Verbatim, optional - edition: Union[int, Literal], optional - editora: NameList, optional - editorb: NameList, optional - editorc: NameList, optional - editortype: Key, optional - editoratype: Key, optional - editorbtype: Key, optional - editorctype: Key, optional - eid: Literal, optional - entrysubtype: Literal, optional - eprint: Verbatim, optional - eprintclass: Literal, optional - eprinttype: Literal, optional - eventdate: Date, optional - file: Verbatim, optional - foreword: NameList, optional - holder: NameList, optional - howpublished: Literal, optional - institution: LiteralList, optional - introduction: NameList, optional - isan: Literal, optional - isbn: Literal, optional - ismn: Literal, optional - isrn: Literal, optional - issn: Literal, optional - issue: Literal, optional - iswc: Literal, optional - eventtitle: Literal, optional - eventtitleaddon: Literal, optional - subtitle: Literal, optional - titleaddon: Literal, optional - journalsubtitle: Literal, optional - journaltitle: Literal, optional - journaltitleaddon: Literal, optional - issuesubtitle: Literal, optional - issuetitle: Literal, optional - issuetitleaddon: Literal, optional - booksubtitle: Literal, optional - booktitle: Literal, optional - booktitleaddon: Literal, optional - mainsubtitle: Literal, optional - maintitle: Literal, optional - maintitleaddon: Literal, optional - origtitle: Literal, optional - reprinttitle: Literal, optional - shorttitle: Literal, optional - shortjournal: Literal, optional - indextitle: Literal, optional - indexsorttitle: Literal, optional - sorttitle: Literal, optional - label: Literal, optional - language: KeyList, optional - library: Literal, optional - location: LiteralList, optional - month: Literal, optional - nameaddon: Literal, optional - note: Literal, optional - number: Literal, optional - organization: LiteralList, optional - origdate: Date, optional - origlanguage: KeyList, optional - origlocation: LiteralList, optional - origpublisher: LiteralList, optional - pages: Range, optional - pagetotal: Literal, optional - pagination: Key, optional - part: Literal, optional - publisher: LiteralList, optional - pubstate: Key, optional - series: Literal, optional - shortauthor: NameList, optional - shorteditor: NameList, optional - shorthand: Literal, optional - shorthandintro: Literal, optional - shortseries: Literal, optional - translator: NameList, optional - type: Key, optional - url: URI, optional - urldate: Date, optional - venue: Literal, optional - version: Literal, optional - volume: int, optional - volumes: int, optional - crossref: Key, optional - entryset: SeparatedValues, optional - execute: Special, optional - gender: Key, optional - langid: Key, optional - langidopts: Special, optional - ids: SeparatedValues, optional - keywords: SeparatedValues, optional - options: Special, optional - presort: Special, optional - related: SeparatedValues, optional - relatedoptions: SeparatedValues, optional - relatedtype: Special, optional - relatedstring: Literal, optional - sortkey: Literal, optional - sortname: NameList, optional - sortshorthand: Literal, optional - sortyear: int, optional - xdata: SeparatedValues, optional - xref: Key, optional - address: LiteralList, optional - annote: Literal, optional - archiveprefix: Literal, optional - journal: Literal, optional - pdf: Verbatim, optional - primaryclass: Literal, optional - school: LiteralList, optional + entry_type : str + Describe the type of citation, for example, 'journal' or 'book'. + key : str + A key to use to identify this citation. Usually a BibTeX key or an + alphanumeric key per citation standards. + fields : CitationFields + An object that has attributes that align with different citation + fields, such as 'title' or 'author'. + """ + + entry_type: str + key: str + fields: "CitationFields" = None + + def __post_init__(self): + if self.fields is None: + self.fields = CitationFields(None) + elif isinstance(self.fields, dict): + self.fields = CitationFields(**self.fields) + elif isinstance(self.fields, list): + self.fields = CitationFields(*self.fields) + + def to_dict(self): + """Convert to a dictionary. + + Returns + ------- + dict + the citation dictionary + """ + try: + ret = dict() + ret["entry_type"] = self.entry_type + ret["key"] = self.key + ret["fields"] = self.fields.to_dict() + return ret + except: + return asdict(self) + + +@dataclass(repr=False) +class CitationFields: + """A dataclass for citation fields; field names and types are taken from BibLaTeX. + This class makes no attempt to format or represent the citation in any form + other than as a dictionary. This class also does not perform any type-checking + on fields, although it does create ``TypeAlias`` es for each field for the + user's information. Please see the BibLaTeX or BibTeX documentation for a list of + valid field names. """ - title: Literal + + title: Literal = None + """Title of the work, required for most bibliographies.""" author: NameList = None + """The author of a work. Typically, either `author` or `editor` is required.""" editor: NameList = None + """The editor of a work. Typically, either `author` or `editor` is required.""" date: Date = None + """The date the work was published. Typically, either `year` or `date` is required""" year: Literal = None + """The year the work was published. Typically, either `year` or `date` is required.""" + journal: Literal = None + """The journal an articles was published in. Both `journal` and `journaltitle` are accepted as field names.""" + journaltitle: Literal = None + """The journal an articles was published in. Both `journal` and `journaltitle` are accepted as field names.""" + doi: Verbatim = None + """The DOI identifier. Most works, and nearly all journal articles, have a DOI.""" + type: Key = None + """The (sub)type of an :attr:`Citation.entry_type`. For example, "masters" for a masters thesis.""" + + volume: int = None + """The volume for a journal or multi-volume set. Use `volumes` to list the total number of volumes in a set.""" + number: Literal = None + """The journal number within a volume, or a report number.""" + pages: Range = None + """The pages for the work.""" + eid: Literal = None + """The electronic identifier number, has replaced pages in some digital journals.""" + issue: Literal = None + """The issue if the issue is not a number, for example, 'Spring'""" + series: Literal = None + """The series name, such as 'Chemical Reviews'""" + part: Literal = None + """The part, usually for reports or multi-volume sets.""" + + eprint: Verbatim = None + """Used for alternatives to DOI, such as PubMed PMIDs. The `eprintclass` and `eprinttype` fields identify the type of ID.""" + eprintclass: Literal = None + eprinttype: Literal = None + url: URI = None + """A URL for access to a dataset or work. Use `urldate` to indicate when the URL was accessed.""" + urldate: Date = None + """The date a `url` was accessed.""" + + issuetitle: Literal = None + booktitle: Literal = None + eventtitle: Literal = None + maintitle: Literal = None + """The `maintitle`, `booktitle`, `eventtitle`, and `issuetitle` are used for containing works, such as for works within proceedings.""" + + eventdate: Date = None + + institution: LiteralList = None + organization: LiteralList = None + publisher: LiteralList = None + school: LiteralList = None + + location: LiteralList = None + address: LiteralList = None + venue: Literal = None abstract: Literal = None addendum: Literal = None @@ -182,7 +160,6 @@ class CitationFields: bookpagination: Key = None chapter: Literal = None commentator: NameList = None - doi: Verbatim = None edition: Union[int, Literal] = None editora: NameList = None editorb: NameList = None @@ -191,41 +168,29 @@ class CitationFields: editoratype: Key = None editorbtype: Key = None editorctype: Key = None - eid: Literal = None entrysubtype: Literal = None - eprint: Verbatim = None - eprintclass: Literal = None - eprinttype: Literal = None - eventdate: Date = None file: Verbatim = None foreword: NameList = None holder: NameList = None howpublished: Literal = None - institution: LiteralList = None introduction: NameList = None isan: Literal = None isbn: Literal = None ismn: Literal = None isrn: Literal = None issn: Literal = None - issue: Literal = None iswc: Literal = None # Titles - eventtitle: Literal = None eventtitleaddon: Literal = None subtitle: Literal = None titleaddon: Literal = None journalsubtitle: Literal = None - journaltitle: Literal = None journaltitleaddon: Literal = None issuesubtitle: Literal = None - issuetitle: Literal = None issuetitleaddon: Literal = None booksubtitle: Literal = None - booktitle: Literal = None booktitleaddon: Literal = None mainsubtitle: Literal = None - maintitle: Literal = None maintitleaddon: Literal = None origtitle: Literal = None reprinttitle: Literal = None @@ -238,35 +203,23 @@ class CitationFields: label: Literal = None language: KeyList = None library: Literal = None - location: LiteralList = None month: Literal = None nameaddon: Literal = None note: Literal = None - number: Literal = None - organization: LiteralList = None origdate: Date = None origlanguage: KeyList = None origlocation: LiteralList = None origpublisher: LiteralList = None - pages: Range = None pagetotal: Literal = None pagination: Key = None - part: Literal = None - publisher: LiteralList = None pubstate: Key = None - series: Literal = None shortauthor: NameList = None shorteditor: NameList = None shorthand: Literal = None shorthandintro: Literal = None shortseries: Literal = None translator: NameList = None - type: Key = None - url: URI = None - urldate: Date = None - venue: Literal = None version: Literal = None - volume: int = None volumes: int = None # SPECIAL FIELDS crossref: Key = None @@ -290,13 +243,10 @@ class CitationFields: xdata: SeparatedValues = None xref: Key = None # FIELD ALIASES - address: LiteralList = None annote: Literal = None archiveprefix: Literal = None - journal: Literal = None pdf: Verbatim = None primaryclass: Literal = None - school: LiteralList = None def to_dict(self) -> Dict[str, Any]: """Return a dictionary representation of the citation. @@ -319,39 +269,69 @@ def __repr__(self) -> str: for k in list(d.keys()): if d[k] is None: del d[k] - rep = str(self.__class__.__name__) + '(' - rep = rep + ', '.join(['{}={}'.format(k, repr(v)) for k, v in d.items()]) - rep = rep + ')' + rep = str(self.__class__.__name__) + "(" + rep = rep + ", ".join(["{}={}".format(k, repr(v)) for k, v in d.items()]) + rep = rep + ")" return rep - -@dataclass(repr=False) -class Citation: - """A class to hold a citation to document the source of a model. + +def to_jsontypes(citations): + """Convert a Citation, list of citations, or dictionary of citations to a JSON mapping. + + Parameters + ---------- + citations : Citation, List[Citation], Any + the citation(s) to convert + + Returns + ------- + JSON valid object + dictionary, list, or scalar """ - entry_type: str - key: str - fields: CitationFields = field(default_factory=CitationFields) + if isinstance(citations, str): + return citations + elif not isinstance(citations, list) and hasattr(citations, 'to_dict'): + return citations.to_dict() + elif is_dataclass(citations.__class__): + return asdict(citations) + elif isinstance(citations, (list, tuple)): + ret = list() + for obj in citations: + ret.append(to_jsontypes(obj)) + return ret + elif isinstance(citations, dict): + ret = dict() + for key, obj in citations.items(): + ret[key] = to_jsontypes(obj) + return ret + else: + return str(citations) - def __post_init__(self): - if isinstance(self.fields, dict): - self.fields = CitationFields(**self.fields) - elif isinstance(self.fields, list): - self.fields = CitationFields(*self.fields) +def from_jsontypes(citations): + """Convert a JSON mapping or list of mappings to a Citation structure. - def to_dict(self): - """Convert to a dictionary. + Parameters + ---------- + citations : dict, list[dict] + a dictionary or list of dictionaries to convert to Citation objects or leave as strings. - Returns - ------- - dict - the citation dictionary - """ + Returns + ------- + Any + the converted objects + """ + if isinstance(citations, list): + ret = list() + for obj in citations: + ret.append(from_jsontypes(obj)) + return ret + elif isinstance(citations, dict): try: - ret = dict() - ret['entry_type'] = self.entry_type - ret['key'] = self.key - ret['fields'] = self.fields.to_dict() - return ret + ret = Citation(**citations) except: - return asdict(self) + ret = dict() + for key, obj in citations.items(): + ret[key] = from_jsontypes(citations) + return ret + elif isinstance(citations, str): + return ret From b19122e7eb17ec1a5ead0e7fda89230949a550c9 Mon Sep 17 00:00:00 2001 From: dbhart Date: Tue, 12 Sep 2023 15:17:24 -0600 Subject: [PATCH 17/75] Documentation updates --- documentation/apidoc/wntr.utils.citations.rst | 7 +++++++ documentation/apidoc/wntr.utils.rst | 2 +- documentation/conf.py | 1 + 3 files changed, 9 insertions(+), 1 deletion(-) create mode 100644 documentation/apidoc/wntr.utils.citations.rst diff --git a/documentation/apidoc/wntr.utils.citations.rst b/documentation/apidoc/wntr.utils.citations.rst new file mode 100644 index 000000000..c7de4e437 --- /dev/null +++ b/documentation/apidoc/wntr.utils.citations.rst @@ -0,0 +1,7 @@ +wntr.utils.citations module +=========================== + +.. automodule:: wntr.utils.citations + :members: + :no-undoc-members: + :show-inheritance: diff --git a/documentation/apidoc/wntr.utils.rst b/documentation/apidoc/wntr.utils.rst index f613c8e99..64da68587 100644 --- a/documentation/apidoc/wntr.utils.rst +++ b/documentation/apidoc/wntr.utils.rst @@ -14,4 +14,4 @@ Submodules wntr.utils.logger wntr.utils.ordered_set - + wntr.utils.citations diff --git a/documentation/conf.py b/documentation/conf.py index 38819bec8..7e7097856 100644 --- a/documentation/conf.py +++ b/documentation/conf.py @@ -106,6 +106,7 @@ # If true, '()' will be appended to :func: etc. cross-reference text. #add_function_parentheses = True +autodoc_type_aliases = {'Literal': 'Literal', 'Name':'Name', 'NameList':'NameList', 'LiteralList':'LiteralList', 'Key':'Key', 'KeyList':'KeyList','Verbatim': 'Verbatim', 'URI': 'URI', 'Date':'Date', 'Range':'Range', 'SeparatedValues':'SeparatedValues'} # If true, the current module name will be prepended to all description # unit titles (such as .. function::). From d4c31b54f181c8ee089fa7548eb11a69cd9a8e36 Mon Sep 17 00:00:00 2001 From: dbhart Date: Tue, 12 Sep 2023 15:40:27 -0600 Subject: [PATCH 18/75] Update to add basic citation class --- documentation/apidoc/wntr.utils.citations.rst | 7 + documentation/apidoc/wntr.utils.rst | 3 +- wntr/network/io.py | 5 + wntr/network/model.py | 4 + wntr/utils/citations.py | 337 ++++++++++++++++++ 5 files changed, 355 insertions(+), 1 deletion(-) create mode 100644 documentation/apidoc/wntr.utils.citations.rst create mode 100644 wntr/utils/citations.py diff --git a/documentation/apidoc/wntr.utils.citations.rst b/documentation/apidoc/wntr.utils.citations.rst new file mode 100644 index 000000000..c7de4e437 --- /dev/null +++ b/documentation/apidoc/wntr.utils.citations.rst @@ -0,0 +1,7 @@ +wntr.utils.citations module +=========================== + +.. automodule:: wntr.utils.citations + :members: + :no-undoc-members: + :show-inheritance: diff --git a/documentation/apidoc/wntr.utils.rst b/documentation/apidoc/wntr.utils.rst index f613c8e99..e4f3145d6 100644 --- a/documentation/apidoc/wntr.utils.rst +++ b/documentation/apidoc/wntr.utils.rst @@ -12,6 +12,7 @@ Submodules .. toctree:: + wntr.utils.citations wntr.utils.logger wntr.utils.ordered_set - + wntr.utils.citations diff --git a/wntr/network/io.py b/wntr/network/io.py index b8d009937..684388037 100644 --- a/wntr/network/io.py +++ b/wntr/network/io.py @@ -31,6 +31,7 @@ import wntr.epanet from wntr.epanet.util import FlowUnits import wntr.network.model +import wntr.utils.citations from wntr.gis.network import WaterNetworkGIS try: import geopandas as gpd @@ -69,6 +70,7 @@ def to_dict(wn) -> dict: version="wntr-{}".format(__version__), comment="WaterNetworkModel - all values given in SI units", name=wn.name, + citations=wntr.utils.citations.to_jsontypes(wn.citations), options=wn._options.to_dict(), curves=wn._curve_reg.to_list(), patterns=wn._pattern_reg.to_list(), @@ -103,6 +105,7 @@ def from_dict(d: dict, append=None): "version", "comment", "name", + "citations", "options", "curves", "patterns", @@ -120,6 +123,8 @@ def from_dict(d: dict, append=None): wn = append if "name" in d: wn.name = d["name"] + if "citations" in d: + wn.citations = wntr.utils.citations.from_jsontypes(d["citations"]) if "options" in d: wn.options.__init__(**d["options"]) if "curves" in d: diff --git a/wntr/network/model.py b/wntr/network/model.py index 938da1421..3c235e797 100644 --- a/wntr/network/model.py +++ b/wntr/network/model.py @@ -16,6 +16,7 @@ """ import logging from collections import OrderedDict +from typing import List, Union from warnings import warn import networkx as nx @@ -24,6 +25,7 @@ import six import wntr.epanet import wntr.network.io +from wntr.utils.citations import Citation from wntr.utils.ordered_set import OrderedSet from .base import AbstractModel, Link, LinkStatus, Registry @@ -71,6 +73,8 @@ def __init__(self, inp_file_name=None): # Network name self.name = None + self.citations: Union[str,Citation, List[Union[str,Citation]]] = list() + """A list of citations that document the source of this model. See also :class:`~wntr.utils.citations.Citation`.""" self._options = Options() self._node_reg = NodeRegistry(self) diff --git a/wntr/utils/citations.py b/wntr/utils/citations.py new file mode 100644 index 000000000..db0cba886 --- /dev/null +++ b/wntr/utils/citations.py @@ -0,0 +1,337 @@ +# coding: utf-8 +"""Contains a dataclass that can be used to store citations. +""" +from __future__ import annotations +import dataclasses + +import datetime +from dataclasses import asdict, dataclass, field, is_dataclass +from typing import Any, Dict, Union, List, Tuple + +Literal = str +"""A literal string""" +Name = str +"""A name string, preferrably in order without commas""" +NameList = Union[Name, List[Name]] +"""A list of names, or a string with "and" between names""" +LiteralList = Union[Literal, List[Literal]] +"""A list of literals, or a string with "and" between literals""" +Key = str +"""A string that comes from a limited set of values""" +KeyList = Union[Key, List[Key]] +"""A list of keys, or a string with "and" between keys""" +Verbatim = str +"""A string that should not be interpreted (ie raw)""" +Special = Any +"""Anything that isn't a string or list of strings""" +URI = str +"""A valid URI""" +Date = Union[str, datetime.date] +"""A date or string in yyyy-mm-dd format (must be 0-padded, eg 2021-02-02 for February 2, 2021""" +Range = Union[str, Tuple[Any, Any]] +"""A 2-tuple of (start,stop) or a string with two values separated by '--' """ +SeparatedValues = Union[str, List[str]] +"""A list of strings, or a string that is delimited (the delimiter is not specified)""" + + +@dataclass(repr=False) +class Citation: + """A class to hold a citation to document the source of a model. + + Parameters + ---------- + entry_type : str + Describe the type of citation, for example, 'journal' or 'book'. + key : str + A key to use to identify this citation. Usually a BibTeX key or an + alphanumeric key per citation standards. + fields : CitationFields + An object that has attributes that align with different citation + fields, such as 'title' or 'author'. + """ + + entry_type: str + key: str + fields: "CitationFields" = None + + def __post_init__(self): + if self.fields is None: + self.fields = CitationFields(None) + elif isinstance(self.fields, dict): + self.fields = CitationFields(**self.fields) + elif isinstance(self.fields, list): + self.fields = CitationFields(*self.fields) + + def to_dict(self): + """Convert to a dictionary. + + Returns + ------- + dict + the citation dictionary + """ + try: + ret = dict() + ret["entry_type"] = self.entry_type + ret["key"] = self.key + ret["fields"] = self.fields.to_dict() + return ret + except: + return asdict(self) + + +@dataclass(repr=False) +class CitationFields: + """A dataclass for citation fields; field names and types are taken from BibLaTeX. + This class makes no attempt to format or represent the citation in any form + other than as a dictionary. This class also does not perform any type-checking + on fields, although it does create ``TypeAlias`` es for each field for the + user's information. Please see the BibLaTeX or BibTeX documentation for a list of + valid field names. + """ + + title: Literal = None + """Title of the work, required for most bibliographies.""" + author: NameList = None + """The author of a work. Typically, either `author` or `editor` is required.""" + editor: NameList = None + """The editor of a work. Typically, either `author` or `editor` is required.""" + date: Date = None + """The date the work was published. Typically, either `year` or `date` is required""" + year: Literal = None + """The year the work was published. Typically, either `year` or `date` is required.""" + journal: Literal = None + """The journal an articles was published in. Both `journal` and `journaltitle` are accepted as field names.""" + journaltitle: Literal = None + """The journal an articles was published in. Both `journal` and `journaltitle` are accepted as field names.""" + doi: Verbatim = None + """The DOI identifier. Most works, and nearly all journal articles, have a DOI.""" + type: Key = None + """The (sub)type of an :attr:`Citation.entry_type`. For example, "masters" for a masters thesis.""" + + volume: int = None + """The volume for a journal or multi-volume set. Use `volumes` to list the total number of volumes in a set.""" + number: Literal = None + """The journal number within a volume, or a report number.""" + pages: Range = None + """The pages for the work.""" + eid: Literal = None + """The electronic identifier number, has replaced pages in some digital journals.""" + issue: Literal = None + """The issue if the issue is not a number, for example, 'Spring'""" + series: Literal = None + """The series name, such as 'Chemical Reviews'""" + part: Literal = None + """The part, usually for reports or multi-volume sets.""" + + eprint: Verbatim = None + """Used for alternatives to DOI, such as PubMed PMIDs. The `eprintclass` and `eprinttype` fields identify the type of ID.""" + eprintclass: Literal = None + eprinttype: Literal = None + url: URI = None + """A URL for access to a dataset or work. Use `urldate` to indicate when the URL was accessed.""" + urldate: Date = None + """The date a `url` was accessed.""" + + issuetitle: Literal = None + booktitle: Literal = None + eventtitle: Literal = None + maintitle: Literal = None + """The `maintitle`, `booktitle`, `eventtitle`, and `issuetitle` are used for containing works, such as for works within proceedings.""" + + eventdate: Date = None + + institution: LiteralList = None + organization: LiteralList = None + publisher: LiteralList = None + school: LiteralList = None + + location: LiteralList = None + address: LiteralList = None + venue: Literal = None + + abstract: Literal = None + addendum: Literal = None + afterword: NameList = None + annotation: Literal = None + annotator: NameList = None + authortype: Key = None + bookauthor: NameList = None + bookpagination: Key = None + chapter: Literal = None + commentator: NameList = None + edition: Union[int, Literal] = None + editora: NameList = None + editorb: NameList = None + editorc: NameList = None + editortype: Key = None + editoratype: Key = None + editorbtype: Key = None + editorctype: Key = None + entrysubtype: Literal = None + file: Verbatim = None + foreword: NameList = None + holder: NameList = None + howpublished: Literal = None + introduction: NameList = None + isan: Literal = None + isbn: Literal = None + ismn: Literal = None + isrn: Literal = None + issn: Literal = None + iswc: Literal = None + # Titles + eventtitleaddon: Literal = None + subtitle: Literal = None + titleaddon: Literal = None + journalsubtitle: Literal = None + journaltitleaddon: Literal = None + issuesubtitle: Literal = None + issuetitleaddon: Literal = None + booksubtitle: Literal = None + booktitleaddon: Literal = None + mainsubtitle: Literal = None + maintitleaddon: Literal = None + origtitle: Literal = None + reprinttitle: Literal = None + shorttitle: Literal = None + shortjournal: Literal = None + indextitle: Literal = None + indexsorttitle: Literal = None + sorttitle: Literal = None + # Continued + label: Literal = None + language: KeyList = None + library: Literal = None + month: Literal = None + nameaddon: Literal = None + note: Literal = None + origdate: Date = None + origlanguage: KeyList = None + origlocation: LiteralList = None + origpublisher: LiteralList = None + pagetotal: Literal = None + pagination: Key = None + pubstate: Key = None + shortauthor: NameList = None + shorteditor: NameList = None + shorthand: Literal = None + shorthandintro: Literal = None + shortseries: Literal = None + translator: NameList = None + version: Literal = None + volumes: int = None + # SPECIAL FIELDS + crossref: Key = None + entryset: SeparatedValues = None + execute: Special = None + gender: Key = None + langid: Key = None + langidopts: Special = None + ids: SeparatedValues = None + keywords: SeparatedValues = None + options: Special = None + presort: Special = None + related: SeparatedValues = None + relatedoptions: SeparatedValues = None + relatedtype: Special = None + relatedstring: Literal = None + sortkey: Literal = None + sortname: NameList = None + sortshorthand: Literal = None + sortyear: int = None + xdata: SeparatedValues = None + xref: Key = None + # FIELD ALIASES + annote: Literal = None + archiveprefix: Literal = None + pdf: Verbatim = None + primaryclass: Literal = None + + def to_dict(self) -> Dict[str, Any]: + """Return a dictionary representation of the citation. + All blank (None) values will be removed from the dictionary + so that it is minimal. + + Returns + ------- + Dict[str, Any] + minimal dictionary representation of the Citation + """ + d = asdict(self) + for k in list(d.keys()): + if d[k] is None: + del d[k] + return d + + def __repr__(self) -> str: + d = asdict(self) + for k in list(d.keys()): + if d[k] is None: + del d[k] + rep = str(self.__class__.__name__) + "(" + rep = rep + ", ".join(["{}={}".format(k, repr(v)) for k, v in d.items()]) + rep = rep + ")" + return rep + + +def to_jsontypes(citations): + """Convert a Citation, list of citations, or dictionary of citations to a JSON mapping. + + Parameters + ---------- + citations : Citation, List[Citation], Any + the citation(s) to convert + + Returns + ------- + JSON valid object + dictionary, list, or scalar + """ + if isinstance(citations, str): + return citations + elif not isinstance(citations, list) and hasattr(citations, 'to_dict'): + return citations.to_dict() + elif is_dataclass(citations.__class__): + return asdict(citations) + elif isinstance(citations, (list, tuple)): + ret = list() + for obj in citations: + ret.append(to_jsontypes(obj)) + return ret + elif isinstance(citations, dict): + ret = dict() + for key, obj in citations.items(): + ret[key] = to_jsontypes(obj) + return ret + else: + return str(citations) + +def from_jsontypes(citations): + """Convert a JSON mapping or list of mappings to a Citation structure. + + Parameters + ---------- + citations : dict, list[dict] + a dictionary or list of dictionaries to convert to Citation objects or leave as strings. + + Returns + ------- + Any + the converted objects + """ + if isinstance(citations, list): + ret = list() + for obj in citations: + ret.append(from_jsontypes(obj)) + return ret + elif isinstance(citations, dict): + try: + ret = Citation(**citations) + except: + ret = dict() + for key, obj in citations.items(): + ret[key] = from_jsontypes(citations) + return ret + elif isinstance(citations, str): + return ret From a2b0c4f64d0078bea2d8b87c6487ad8f59e77a67 Mon Sep 17 00:00:00 2001 From: dbhart Date: Tue, 12 Sep 2023 15:51:03 -0600 Subject: [PATCH 19/75] Getting rid of merge conflict --- wntr/network/io.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/wntr/network/io.py b/wntr/network/io.py index 82ced0108..684388037 100644 --- a/wntr/network/io.py +++ b/wntr/network/io.py @@ -31,6 +31,7 @@ import wntr.epanet from wntr.epanet.util import FlowUnits import wntr.network.model +import wntr.utils.citations from wntr.gis.network import WaterNetworkGIS try: import geopandas as gpd @@ -69,7 +70,7 @@ def to_dict(wn) -> dict: version="wntr-{}".format(__version__), comment="WaterNetworkModel - all values given in SI units", name=wn.name, - citations=wntr.utils.citations.to_dict(wn.citations), + citations=wntr.utils.citations.to_jsontypes(wn.citations), options=wn._options.to_dict(), curves=wn._curve_reg.to_list(), patterns=wn._pattern_reg.to_list(), @@ -122,6 +123,8 @@ def from_dict(d: dict, append=None): wn = append if "name" in d: wn.name = d["name"] + if "citations" in d: + wn.citations = wntr.utils.citations.from_jsontypes(d["citations"]) if "options" in d: wn.options.__init__(**d["options"]) if "curves" in d: From 60af118f6016c728e62216d9ec2c3a5e83536df2 Mon Sep 17 00:00:00 2001 From: David Hart Date: Sat, 16 Sep 2023 13:18:48 -0600 Subject: [PATCH 20/75] Exceptions (#133) * Update to exception documentation * Update documentation for EN errors --- .../apidoc/wntr.epanet.exceptions.rst | 7 + documentation/apidoc/wntr.epanet.rst | 1 + wntr/epanet/__init__.py | 2 +- wntr/epanet/exceptions.py | 153 +++++++++++++++++- 4 files changed, 159 insertions(+), 4 deletions(-) create mode 100644 documentation/apidoc/wntr.epanet.exceptions.rst diff --git a/documentation/apidoc/wntr.epanet.exceptions.rst b/documentation/apidoc/wntr.epanet.exceptions.rst new file mode 100644 index 000000000..6cb9d9029 --- /dev/null +++ b/documentation/apidoc/wntr.epanet.exceptions.rst @@ -0,0 +1,7 @@ +wntr.epanet.exceptions module +============================= + +.. automodule:: wntr.epanet.exceptions + :members: + :no-undoc-members: + :show-inheritance: diff --git a/documentation/apidoc/wntr.epanet.rst b/documentation/apidoc/wntr.epanet.rst index 613df4e41..1af96c98b 100644 --- a/documentation/apidoc/wntr.epanet.rst +++ b/documentation/apidoc/wntr.epanet.rst @@ -12,6 +12,7 @@ Submodules .. toctree:: + wntr.epanet.exceptions wntr.epanet.io wntr.epanet.toolkit wntr.epanet.util diff --git a/wntr/epanet/__init__.py b/wntr/epanet/__init__.py index 272572d1c..de5a4f410 100644 --- a/wntr/epanet/__init__.py +++ b/wntr/epanet/__init__.py @@ -4,4 +4,4 @@ from .io import InpFile #, BinFile, HydFile, RptFile from .util import FlowUnits, MassUnits, HydParam, QualParam, EN import wntr.epanet.toolkit - +import wntr.epanet.exceptions diff --git a/wntr/epanet/exceptions.py b/wntr/epanet/exceptions.py index 6672cc95e..0cc6dbc01 100644 --- a/wntr/epanet/exceptions.py +++ b/wntr/epanet/exceptions.py @@ -1,3 +1,6 @@ +# coding: utf-8 +"""Exceptions for EPANET toolkit and IO operations.""" + from enum import IntEnum from typing import List @@ -79,84 +82,181 @@ 308: "cannot save results to binary file %s", 309: "cannot save results to report file %s", } +"""A dictionary of the error codes and their meanings from the EPANET toolkit. +See :class:`EpanetErrors` for the documentation of each code number. + +:meta hide-value: +""" -class EpanetErrors(IntEnum): +class EpanetErrorEnum(IntEnum): + """A list of short phrases that can be used in place of the error code numbers.""" + warn_unbalanced = 1 + """system hydraulically unbalanced - convergence to a hydraulic solution was not achieved in the allowed number of trials""" + warn_unstable = 2 + """system may be hydraulically unstable - hydraulic convergence was only achieved after the status of all links was held fixed""" + warn_disconnected = 3 + """system disconnected - one or more nodes with positive demands were disconnected for all supply sources""" + warn_pumps = 4 + """pumps cannot deliver enough flow or head - one or more pumps were forced to either shut down (due to insufficient head) or operate beyond the maximum rated flow""" + warn_valves = 5 + """vavles cannot deliver enough flow - one or more flow control valves could not deliver the required flow even when fully open""" + warn_pressures = 6 + """system has negative pressures - negative pressures occurred at one or more junctions with positive demand""" insufficient_memory = 101 + """insufficient memory available""" no_network = 102 + """no network data available""" no_init_hyd = 103 + """hydraulics not initialized""" no_hydraulics = 104 + """no hydraulics for water quality analysis""" no_init_qual = 105 + """water quality not initialized""" no_results = 106 + """no results saved to report on""" hyd_file = 107 + """hydraulics supplied from external file""" hyd_init_and_hyd_file = 108 + """cannot use external file while hydraulics solver is active""" modify_time_during_solve = 109 + """cannot change time parameter when solver is active""" solve_hyd_fail = 110 + """cannot solve network hydraulic equations""" solve_qual_fail = 120 + """cannot solve water quality transport equations""" input_file_error = 200 + """one or more errors in input file""" syntax_error = 201 + """syntax error""" illegal_numeric_value = 202 + """illegal numeric value""" undefined_node = 203 + """undefined node""" undefined_link = 204 + """undefined link""" undefined_pattern = 205 + """undefined time pattern""" undefined_curve = 206 + """undefined curve""" control_on_cv_gpv = 207 + """attempt to control a CV/GPV link""" illegal_pda_limits = 208 + """illegal PDA pressure limits""" illegal_node_property = 209 + """illegal node property value""" illegal_link_property = 211 + """illegal link property value""" undefined_trace_node = 212 + """undefined trace node""" invalid_option_value = 213 + """invalid option value""" too_many_chars_inp = 214 + """too many characters in input line""" duplicate_id = 215 + """duplicate ID label""" undefined_pump = 216 + """reference to undefined pump""" invalid_energy_value = 217 + """pump has no head curve or power defined""" illegal_valve_tank = 219 + """illegal valve connection to tank node""" illegal_tank_valve = 219 + """illegal valve connection to tank node""" illegal_valve_valve = 220 + """illegal valve connection to another valve""" misplaced_rule = 221 + """misplaced rule clause in rule-based control""" link_to_self = 222 + """link assigned same start and end nodes""" not_enough_nodes = 223 + """not enough nodes in network""" no_tanks_or_res = 224 + """no tanks or reservoirs in network""" invalid_tank_levels = 225 + """invalid lower/upper levels for tank""" missing_pump_data = 226 + """no head curve or power rating for pump""" invalid_head_curve = 227 + """invalid head curve for pump""" nonincreasing_x_curve = 230 + """nonincreasing x-values for curve""" unconnected_node = 233 + """network has unconnected node""" unconnected_node_id = 234 + """network has an unconnected node with ID""" no_such_source_node = 240 + """nonexistent water quality source""" no_such_control = 241 + """nonexistent control""" invalid_name_format = 250 + """invalid format (e.g. too long an ID name)""" invalid_parameter_code = 251 + """invalid parameter code""" invalid_id_name = 252 + """invalid ID name""" no_such_demand_category = 253 + """nonexistent demand category""" missing_coords = 254 + """node with no coordinates""" invalid_vertex = 255 + """invalid link vertex""" no_such_rule = 257 + """nonexistent rule""" no_such_rule_clause = 258 + """nonexistent rule clause""" delete_node_still_linked = 259 + """attempt to delete a node that still has links connected to it""" delete_node_is_trace = 260 + """attempt to delete node assigned as a Trace Node""" delete_node_in_control = 261 + """attempt to delete a node or link contained in a control""" modify_network_during_solve = 262 + """attempt to modify network structure while a solver is open""" node_not_a_tank = 263 + """node is not a tank""" same_file_names = 301 + """identical file names used for different types of files""" open_inp_fail = 302 + """cannot open input file""" open_rpt_fail = 303 + """cannot open report file""" open_bin_fail = 304 + """cannot open binary output file""" open_hyd_fail = 305 + """cannot open hydraulics file""" hyd_file_different_network = 306 + """hydraulics file does not match network data""" read_hyd_fail = 307 + """cannot read hydraulics file""" save_bin_fail = 308 + """cannot save results to binary file""" save_rpt_fail = 309 + """cannot save results to report file""" class EpanetException(Exception): def __init__(self, code: int, *args: List[object], line_num=None, line=None) -> None: - if isinstance(code, EpanetErrors): + """An Exception class for EPANET Toolkit and IO exceptions. + + Parameters + ---------- + code : int or str or EpanetErrors + The EPANET error code (int) or a string mapping to the EpanetErrors enum members + args : additional non-keyword arguments, optional + If there is a string-format within the error code's text, these will be used to + replace the format, otherwise they will be output at the end of the Exception message. + line_num : int, optional + The line number, if reading an INP file, by default None + line : str, optional + The contents of the line, by default None + """ + if isinstance(code, EpanetErrorEnum): code = int(code) elif isinstance(code, str): try: code = code.strip().replace('-','_').replace(' ','_') - code = int(EpanetErrors[code]) + code = int(EpanetErrorEnum[code]) except KeyError: return super().__init__('unknown error code: {}'.format(repr(code)), *args) elif not isinstance(code, int): @@ -177,12 +277,59 @@ def __init__(self, code: int, *args: List[object], line_num=None, line=None) -> class ENSyntaxError(EpanetException, SyntaxError): def __init__(self, code, *args, line_num=None, line=None) -> None: + """An EPANET exception class that also subclasses SyntaxError + + Parameters + ---------- + code : int or str or EpanetErrors + The EPANET error code (int) or a string mapping to the EpanetErrors enum members + args : additional non-keyword arguments, optional + If there is a string-format within the error code's text, these will be used to + replace the format, otherwise they will be output at the end of the Exception message. + line_num : int, optional + The line number, if reading an INP file, by default None + line : str, optional + The contents of the line, by default None + """ super().__init__(code, *args, line_num=line_num, line=line) class ENKeyError(EpanetException, KeyError): def __init__(self, code, name, *args, line_num=None, line=None) -> None: + """An EPANET exception class that also subclasses KeyError. + + Parameters + ---------- + code : int or str or EpanetErrors + The EPANET error code (int) or a string mapping to the EpanetErrors enum members + name : str + The key/name/id that is missing + args : additional non-keyword arguments, optional + If there is a string-format within the error code's text, these will be used to + replace the format, otherwise they will be output at the end of the Exception message. + line_num : int, optional + The line number, if reading an INP file, by default None + line : str, optional + The contents of the line, by default None + """ + super().__init__(code, name, *args, line_num=line_num, line=line) class ENValueError(EpanetException, ValueError): def __init__(self, code, value, *args, line_num=None, line=None) -> None: + """An EPANET exception class that also subclasses ValueError + + Parameters + ---------- + code : int or str or EpanetErrors + The EPANET error code (int) or a string mapping to the EpanetErrors enum members + value : Any + The value that is invalid + args : additional non-keyword arguments, optional + If there is a string-format within the error code's text, these will be used to + replace the format, otherwise they will be output at the end of the Exception message. + line_num : int, optional + The line number, if reading an INP file, by default None + line : str, optional + The contents of the line, by default None + """ super().__init__(code, value, *args, line_num=line_num, line=line) From 5e976856adc8e70b76692828f658b195aa8bea9c Mon Sep 17 00:00:00 2001 From: David Hart Date: Sat, 16 Sep 2023 13:28:16 -0600 Subject: [PATCH 21/75] Update to sphinx config (#134) From 74b1a0506a132329a0b2c4073200f616e48b8105 Mon Sep 17 00:00:00 2001 From: dbhart Date: Sat, 16 Sep 2023 13:28:33 -0600 Subject: [PATCH 22/75] Updates to toolkit --- wntr/reaction/exceptions.py | 189 +++++++++++++++++++++++++ wntr/reaction/io.py | 190 ++++++++++++++----------- wntr/reaction/library.py | 274 ++++++++++++++++++------------------ wntr/reaction/toolkitmsx.py | 154 ++++---------------- 4 files changed, 468 insertions(+), 339 deletions(-) create mode 100644 wntr/reaction/exceptions.py diff --git a/wntr/reaction/exceptions.py b/wntr/reaction/exceptions.py new file mode 100644 index 000000000..bffb41070 --- /dev/null +++ b/wntr/reaction/exceptions.py @@ -0,0 +1,189 @@ +# coding: utf-8 +"""EPANET-MSX error and exception classes.""" + +from enum import IntEnum +from typing import List +from ..epanet.exceptions import EpanetException, EN_ERROR_CODES, EpanetErrorEnum + + +MSX_ERROR_CODES = EN_ERROR_CODES.copy() +MSX_ERROR_CODES.update({ + # MSX syntax errors + 401: "too many characters", + 402: "too few input items", + 403: "invalid keyword: '%s'", + 404: "invalid numeric value: '%s'", + 405: "reference to undefined object: '%s'", + 406: "illegal use of reserved name: '%s'", + 407: "name already used by another object: '%s'", + 408: "species already assigned an expression: '%s'", + 409: "illegal math expression", + 410: "option no longer supported", + 411: "term '%s' contains a cyclic reference", + # MSX runtime errors + 501: "insufficient memory available", + 502: "no EPANET data file supplied", + 503: "could not open MSX input file", + 504: "could not open hydraulic results file", + 505: "could not read hydraulic results file", + 506: "could not read MSX input file", + 507: "too few pipe reaction expressions", + 508: "too few tank reaction expressions", + 509: "could not open differential equation solver", + 510: "could not open algebraic equation solver", + 511: "could not open binary results file", + 512: "read/write error on binary results file", + 513: "could not integrate reaction rate expressions", + 514: "could not solve reaction equilibrium expressions", + 515: "reference made to an unknown type of object", + 516: "reference made to an illegal object index", + 517: "reference made to an undefined object ID", + 518: "invalid property values were specified", + 519: "an MSX project was not opened", + 520: "an MSX project is already opened", + 522: "could not compile chemistry functions", + 523: "could not load functions from compiled chemistry file", + 524: "illegal math operation", +}) + +class MSXErrors(IntEnum): + too_many_chars_msx = 401 + too_few_items = 402 + invalid_keyword = 403 + invalid_numeric_value_msx = 404 + undefined_msx_object = 405 + illegal_reserved_name = 406 + name_in_use = 407 + species_already_assigned = 408 + illegal_math_expression = 409 + option_deprecated = 410 + cyclic_reference = 411 + insufficient_memory_msx = 501 + no_epanet_datafile = 502 + open_msx_fail = 503 + open_hyd_fail_msx = 504 + read_hyd_fail_msx = 505 + read_msx_fail = 506 + not_enough_pipe_reactions = 507 + not_enough_tank_reactions = 508 + open_de_solver_fail = 509 + open_ae_solver_fail = 510 + open_bin_fail_msx = 511 + io_error_msx_bin = 512 + solve_rate_failed = 513 + solve_equil_failed = 514 + unknown_object_type = 515 + illegal_object_index = 516 + undefined_object_id = 517 + invalid_property_value = 518 + msx_project_not_open = 519 + msx_project_open = 520 + compile_chem_failed = 522 + load_compiled_chem_failed = 523 + illegal_math_operation = 524 + insufficient_memory = 101 + no_network = 102 + no_init_hyd = 103 + no_hydraulics = 104 + no_init_qual = 105 + no_results = 106 + hyd_file = 107 + hyd_init_and_hyd_file = 108 + modify_time_during_solve = 109 + solve_hyd_fail = 110 + solve_qual_fail = 120 + input_file_error = 200 + syntax_error = 201 + illegal_numeric_value = 202 + undefined_node = 203 + undefined_link = 204 + undefined_pattern = 205 + undefined_curve = 206 + control_on_cv_gpv = 207 + illegal_pda_limits = 208 + illegal_node_property = 209 + illegal_link_property = 211 + undefined_trace_node = 212 + invalid_option_value = 213 + too_many_chars_inp = 214 + duplicate_id = 215 + undefined_pump = 216 + invalid_energy_value = 217 + illegal_valve_tank = 219 + illegal_tank_valve = 219 + illegal_valve_valve = 220 + misplaced_rule = 221 + link_to_self = 222 + not_enough_nodes = 223 + no_tanks_or_res = 224 + invalid_tank_levels = 225 + missing_pump_data = 226 + invalid_head_curve = 227 + nonincreasing_x_curve = 230 + unconnected_node = 233 + unconnected_node_id = 234 + no_such_source_node = 240 + no_such_control = 241 + invalid_name_format = 250 + invalid_parameter_code = 251 + invalid_id_name = 252 + no_such_demand_category = 253 + missing_coords = 254 + invalid_vertex = 255 + no_such_rule = 257 + no_such_rule_clause = 258 + delete_node_still_linked = 259 + delete_node_is_trace = 260 + delete_node_in_control = 261 + modify_network_during_solve = 262 + node_not_a_tank = 263 + same_file_names = 301 + open_inp_fail = 302 + open_rpt_fail = 303 + open_bin_fail = 304 + open_hyd_fail = 305 + hyd_file_different_network = 306 + read_hyd_fail = 307 + save_bin_fail = 308 + save_rpt_fail = 309 + +class EpanetMsxException(EpanetException): + def __init__(self, code: int, *args: List[object], line_num=None, line=None) -> None: + if isinstance(code, (EpanetErrorEnum, MSXErrors)): + code = int(code) + elif isinstance(code, str): + try: + code = code.strip().replace('-','_').replace(' ','_') + code = int(MSXErrors[code]) + except KeyError: + return super(Exception, self).__init__('unknown error code: {}'.format(repr(code)), *args) + elif not isinstance(code, int): + return super(Exception, self).__init__('unknown error code: {}'.format(repr(code)), *args) + msg = MSX_ERROR_CODES.get(code, 'unknown error') + if args is not None: + args = [*args] + if r'%' in msg and len(args) > 0: + msg = msg % args.pop(0) + if len(args) > 0: + msg = msg + ' ' + str(args) + if line_num: + msg = msg + ", at line {}".format(line_num) + if line: + msg = msg + ':\n ' + str(line) + msg = '(Error {}) '.format(code) + msg + super(Exception, self).__init__(msg) + +class MSXSyntaxError(EpanetMsxException, SyntaxError): + def __init__(self, code, *args) -> None: + + super().__init__(code, *args) + +class MSXNameError(EpanetMsxException, NameError): + def __init__(self, code, name, *args) -> None: + + super().__init__(code, name, *args) + +class MSXValueError(EpanetMsxException, ValueError): + def __init__(self, code, name, *args) -> None: + + super().__init__(code, name, *args) diff --git a/wntr/reaction/io.py b/wntr/reaction/io.py index 8844321aa..64ad7b217 100644 --- a/wntr/reaction/io.py +++ b/wntr/reaction/io.py @@ -8,12 +8,12 @@ from wntr.network.elements import Source from wntr.reaction.base import MSXComment, RxnLocationType, RxnVariableType from wntr.reaction.model import WaterQualityReactionsModel +from .exceptions import EpanetMsxException from wntr.reaction.variables import Parameter, Species from wntr.utils.citations import Citation sys_default_enc = sys.getdefaultencoding() - logger = logging.getLogger(__name__) _INP_SECTIONS = [ @@ -87,64 +87,69 @@ def read(self, msx_file, rxn_model=None): for sec in _INP_SECTIONS: self.sections[sec] = [] - section = None - lnum = 0 - edata = {"fname": msx_file} - with open(msx_file, "r", encoding=sys_default_enc) as f: - for line in f: - lnum += 1 - edata["lnum"] = lnum - line = line.strip() - nwords = len(line.split()) - if len(line) == 0 or nwords == 0: - # Blank line - continue - elif line.startswith("["): - vals = line.split(None, 1) - sec = vals[0].upper() - # Add handlers to deal with extra 'S'es (or missing 'S'es) in INP file - if sec not in _INP_SECTIONS: - trsec = sec.replace("]", "S]") - if trsec in _INP_SECTIONS: - sec = trsec - if sec not in _INP_SECTIONS: - trsec = sec.replace("S]", "]") - if trsec in _INP_SECTIONS: - sec = trsec - edata["sec"] = sec - if sec in _INP_SECTIONS: - section = sec - # logger.info('%(fname)s:%(lnum)-6d %(sec)13s section found' % edata) + def _read(): + section = None + lnum = 0 + edata = {"fname": msx_file} + with open(msx_file, "r", encoding=sys_default_enc) as f: + for line in f: + lnum += 1 + edata["lnum"] = lnum + line = line.strip() + nwords = len(line.split()) + if len(line) == 0 or nwords == 0: + # Blank line continue - elif sec == "[END]": - # logger.info('%(fname)s:%(lnum)-6d %(sec)13s end of file found' % edata) - section = None - break - else: - raise RuntimeError('%(fname)s:%(lnum)d: Invalid section "%(sec)s"' % edata) - elif section is None and line.startswith(";"): - self.top_comments.append(line[1:]) - continue - elif section is None: - logger.debug("Found confusing line: %s", repr(line)) - raise RuntimeError("%(fname)s:%(lnum)d: Non-comment outside of valid section!" % edata) - # We have text, and we are in a section - self.sections[section].append((lnum, line)) - - self._read_title() - self._read_options() - self._read_species() - self._read_coefficients() - self._read_terms() - self._read_pipes() - self._read_tanks() - self._read_sources() - self._read_quality() - self._read_parameters() - self._read_diffusivity() - self._read_patterns() - self._read_report() - return self.rxn + elif line.startswith("["): + vals = line.split(None, 1) + sec = vals[0].upper() + # Add handlers to deal with extra 'S'es (or missing 'S'es) in INP file + if sec not in _INP_SECTIONS: + trsec = sec.replace("]", "S]") + if trsec in _INP_SECTIONS: + sec = trsec + if sec not in _INP_SECTIONS: + trsec = sec.replace("S]", "]") + if trsec in _INP_SECTIONS: + sec = trsec + edata["sec"] = sec + if sec in _INP_SECTIONS: + section = sec + # logger.info('%(fname)s:%(lnum)-6d %(sec)13s section found' % edata) + continue + elif sec == "[END]": + # logger.info('%(fname)s:%(lnum)-6d %(sec)13s end of file found' % edata) + section = None + break + else: + logger.warning('%(fname)s:%(lnum)d: Invalid section "%(sec)s"' % edata) + raise EpanetMsxException(201, note='at line {}:\n{}'.format(lnum, line)) + elif section is None and line.startswith(";"): + self.top_comments.append(line[1:]) + continue + elif section is None: + logger.debug("Found confusing line: %s", repr(line)) + raise EpanetMsxException(201, note='at line {}:\n{}'.format(lnum, line)) + # We have text, and we are in a section + self.sections[section].append((lnum, line)) + try: + _read() + self._read_title() + self._read_options() + self._read_species() + self._read_coefficients() + self._read_terms() + self._read_pipes() + self._read_tanks() + self._read_sources() + self._read_quality() + self._read_parameters() + self._read_diffusivity() + self._read_patterns() + self._read_report() + return self.rxn + except Exception as e: + raise EpanetMsxException(200) from e def _read_title(self): lines = [] @@ -169,8 +174,8 @@ def _read_options(self): for lnum, line in self.sections["[OPTIONS]"]: vals, comment = _split_line(line) try: - if len(vals) != 2: - raise SyntaxError("Invalid [OPTIONS] entry") + if len(vals) < 2: + raise EpanetMsxException(402, note="at line {} of [OPTIONS] section:\n{}".format(lnum, line)) name, val = vals[0].upper(), vals[1].upper() if name == "AREA_UNITS": self.rxn._options.quality.area_units = val @@ -192,8 +197,14 @@ def _read_options(self): self.rxn._options.quality.segments = int(val) elif name == "PECLET": self.rxn._options.quality.peclet = int(val) + else: + raise EpanetMsxException(403, note='at line {} of [OPTIONS] section:\n{}'.format(lnum, line)) + except ValueError: + raise EpanetMsxException(404, note='at line {} of [OPTIONS] section:\n{}'.format(lnum, line)) + except EpanetMsxException: + raise except Exception as e: - raise RuntimeError('Error on line {} of file "{}": {}'.format(lnum, self.rxn.filename, line)) from e + raise EpanetMsxException(201, note='at line {} of [OPTIONS] section:\n{}'.format(lnum, line)) from e def _read_species(self): lines = [] @@ -207,15 +218,18 @@ def _read_species(self): try: if comment is not None: note.post = comment - if len(vals) not in [3, 5]: - raise SyntaxError("Invalid [SPECIES] entry") - + if len(vals) < 3: + raise EpanetMsxException(402, note='at line {} of [SPECIES] section:\n{}'.format(lnum, line)) if len(vals) == 3: species = self.rxn.add_species(vals[0], vals[1], vals[2], note=note) elif len(vals) == 5: species = self.rxn.add_species(vals[0], vals[1], vals[2], float(vals[3]), float(vals[4]), note=note) + else: + raise EpanetMsxException(201, note='at line {} of [SPECIES] section:\n{}'.format(lnum, line)) + except EpanetMsxException: + raise except Exception as e: - raise RuntimeError('Error on line {} of file "{}": {}'.format(lnum, self.rxn.filename, line)) from e + raise EpanetMsxException(201, note='at line {} of [SPECIES] section:\n{}'.format(lnum, line)) from e else: note = MSXComment() @@ -231,11 +245,13 @@ def _read_coefficients(self): try: if comment is not None: note.post = comment - if len(vals) != 3: - raise SyntaxError("Invalid [COEFFICIENTS] entry") + if len(vals) < 3: + raise EpanetMsxException(402, note='at line {} of [COEFFICIENTS] section:\n{}'.format(lnum, line)) coeff = self.rxn.add_coefficient(vals[0], vals[1], float(vals[2]), note=note) + except EpanetMsxException: + raise except Exception as e: - raise RuntimeError('Error on line {} of file "{}": {}'.format(lnum, self.rxn.filename, line)) from e + raise EpanetMsxException(201, note='at line {} of [COEFFICIENTS] section:\n{}'.format(lnum, line)) from e else: note = MSXComment() @@ -254,8 +270,10 @@ def _read_terms(self): if len(vals) < 2: raise SyntaxError("Invalid [TERMS] entry") term = self.rxn.add_other_term(vals[0], " ".join(vals[1:]), note=note) + except EpanetMsxException: + raise except Exception as e: - raise RuntimeError('Error on line {} of file "{}": {}'.format(lnum, self.rxn.filename, line)) from e + raise EpanetMsxException(201, note='at line {} of [TERMS] section:\n{}'.format(lnum, line)) from e else: note = MSXComment() @@ -274,8 +292,10 @@ def _read_pipes(self): if len(vals) < 3: raise SyntaxError("Invalid [PIPES] entry") reaction = self.rxn.add_pipe_reaction(vals[1], vals[0], " ".join(vals[2:]), note=note) + except EpanetMsxException: + raise except Exception as e: - raise RuntimeError('Error on line {} of file "{}": {}'.format(lnum, self.rxn.filename, line)) from e + raise EpanetMsxException(201, note='at line {} of [PIPES] section:\n{}'.format(lnum, line)) from e else: note = MSXComment() @@ -294,8 +314,10 @@ def _read_tanks(self): if len(vals) < 3: raise SyntaxError("Invalid [TANKS] entry") reaction = self.rxn.add_tank_reaction(vals[1], vals[0], " ".join(vals[2:]), note=note) + except EpanetMsxException: + raise except Exception as e: - raise RuntimeError('Error on line {} of file "{}": {}'.format(lnum, self.rxn.filename, line)) from e + raise EpanetMsxException(201, note='at line {} of [TANKS] section:\n{}'.format(lnum, line)) from e else: note = MSXComment() @@ -317,13 +339,15 @@ def _read_sources(self): else: typ, node, spec, strength, pat = vals if not self.rxn.has_variable(spec): - raise ValueError("Undefined species in [QUALITY] section: {}".format(spec)) + raise ValueError("Undefined species in [SOURCES] section: {}".format(spec)) if spec not in self.rxn._sources.keys(): self.rxn._sources[spec] = dict() source = dict(source_type=typ, strength=strength, pattern=pat, note=note) self.rxn._sources[spec][node] = source + except EpanetMsxException: + raise except Exception as e: - raise RuntimeError('Error on line {} of file "{}": {}'.format(lnum, self.rxn.filename, line)) from e + raise EpanetMsxException(201, note='at line {} of [SOURCES] section:\n{}'.format(lnum, line)) from e else: note = MSXComment() @@ -355,8 +379,10 @@ def _read_quality(self): self.rxn._inital_quality[spec]["nodes"][netid] = float(concen) elif cmd[1].lower() == "l": self.rxn._inital_quality[spec]["links"][netid] = float(concen) + except EpanetMsxException: + raise except Exception as e: - raise RuntimeError('Error on line {} of file "{}": {}'.format(lnum, self.rxn.filename, line)) from e + raise EpanetMsxException(201, note='at line {} of [QUALITY] section:\n{}'.format(lnum, line)) from e else: note = MSXComment() @@ -375,16 +401,18 @@ def _read_parameters(self): typ, netid, paramid, value = vals coeff = self.rxn.get_variable(paramid) if not isinstance(coeff, Parameter): - raise RuntimeError("Invalid parameter {}".format(paramid)) + raise ValueError("Invalid parameter {}".format(paramid)) value = float(value) if typ.lower()[0] == "p": coeff.pipe_values[netid] = value elif typ.lower()[0] == "t": coeff.tank_values[netid] = value else: - raise RuntimeError("Invalid parameter type {}".format(typ)) + raise ValueError("Invalid parameter type {}".format(typ)) + except EpanetMsxException: + raise except Exception as e: - raise RuntimeError('Error on line {} of file "{}": {}'.format(lnum, self.rxn.filename, line)) from e + raise EpanetMsxException(201, note='at line {} of [PARAMETERS] section:\n{}'.format(lnum, line)) from e else: note = MSXComment() @@ -406,8 +434,10 @@ def _read_diffusivity(self): if not isinstance(species, Species): raise RuntimeError("Invalid species {} in diffusivity".format(vals[0])) species.diffusivity = float(vals[1]) + except EpanetMsxException: + raise except Exception as e: - raise RuntimeError('Error on line {} of file "{}": {}'.format(lnum, self.rxn.filename, line)) from e + raise EpanetMsxException(201, note='at line {} of [DIFFUSIVITIES] section:\n{}'.format(lnum, line)) from e else: note = MSXComment() @@ -484,8 +514,10 @@ def _read_report(self): self.rxn._options.report.species_precision[vals[1]] = int(vals[3]) else: raise SyntaxError("Invalid syntax in [REPORT] section: unknown first word") + except EpanetMsxException: + raise except Exception as e: - raise RuntimeError('Error on line {} of file "{}": {}'.format(lnum, self.rxn.filename, line)) from e + raise EpanetMsxException(201, note='at line {} of [REPORT] section:\n{}'.format(lnum, line)) from e else: note = MSXComment() diff --git a/wntr/reaction/library.py b/wntr/reaction/library.py index 6409cc017..dcf95b142 100644 --- a/wntr/reaction/library.py +++ b/wntr/reaction/library.py @@ -1,149 +1,149 @@ -# -*- coding: utf-8 -*- -# @Contributors: -# Jonathan Burkhardt, U.S. Environmental Protection Agency, Office of Research and Development +# # -*- coding: utf-8 -*- +# # @Contributors: +# # Jonathan Burkhardt, U.S. Environmental Protection Agency, Office of Research and Development -""" -A library of common reactions. -Values in libarary are for test purposes ONLY. These highlight the reaction form/relationship -but not necessarily the specific system kinetics. Citations are provided where appropriate for -sources of values or models. In most cases updates will be necessary to use for different -models - that is, sources, pipes, nodes are for a given network, and must be updated for different -models. +# """ +# A library of common reactions. +# Values in libarary are for test purposes ONLY. These highlight the reaction form/relationship +# but not necessarily the specific system kinetics. Citations are provided where appropriate for +# sources of values or models. In most cases updates will be necessary to use for different +# models - that is, sources, pipes, nodes are for a given network, and must be updated for different +# models. -.. autosummary:: +# .. autosummary:: - nicotine - nicotine_ri - lead_ppm +# nicotine +# nicotine_ri +# lead_ppm -""" -import logging +# """ +# import logging -from ..utils.citations import Citation -from .model import WaterQualityReactionsModel +# from ..utils.citations import Citation +# from .model import WaterQualityReactionsModel -logger = logging.getLogger(__name__) +# logger = logging.getLogger(__name__) -# ===================== Nicotine-chlorine model -# -nicotine = WaterQualityReactionsModel( - title="Nicotine - Chlorine reaction", - desc="Values in libarary are for test purposes ONLY.", -) -"""A nicotine-chlorine reaction model""" +# # ===================== Nicotine-chlorine model +# # +# nicotine = WaterQualityReactionsModel( +# title="Nicotine - Chlorine reaction", +# desc="Values in libarary are for test purposes ONLY.", +# ) +# """A nicotine-chlorine reaction model""" -nicotine.options.quality.area_units = "M2" -nicotine.options.quality.rate_units = "MIN" -nicotine.options.quality.timestep = 1 -nicotine.add_bulk_species("Nx", units="MG", note="Nicotine") -nicotine.add_bulk_species("HOCL", units="MG", note="Free chlorine") -nicotine.add_constant_coeff("kd", global_value=2.33e-3, units="min^(-1)", note="decay rate") -nicotine.add_constant_coeff("K1", global_value=5.92e-2, units="L * min^(-1) * mg^(-1)", note="decay constant for chlorine as function of mass(Nic)") -nicotine.add_constant_coeff("K2", global_value=1.84e-1, units="L * min^(-1) * mg^(-1)", note="decay constant for nicotine as function of mass(Cl)") -nicotine.add_other_term("RXCL", expression="kd * HOCL + K1 * Nx * HOCL") -nicotine.add_other_term("RXN", expression="K2 * Nx * HOCL") -nicotine.add_pipe_reaction("Nx", "rate", expression="-RXN") -nicotine.add_pipe_reaction("HOCL", "rate", expression="-RXCL") -nicotine.add_tank_reaction("Nx", "rate", "0") -nicotine.add_tank_reaction("HOCL", "rate", "0") +# nicotine.options.quality.area_units = "M2" +# nicotine.options.quality.rate_units = "MIN" +# nicotine.options.quality.timestep = 1 +# nicotine.add_bulk_species("Nx", units="MG", note="Nicotine") +# nicotine.add_bulk_species("HOCL", units="MG", note="Free chlorine") +# nicotine.add_constant_coeff("kd", global_value=2.33e-3, units="min^(-1)", note="decay rate") +# nicotine.add_constant_coeff("K1", global_value=5.92e-2, units="L * min^(-1) * mg^(-1)", note="decay constant for chlorine as function of mass(Nic)") +# nicotine.add_constant_coeff("K2", global_value=1.84e-1, units="L * min^(-1) * mg^(-1)", note="decay constant for nicotine as function of mass(Cl)") +# nicotine.add_other_term("RXCL", expression="kd * HOCL + K1 * Nx * HOCL") +# nicotine.add_other_term("RXN", expression="K2 * Nx * HOCL") +# nicotine.add_pipe_reaction("Nx", "rate", expression="-RXN") +# nicotine.add_pipe_reaction("HOCL", "rate", expression="-RXCL") +# nicotine.add_tank_reaction("Nx", "rate", "0") +# nicotine.add_tank_reaction("HOCL", "rate", "0") -# ===================== Nicotine-chlorine reactive intermediate species -# -nicotine_ri = WaterQualityReactionsModel( - title="Nicotine - Chlorine reaction with reactive intermediate", - desc="Values in libarary are for test purposes ONLY.", -) -"""A nicotine-chlorine reaction with a reactive intermediate""" -# Set the options -nicotine_ri.options.quality.area_units = "M2" -nicotine_ri.options.quality.rate_units = "MIN" -nicotine_ri.options.quality.timestep = 1 -nicotine_ri.options.quality.atol = 1.0e-10 -nicotine_ri.options.quality.rtol = 1.0e-10 -# Add species -nicotine_ri.add_bulk_species("Nx", units="MG", note="Nicotine") -nicotine_ri.add_bulk_species("HOCL", units="MG", note="Free Chlorine") -nicotine_ri.add_bulk_species("NX2", units="MG", note="Intermediate Nicotine Reactive") -# Add coefficients -nicotine_ri.add_constant_coeff("kd", 3.0e-5, note="decay rate", units="1/min") -nicotine_ri.add_constant_coeff("K1", global_value=9.75e-2, units="L * min^(-1) * mg^(-1)", note="decay constant for chlorine as function of mass(Nic)") -nicotine_ri.add_constant_coeff("K2", global_value=5.73e-1, units="L * min^(-1) * mg^(-1)", note="decay constant for nicotine as function of mass(Cl)") -nicotine_ri.add_constant_coeff("K3", global_value=1.34e-2, units="L * min^(-1) * mg^(-1)", note="decay constant for nicotine as function of mass(N2)") -nicotine_ri.add_constant_coeff("K4", global_value=2.19e-2, units="L * min^(-1) * mg^(-1)", note="decay constant for nicotine as function of mass(Cl)") -# Add terms (named subexpressions) -nicotine_ri.add_other_term("RXCL", expression="kd*HOCL + K1*Nx*HOCL + K3*NX2*HOCL") -nicotine_ri.add_other_term("RXN", expression="K2*Nx*HOCL") -nicotine_ri.add_other_term("RXNX2", expression="K2*Nx*HOCL - K4*NX2*HOCL") -# Add pipe reactions, one per species -nicotine_ri.add_pipe_reaction("Nx", "RATE", expression="-RXN") -nicotine_ri.add_pipe_reaction("HOCL", "RATE", expression="-RXCL") -nicotine_ri.add_pipe_reaction("NX2", "RATE", expression="RXNX2") -# Tank reactions actually aren't necessary since there aren't any wall species -nicotine_ri.add_tank_reaction("Nx", "RATE", expression="-RXN") -nicotine_ri.add_tank_reaction("HOCL", "RATE", expression="-RXCL") -nicotine_ri.add_tank_reaction("NX2", "RATE", expression="RXNX2") +# # ===================== Nicotine-chlorine reactive intermediate species +# # +# nicotine_ri = WaterQualityReactionsModel( +# title="Nicotine - Chlorine reaction with reactive intermediate", +# desc="Values in libarary are for test purposes ONLY.", +# ) +# """A nicotine-chlorine reaction with a reactive intermediate""" +# # Set the options +# nicotine_ri.options.quality.area_units = "M2" +# nicotine_ri.options.quality.rate_units = "MIN" +# nicotine_ri.options.quality.timestep = 1 +# nicotine_ri.options.quality.atol = 1.0e-10 +# nicotine_ri.options.quality.rtol = 1.0e-10 +# # Add species +# nicotine_ri.add_bulk_species("Nx", units="MG", note="Nicotine") +# nicotine_ri.add_bulk_species("HOCL", units="MG", note="Free Chlorine") +# nicotine_ri.add_bulk_species("NX2", units="MG", note="Intermediate Nicotine Reactive") +# # Add coefficients +# nicotine_ri.add_constant_coeff("kd", 3.0e-5, note="decay rate", units="1/min") +# nicotine_ri.add_constant_coeff("K1", global_value=9.75e-2, units="L * min^(-1) * mg^(-1)", note="decay constant for chlorine as function of mass(Nic)") +# nicotine_ri.add_constant_coeff("K2", global_value=5.73e-1, units="L * min^(-1) * mg^(-1)", note="decay constant for nicotine as function of mass(Cl)") +# nicotine_ri.add_constant_coeff("K3", global_value=1.34e-2, units="L * min^(-1) * mg^(-1)", note="decay constant for nicotine as function of mass(N2)") +# nicotine_ri.add_constant_coeff("K4", global_value=2.19e-2, units="L * min^(-1) * mg^(-1)", note="decay constant for nicotine as function of mass(Cl)") +# # Add terms (named subexpressions) +# nicotine_ri.add_other_term("RXCL", expression="kd*HOCL + K1*Nx*HOCL + K3*NX2*HOCL") +# nicotine_ri.add_other_term("RXN", expression="K2*Nx*HOCL") +# nicotine_ri.add_other_term("RXNX2", expression="K2*Nx*HOCL - K4*NX2*HOCL") +# # Add pipe reactions, one per species +# nicotine_ri.add_pipe_reaction("Nx", "RATE", expression="-RXN") +# nicotine_ri.add_pipe_reaction("HOCL", "RATE", expression="-RXCL") +# nicotine_ri.add_pipe_reaction("NX2", "RATE", expression="RXNX2") +# # Tank reactions actually aren't necessary since there aren't any wall species +# nicotine_ri.add_tank_reaction("Nx", "RATE", expression="-RXN") +# nicotine_ri.add_tank_reaction("HOCL", "RATE", expression="-RXCL") +# nicotine_ri.add_tank_reaction("NX2", "RATE", expression="RXNX2") -# ===================== Lead plumbosolvency model -# -lead_ppm = WaterQualityReactionsModel( - title="Lead Plumbosolvency Model (from Burkhardt et al 2020)", - desc="Parameters for EPA HPS Simulator Model", - citations=[Citation( - title="Framework for Modeling Lead in Premise Plumbing Systems Using EPANET", - year=2020, - author=[ - "Jonathan B. Burkhardt", - "Hyoungmin Woo", - "James Mason", - "Feng Shang", - "Simoni Triantafyllidou", - "Michael R. Schock", - "Darren Lytle", - "Regan Murray", - ], - citation_class="article", - journaltitle="J Water Resour Plan Manag", - volume=146, - number=12, - fulldate="2020-12-01", - doi="10.1061/(asce)wr.1943-5452.0001304", - eprint=[ - "PMID:33627937", - "PMCID:PMC7898126", - "NIHMSID:NIHMS1664627", - ], - )], - allow_sympy_reserved_names=True, - options={ - "report": { - "species": {"PB2": "YES"}, - "species_precision": {"PB2": 5}, - "nodes": "all", - "links": "all", - }, - "quality": { - "timestep": 1, - "area_units": "M2", - "rate_units": "SEC", - "rtol": 1e-08, - "atol": 1e-08, - }, - }, -) -"""A lead plumbosolvency model [BEMS20]_. +# # ===================== Lead plumbosolvency model +# # +# lead_ppm = WaterQualityReactionsModel( +# title="Lead Plumbosolvency Model (from Burkhardt et al 2020)", +# desc="Parameters for EPA HPS Simulator Model", +# citations=[Citation( +# title="Framework for Modeling Lead in Premise Plumbing Systems Using EPANET", +# year=2020, +# author=[ +# "Jonathan B. Burkhardt", +# "Hyoungmin Woo", +# "James Mason", +# "Feng Shang", +# "Simoni Triantafyllidou", +# "Michael R. Schock", +# "Darren Lytle", +# "Regan Murray", +# ], +# citation_class="article", +# journaltitle="J Water Resour Plan Manag", +# volume=146, +# number=12, +# fulldate="2020-12-01", +# doi="10.1061/(asce)wr.1943-5452.0001304", +# eprint=[ +# "PMID:33627937", +# "PMCID:PMC7898126", +# "NIHMSID:NIHMS1664627", +# ], +# )], +# allow_sympy_reserved_names=True, +# options={ +# "report": { +# "species": {"PB2": "YES"}, +# "species_precision": {"PB2": 5}, +# "nodes": "all", +# "links": "all", +# }, +# "quality": { +# "timestep": 1, +# "area_units": "M2", +# "rate_units": "SEC", +# "rtol": 1e-08, +# "atol": 1e-08, +# }, +# }, +# ) +# """A lead plumbosolvency model [BEMS20]_. -.. [BEMS20] - J. B. Burkhardt, et al. (2020) - "Framework for Modeling Lead in Premise Plumbing Systems Using EPANET". - `Journal of water resources planning and management`. - **146** (12). - https://doi.org/10.1061/(asce)wr.1943-5452.0001304 +# .. [BEMS20] +# J. B. Burkhardt, et al. (2020) +# "Framework for Modeling Lead in Premise Plumbing Systems Using EPANET". +# `Journal of water resources planning and management`. +# **146** (12). +# https://doi.org/10.1061/(asce)wr.1943-5452.0001304 -""" -# add the species, coefficients and reactions -lead_ppm.add_bulk_species("PB2", "ug", note="dissolved lead (Pb)") -lead_ppm.add_constant_coeff("M", global_value=0.117, note="Desorption rate (ug/m^2/s)", units="ug * m^(-1) * s^(-1)") -lead_ppm.add_constant_coeff("E", global_value=140.0, note="saturation/plumbosolvency level (ug/L)", units="ug/L") -lead_ppm.add_parameterized_coeff("F", global_value=0, note="determines which pipes have reactions") -lead_ppm.add_pipe_reaction("PB2", "RATE", expression="F*Av*M*(E - PB2)/E") -lead_ppm.add_tank_reaction("PB2", "RATE", expression="0") +# """ +# # add the species, coefficients and reactions +# lead_ppm.add_bulk_species("PB2", "ug", note="dissolved lead (Pb)") +# lead_ppm.add_constant_coeff("M", global_value=0.117, note="Desorption rate (ug/m^2/s)", units="ug * m^(-1) * s^(-1)") +# lead_ppm.add_constant_coeff("E", global_value=140.0, note="saturation/plumbosolvency level (ug/L)", units="ug/L") +# lead_ppm.add_parameterized_coeff("F", global_value=0, note="determines which pipes have reactions") +# lead_ppm.add_pipe_reaction("PB2", "RATE", expression="F*Av*M*(E - PB2)/E") +# lead_ppm.add_tank_reaction("PB2", "RATE", expression="0") diff --git a/wntr/reaction/toolkitmsx.py b/wntr/reaction/toolkitmsx.py index 6429066ff..cca0a09c5 100644 --- a/wntr/reaction/toolkitmsx.py +++ b/wntr/reaction/toolkitmsx.py @@ -19,8 +19,9 @@ from pkg_resources import resource_filename -from ..epanet.toolkit import ENepanet, EpanetException +from ..epanet.toolkit import ENepanet from ..epanet.util import SizeLimits +from .exceptions import EpanetMsxException epanet_toolkit = "wntr.epanet.toolkit" @@ -39,99 +40,6 @@ logger = logging.getLogger(__name__) -class EpanetMsxToolkitError(Exception): - ERROR_CODES = { - 101: "insufficient memory available.", - 102: "no network data available.", - 103: "hydraulics not initialized.", - 104: "no hydraulics for water quality analysis.", - 105: "water quality not initialized.", - 106: "no results saved to report on.", - 107: "hydraulics supplied from external file.", - 108: "cannot use external file while hydraulics solver is active.", - 109: "cannot change time parameter when solver is active.", - 110: "cannot solve network hydraulic equations.", - 120: "cannot solve water quality transport equations.", - 200: "Cannot read EPANET-MSX file.", - 201: "Syntax error", - 202: "Function call contains an illegal numeric value", - 203: "Function call refers to an undefined node", - 204: "Function call refers to an undefined link", - 205: "Function call refers to an undefined time pattern", - 206: "Function call refers to an undefined curve", - 207: "Function call attempts to control a check valve pipe or a GPV valve", - 208: "Function call contains illegal PDA pressure limits", - 209: "Function call contains an illegal node property value", - 211: "Function call contains an illegal link property value", - 212: "Function call refers to an undefined Trace Node", - 213: "Function call contains an invalid option value", - 214: "Too many characters in a line of an input file", - 215: "Function call contains a duplicate ID label", - 216: "Function call refers to an undefined pump", - 217: "Invalid pump energy data", - 219: "Illegal valve connection to tank node", - 220: "Illegal valve connection to another valve", - 221: "Mis-placed clause in rule-based control", - 222: "Link assigned same start and end nodes", - 223: "Not enough nodes in network", - 224: "No tanks or reservoirs in network", - 225: "Invalid lower/upper levels for tank", - 226: "No head curve or power rating for pump", - 227: "Invalid head curve for pump", - 230: "Nonincreasing x-values for curve", - 233: "Network has unconnected node", - 240: "Function call refers to nonexistent water quality source", - 241: "Function call refers to nonexistent control", - 250: "Function call contains invalid format (e.g. too long an ID name)", - 251: "Function call contains invalid parameter code", - 253: "Function call refers to nonexistent demand category", - 254: "Function call refers to node with no coordinates", - 257: "Function call refers to nonexistent rule", - 258: "Function call refers to nonexistent rule clause", - 259: "Function call attempts to delete a node that still has links connected to it", - 260: "Function call attempts to delete node assigned as a Trace Node", - 261: "Function call attempts to delete a node or link contained in a control", - 262: "Function call attempts to modify network structure while a solver is open", - 301: "Identical file names used for different types of files", - 302: "Cannot open input file", - 303: "Cannot open report file", - 304: "Cannot open output file", - 305: "Cannot open hydraulics file", - 306: "Hydraulics file does not match network data", - 307: "Cannot read hydraulics file", - 308: "Cannot save results to binary file", - 309: "Cannot save results to report file", - 501: "insufficient memory available.", - 502: "no EPANET data file supplied.", - 503: "could not open MSX input file.", - 504: "could not open hydraulic results file.", - 505: "could not read hydraulic results file.", - 506: "could not read MSX input file.", - 507: "too few pipe reaction expressions.", - 508: "too few tank reaction expressions.", - 509: "could not open differential equation solver.", - 510: "could not open algebraic equation solver.", - 511: "could not open binary results file.", - 512: "read/write on binary results file.", - 513: "could not integrate reaction rate expressions.", - 514: "could not solve reaction equilibrium expressions.", - 515: "reference made to an unknown type of object.", - 516: "reference made to an illegal object index.", - 517: "reference made to an undefined object ID.", - 518: "invalid property values were specified.", - 519: "an MSX project was not opened.", - 520: "an MSX project is already opened.", - 521: "could not open MSX report file.", - 522: "could not compile chemistry functions.", - 523: "could not load functions from compiled chemistry file.", - 524: "illegal math operation.", - } - - def __init__(self, code, *args: object) -> None: - msg = self.ERROR_CODES.get(code, "EPANET MSX error: {}".format(code)) - super().__init__(msg, *args) - - class MSXepanet(ENepanet): def __init__(self, inpfile="", rptfile="", binfile="", version=2.2): @@ -185,7 +93,7 @@ def MSXopen(self, nomeinp): """ ierr = self.ENlib.MSXopen(ctypes.c_char_p(nomeinp.encode())) if ierr != 0: - raise EpanetMsxToolkitError(ierr) + raise EpanetMsxException(ierr) def MSXclose( self, @@ -193,13 +101,13 @@ def MSXclose( """Closes down the Toolkit system (including all files being processed)""" ierr = self.ENlib.MSXclose() if ierr != 0: - raise EpanetMsxToolkitError(ierr) + raise EpanetMsxException(ierr) def MSXusehydfile(self, fname): """Uses the contents of the specified file as the current binary hydraulics file""" ierr = self.ENlib.MSXusehydfile(ctypes.c_char_p(fname.encode())) if ierr != 0: - raise EpanetMsxToolkitError(ierr) + raise EpanetMsxException(ierr) def MSXsolveH( self, @@ -208,14 +116,14 @@ def MSXsolveH( for all time periods written to the binary Hydraulics file.""" ierr = self.ENlib.MSXsolveH() if ierr != 0: - raise EpanetMsxToolkitError(ierr) + raise EpanetMsxException(ierr) def MSXinit(self, saveFlag=0): """Initializes the MSX system before solving for water quality results in step-wise fashion set saveFlag to 1 if water quality results should be saved to a scratch binary file, or to 0 is not saved to file""" ierr = self.ENlib.MSXinit(saveFlag) if ierr != 0: - raise EpanetMsxToolkitError(ierr) + raise EpanetMsxException(ierr) def MSXsolveQ( self, @@ -223,7 +131,7 @@ def MSXsolveQ( """solves for water quality over the entire simulation period and saves the results to an internal scratch file""" ierr = self.ENlib.MSXsolveQ() if ierr != 0: - raise EpanetMsxToolkitError(ierr) + raise EpanetMsxException(ierr) def MSXstep( self, @@ -234,7 +142,7 @@ def MSXstep( tleft = ctypes.c_long() ierr = self.ENlib.MSXstep(ctypes.byref(t), ctypes.byref(tleft)) if ierr != 0: - raise EpanetMsxToolkitError(ierr) + raise EpanetMsxException(ierr) out = [t.value, tleft.value] return out @@ -242,13 +150,13 @@ def MSXsaveoutfile(self, fname): """saves water quality results computed for each node, link and reporting time period to a named binary file""" ierr = self.ENlib.MSXsaveoutfile(ctypes.c_char_p(fname.encode())) if ierr != 0: - raise EpanetMsxToolkitError(ierr) + raise EpanetMsxException(ierr) def MSXsavemsxfile(self, fname): """saves the data associated with the current MSX project into a new MSX input file""" ierr = self.ENlib.MSXsavemsxfile(ctypes.c_char_p(fname.encode())) if ierr != 0: - raise EpanetMsxToolkitError(ierr) + raise EpanetMsxException(ierr) def MSXreport( self, @@ -256,7 +164,7 @@ def MSXreport( """Writes water quality simulations results as instructed by the MSX input file to a text file""" ierr = self.ENlib.MSXreport() if ierr != 0: - raise EpanetMsxToolkitError(ierr) + raise EpanetMsxException(ierr) # ---------get parameters--------------------------------------------------------------- def MSXgetindex(self, type, name): @@ -281,7 +189,7 @@ def MSXgetindex(self, type, name): ind = ctypes.c_int() ierr = self.ENlib.MSXgetindex(type_ind, ctypes.c_char_p(name.encode()), ctypes.byref(ind)) if ierr != 0: - raise EpanetMsxToolkitError(ierr) + raise EpanetMsxException(ierr) return ind.value def MSXgetIDlen(self, type, index): @@ -306,7 +214,7 @@ def MSXgetIDlen(self, type, index): len = ctypes.c_int() ierr = self.ENlib.MSXgetIDlen(type_ind, ctypes.c_int(index), ctypes.byref(len)) if ierr != 0: - raise EpanetMsxToolkitError(ierr) + raise EpanetMsxException(ierr) return len.value def MSXgetID(self, type, index): @@ -333,7 +241,7 @@ def MSXgetID(self, type, index): id = ctypes.create_string_buffer(maxlen) ierr = self.ENlib.MSXgetID(type_ind, ctypes.c_int(index), ctypes.byref(id), ctypes.c_int(maxlen - 1)) if ierr != 0: - raise EpanetMsxToolkitError(ierr) + raise EpanetMsxException(ierr) # the .decode() added my MF 6/3/21 return id.value.decode() @@ -354,7 +262,7 @@ def MSXgetinitqual(self, type, ind, spe): iniqual = ctypes.c_double() ierr = self.ENlib.MSXgetinitqual(ctypes.c_int(type_ind), ctypes.c_int(ind), ctypes.c_int(spe), ctypes.byref(iniqual)) if ierr != 0: - raise EpanetMsxToolkitError(ierr) + raise EpanetMsxException(ierr) return iniqual.value def MSXgetqual(self, type, ind, spe): @@ -374,7 +282,7 @@ def MSXgetqual(self, type, ind, spe): qual = ctypes.c_double() ierr = self.ENlib.MSXgetqual(ctypes.c_int(type_ind), ctypes.c_int(ind), ctypes.c_int(spe), ctypes.byref(qual)) if ierr != 0: - raise EpanetMsxToolkitError(ierr) + raise EpanetMsxException(ierr) return qual.value def MSXgetconstant(self, ind): @@ -384,7 +292,7 @@ def MSXgetconstant(self, ind): const = ctypes.c_double() ierr = self.ENlib.MSXgetconstant(ind, ctypes.byref(const)) if ierr != 0: - raise EpanetMsxToolkitError(ierr) + raise EpanetMsxException(ierr) return const.value def MSXgetparameter(self, type, ind, param_ind): @@ -403,7 +311,7 @@ def MSXgetparameter(self, type, ind, param_ind): param = ctypes.c_double() ierr = self.ENlib.MSXgetparameter(ctypes.c_int(type_ind), ctypes.c_int(ind), ctypes.c_int(param_ind), ctypes.byref(param)) if ierr != 0: - raise EpanetMsxToolkitError(ierr) + raise EpanetMsxException(ierr) return param.value def MSXgetsource(self, node, spe): @@ -421,7 +329,7 @@ def MSXgetsource(self, node, spe): pat = ctypes.c_int() ierr = self.ENlib.MSXgetsource(ctypes.c_int(node), ctypes.c_int(spe), ctypes.byref(type), ctypes.byref(level), ctypes.byref(pat)) if ierr != 0: - raise EpanetMsxToolkitError(ierr) + raise EpanetMsxException(ierr) src_out = [type.value, level.value, pat.value] return src_out @@ -432,7 +340,7 @@ def MSXgetpatternlen(self, pat): len = ctypes.c_int() ierr = self.ENlib.MSXgetpatternlen(pat, ctypes.byref(len)) if ierr != 0: - raise EpanetMsxToolkitError(ierr) + raise EpanetMsxException(ierr) return len.value def MSXgetpatternvalue(self, pat, period): @@ -444,7 +352,7 @@ def MSXgetpatternvalue(self, pat, period): val = ctypes.c_double() ierr = self.ENlib.MSXgetpatternvalue(pat, period, ctypes.byref(val)) if ierr != 0: - raise EpanetMsxToolkitError(ierr) + raise EpanetMsxException(ierr) return val.value def MSXgetcount(self, type): @@ -469,7 +377,7 @@ def MSXgetcount(self, type): count = ctypes.c_int() ierr = self.ENlib.MSXgetcount(type_ind, ctypes.byref(count)) if ierr != 0: - raise EpanetMsxToolkitError(ierr) + raise EpanetMsxException(ierr) return count.value def MSXgetspecies(self, spe): @@ -485,7 +393,7 @@ def MSXgetspecies(self, spe): rTol = ctypes.c_double() ierr = self.ENlib.MSXgetspecies(spe, ctypes.byref(type_ind), ctypes.byref(units), ctypes.byref(aTol), ctypes.byref(rTol)) if ierr != 0: - raise EpanetMsxToolkitError(ierr) + raise EpanetMsxException(ierr) spe_out = [type_ind.value, units.value, aTol.value, rTol.value] return spe_out @@ -508,7 +416,7 @@ def MSXsetconstant(self, ind, value): value is the new value to be assigned to the constant""" ierr = self.ENlib.MSXsetconstant(ctypes.c_int(ind), ctypes.c_double(value)) if ierr != 0: - raise EpanetMsxToolkitError(ierr) + raise EpanetMsxException(ierr) def MSXsetparameter(self, type, ind, param, value): """assigns a value to a particular reaction parameter for a given TANK or PIPE @@ -525,7 +433,7 @@ def MSXsetparameter(self, type, ind, param, value): raise Exception("unrecognized type") ierr = self.ENlib.MSXsetparameter(ctypes.c_int(type_ind), ctypes.c_int(ind), ctypes.c_int(param), ctypes.c_double(value)) if ierr != 0: - raise EpanetMsxToolkitError(ierr) + raise EpanetMsxException(ierr) def MSXsetinitqual(self, type, ind, spe, value): """Retrieves the initial concentration of a particular chemical species assigned to a specific node @@ -543,7 +451,7 @@ def MSXsetinitqual(self, type, ind, spe, value): raise Exception("unrecognized type") ierr = self.ENlib.MSXsetinitqual(ctypes.c_int(type_ind), ctypes.c_int(ind), ctypes.c_int(spe), ctypes.c_double(value)) if ierr != 0: - raise EpanetMsxToolkitError(ierr) + raise EpanetMsxException(ierr) def MSXsetsource(self, node, spe, type_n, level, pat): """sets the attributes of an external source of a particular chemical species in a specific node of the pipe network @@ -570,7 +478,7 @@ def MSXsetsource(self, node, spe, type_n, level, pat): raise Exception("unrecognized type") ierr = self.ENlib.MSXsetsource(ctypes.c_int(node), ctypes.c_int(spe), ctypes.c_int(type_ind), ctypes.c_double(level), ctypes.c_int(pat)) if ierr != 0: - raise EpanetMsxToolkitError(ierr) + raise EpanetMsxException(ierr) def MSXsetpattern(self, pat, mult): """assigns a new set of multipliers to a given MSX SOURCE time pattern @@ -585,7 +493,7 @@ def MSXsetpattern(self, pat, mult): cfactors[i] = float(mult[i]) ierr = self.ENlib.MSXsetpattern(ctypes.c_int(pat), cfactors, ctypes.c_int(length)) if ierr != 0: - raise EpanetMsxToolkitError(ierr) + raise EpanetMsxException(ierr) def MSXsetpatternvalue(self, pat, period, value): """Sets the multiplier factor for a specific period within a SOURCE time pattern. @@ -595,7 +503,7 @@ def MSXsetpatternvalue(self, pat, period, value): value: multiplier factor for the period""" ierr = self.ENlib.MSXsetpatternvalue(ctypes.c_int(pat), ctypes.c_int(period), ctypes.c_double(value)) if ierr != 0: - raise EpanetMsxToolkitError(ierr) + raise EpanetMsxException(ierr) def MSXaddpattern(self, patternid): """Adds a new, empty MSX source time pattern to an MSX project. @@ -603,4 +511,4 @@ def MSXaddpattern(self, patternid): pattern id: c-string name of pattern""" ierr = self.ENlib.MSXaddpattern(ctypes.c_char_p(patternid.encode())) if ierr != 0: - raise EpanetMsxToolkitError(ierr) + raise EpanetMsxException(ierr) From 52de3d58ee49a1322f1378ede2eb0cd28228d7fc Mon Sep 17 00:00:00 2001 From: dbhart Date: Sat, 16 Sep 2023 13:28:56 -0600 Subject: [PATCH 23/75] Rebase library --- wntr/reaction/library.py | 274 +++++++++++++++++++-------------------- 1 file changed, 137 insertions(+), 137 deletions(-) diff --git a/wntr/reaction/library.py b/wntr/reaction/library.py index dcf95b142..6409cc017 100644 --- a/wntr/reaction/library.py +++ b/wntr/reaction/library.py @@ -1,149 +1,149 @@ -# # -*- coding: utf-8 -*- -# # @Contributors: -# # Jonathan Burkhardt, U.S. Environmental Protection Agency, Office of Research and Development +# -*- coding: utf-8 -*- +# @Contributors: +# Jonathan Burkhardt, U.S. Environmental Protection Agency, Office of Research and Development -# """ -# A library of common reactions. -# Values in libarary are for test purposes ONLY. These highlight the reaction form/relationship -# but not necessarily the specific system kinetics. Citations are provided where appropriate for -# sources of values or models. In most cases updates will be necessary to use for different -# models - that is, sources, pipes, nodes are for a given network, and must be updated for different -# models. +""" +A library of common reactions. +Values in libarary are for test purposes ONLY. These highlight the reaction form/relationship +but not necessarily the specific system kinetics. Citations are provided where appropriate for +sources of values or models. In most cases updates will be necessary to use for different +models - that is, sources, pipes, nodes are for a given network, and must be updated for different +models. -# .. autosummary:: +.. autosummary:: -# nicotine -# nicotine_ri -# lead_ppm + nicotine + nicotine_ri + lead_ppm -# """ -# import logging +""" +import logging -# from ..utils.citations import Citation -# from .model import WaterQualityReactionsModel +from ..utils.citations import Citation +from .model import WaterQualityReactionsModel -# logger = logging.getLogger(__name__) +logger = logging.getLogger(__name__) -# # ===================== Nicotine-chlorine model -# # -# nicotine = WaterQualityReactionsModel( -# title="Nicotine - Chlorine reaction", -# desc="Values in libarary are for test purposes ONLY.", -# ) -# """A nicotine-chlorine reaction model""" +# ===================== Nicotine-chlorine model +# +nicotine = WaterQualityReactionsModel( + title="Nicotine - Chlorine reaction", + desc="Values in libarary are for test purposes ONLY.", +) +"""A nicotine-chlorine reaction model""" -# nicotine.options.quality.area_units = "M2" -# nicotine.options.quality.rate_units = "MIN" -# nicotine.options.quality.timestep = 1 -# nicotine.add_bulk_species("Nx", units="MG", note="Nicotine") -# nicotine.add_bulk_species("HOCL", units="MG", note="Free chlorine") -# nicotine.add_constant_coeff("kd", global_value=2.33e-3, units="min^(-1)", note="decay rate") -# nicotine.add_constant_coeff("K1", global_value=5.92e-2, units="L * min^(-1) * mg^(-1)", note="decay constant for chlorine as function of mass(Nic)") -# nicotine.add_constant_coeff("K2", global_value=1.84e-1, units="L * min^(-1) * mg^(-1)", note="decay constant for nicotine as function of mass(Cl)") -# nicotine.add_other_term("RXCL", expression="kd * HOCL + K1 * Nx * HOCL") -# nicotine.add_other_term("RXN", expression="K2 * Nx * HOCL") -# nicotine.add_pipe_reaction("Nx", "rate", expression="-RXN") -# nicotine.add_pipe_reaction("HOCL", "rate", expression="-RXCL") -# nicotine.add_tank_reaction("Nx", "rate", "0") -# nicotine.add_tank_reaction("HOCL", "rate", "0") +nicotine.options.quality.area_units = "M2" +nicotine.options.quality.rate_units = "MIN" +nicotine.options.quality.timestep = 1 +nicotine.add_bulk_species("Nx", units="MG", note="Nicotine") +nicotine.add_bulk_species("HOCL", units="MG", note="Free chlorine") +nicotine.add_constant_coeff("kd", global_value=2.33e-3, units="min^(-1)", note="decay rate") +nicotine.add_constant_coeff("K1", global_value=5.92e-2, units="L * min^(-1) * mg^(-1)", note="decay constant for chlorine as function of mass(Nic)") +nicotine.add_constant_coeff("K2", global_value=1.84e-1, units="L * min^(-1) * mg^(-1)", note="decay constant for nicotine as function of mass(Cl)") +nicotine.add_other_term("RXCL", expression="kd * HOCL + K1 * Nx * HOCL") +nicotine.add_other_term("RXN", expression="K2 * Nx * HOCL") +nicotine.add_pipe_reaction("Nx", "rate", expression="-RXN") +nicotine.add_pipe_reaction("HOCL", "rate", expression="-RXCL") +nicotine.add_tank_reaction("Nx", "rate", "0") +nicotine.add_tank_reaction("HOCL", "rate", "0") -# # ===================== Nicotine-chlorine reactive intermediate species -# # -# nicotine_ri = WaterQualityReactionsModel( -# title="Nicotine - Chlorine reaction with reactive intermediate", -# desc="Values in libarary are for test purposes ONLY.", -# ) -# """A nicotine-chlorine reaction with a reactive intermediate""" -# # Set the options -# nicotine_ri.options.quality.area_units = "M2" -# nicotine_ri.options.quality.rate_units = "MIN" -# nicotine_ri.options.quality.timestep = 1 -# nicotine_ri.options.quality.atol = 1.0e-10 -# nicotine_ri.options.quality.rtol = 1.0e-10 -# # Add species -# nicotine_ri.add_bulk_species("Nx", units="MG", note="Nicotine") -# nicotine_ri.add_bulk_species("HOCL", units="MG", note="Free Chlorine") -# nicotine_ri.add_bulk_species("NX2", units="MG", note="Intermediate Nicotine Reactive") -# # Add coefficients -# nicotine_ri.add_constant_coeff("kd", 3.0e-5, note="decay rate", units="1/min") -# nicotine_ri.add_constant_coeff("K1", global_value=9.75e-2, units="L * min^(-1) * mg^(-1)", note="decay constant for chlorine as function of mass(Nic)") -# nicotine_ri.add_constant_coeff("K2", global_value=5.73e-1, units="L * min^(-1) * mg^(-1)", note="decay constant for nicotine as function of mass(Cl)") -# nicotine_ri.add_constant_coeff("K3", global_value=1.34e-2, units="L * min^(-1) * mg^(-1)", note="decay constant for nicotine as function of mass(N2)") -# nicotine_ri.add_constant_coeff("K4", global_value=2.19e-2, units="L * min^(-1) * mg^(-1)", note="decay constant for nicotine as function of mass(Cl)") -# # Add terms (named subexpressions) -# nicotine_ri.add_other_term("RXCL", expression="kd*HOCL + K1*Nx*HOCL + K3*NX2*HOCL") -# nicotine_ri.add_other_term("RXN", expression="K2*Nx*HOCL") -# nicotine_ri.add_other_term("RXNX2", expression="K2*Nx*HOCL - K4*NX2*HOCL") -# # Add pipe reactions, one per species -# nicotine_ri.add_pipe_reaction("Nx", "RATE", expression="-RXN") -# nicotine_ri.add_pipe_reaction("HOCL", "RATE", expression="-RXCL") -# nicotine_ri.add_pipe_reaction("NX2", "RATE", expression="RXNX2") -# # Tank reactions actually aren't necessary since there aren't any wall species -# nicotine_ri.add_tank_reaction("Nx", "RATE", expression="-RXN") -# nicotine_ri.add_tank_reaction("HOCL", "RATE", expression="-RXCL") -# nicotine_ri.add_tank_reaction("NX2", "RATE", expression="RXNX2") +# ===================== Nicotine-chlorine reactive intermediate species +# +nicotine_ri = WaterQualityReactionsModel( + title="Nicotine - Chlorine reaction with reactive intermediate", + desc="Values in libarary are for test purposes ONLY.", +) +"""A nicotine-chlorine reaction with a reactive intermediate""" +# Set the options +nicotine_ri.options.quality.area_units = "M2" +nicotine_ri.options.quality.rate_units = "MIN" +nicotine_ri.options.quality.timestep = 1 +nicotine_ri.options.quality.atol = 1.0e-10 +nicotine_ri.options.quality.rtol = 1.0e-10 +# Add species +nicotine_ri.add_bulk_species("Nx", units="MG", note="Nicotine") +nicotine_ri.add_bulk_species("HOCL", units="MG", note="Free Chlorine") +nicotine_ri.add_bulk_species("NX2", units="MG", note="Intermediate Nicotine Reactive") +# Add coefficients +nicotine_ri.add_constant_coeff("kd", 3.0e-5, note="decay rate", units="1/min") +nicotine_ri.add_constant_coeff("K1", global_value=9.75e-2, units="L * min^(-1) * mg^(-1)", note="decay constant for chlorine as function of mass(Nic)") +nicotine_ri.add_constant_coeff("K2", global_value=5.73e-1, units="L * min^(-1) * mg^(-1)", note="decay constant for nicotine as function of mass(Cl)") +nicotine_ri.add_constant_coeff("K3", global_value=1.34e-2, units="L * min^(-1) * mg^(-1)", note="decay constant for nicotine as function of mass(N2)") +nicotine_ri.add_constant_coeff("K4", global_value=2.19e-2, units="L * min^(-1) * mg^(-1)", note="decay constant for nicotine as function of mass(Cl)") +# Add terms (named subexpressions) +nicotine_ri.add_other_term("RXCL", expression="kd*HOCL + K1*Nx*HOCL + K3*NX2*HOCL") +nicotine_ri.add_other_term("RXN", expression="K2*Nx*HOCL") +nicotine_ri.add_other_term("RXNX2", expression="K2*Nx*HOCL - K4*NX2*HOCL") +# Add pipe reactions, one per species +nicotine_ri.add_pipe_reaction("Nx", "RATE", expression="-RXN") +nicotine_ri.add_pipe_reaction("HOCL", "RATE", expression="-RXCL") +nicotine_ri.add_pipe_reaction("NX2", "RATE", expression="RXNX2") +# Tank reactions actually aren't necessary since there aren't any wall species +nicotine_ri.add_tank_reaction("Nx", "RATE", expression="-RXN") +nicotine_ri.add_tank_reaction("HOCL", "RATE", expression="-RXCL") +nicotine_ri.add_tank_reaction("NX2", "RATE", expression="RXNX2") -# # ===================== Lead plumbosolvency model -# # -# lead_ppm = WaterQualityReactionsModel( -# title="Lead Plumbosolvency Model (from Burkhardt et al 2020)", -# desc="Parameters for EPA HPS Simulator Model", -# citations=[Citation( -# title="Framework for Modeling Lead in Premise Plumbing Systems Using EPANET", -# year=2020, -# author=[ -# "Jonathan B. Burkhardt", -# "Hyoungmin Woo", -# "James Mason", -# "Feng Shang", -# "Simoni Triantafyllidou", -# "Michael R. Schock", -# "Darren Lytle", -# "Regan Murray", -# ], -# citation_class="article", -# journaltitle="J Water Resour Plan Manag", -# volume=146, -# number=12, -# fulldate="2020-12-01", -# doi="10.1061/(asce)wr.1943-5452.0001304", -# eprint=[ -# "PMID:33627937", -# "PMCID:PMC7898126", -# "NIHMSID:NIHMS1664627", -# ], -# )], -# allow_sympy_reserved_names=True, -# options={ -# "report": { -# "species": {"PB2": "YES"}, -# "species_precision": {"PB2": 5}, -# "nodes": "all", -# "links": "all", -# }, -# "quality": { -# "timestep": 1, -# "area_units": "M2", -# "rate_units": "SEC", -# "rtol": 1e-08, -# "atol": 1e-08, -# }, -# }, -# ) -# """A lead plumbosolvency model [BEMS20]_. +# ===================== Lead plumbosolvency model +# +lead_ppm = WaterQualityReactionsModel( + title="Lead Plumbosolvency Model (from Burkhardt et al 2020)", + desc="Parameters for EPA HPS Simulator Model", + citations=[Citation( + title="Framework for Modeling Lead in Premise Plumbing Systems Using EPANET", + year=2020, + author=[ + "Jonathan B. Burkhardt", + "Hyoungmin Woo", + "James Mason", + "Feng Shang", + "Simoni Triantafyllidou", + "Michael R. Schock", + "Darren Lytle", + "Regan Murray", + ], + citation_class="article", + journaltitle="J Water Resour Plan Manag", + volume=146, + number=12, + fulldate="2020-12-01", + doi="10.1061/(asce)wr.1943-5452.0001304", + eprint=[ + "PMID:33627937", + "PMCID:PMC7898126", + "NIHMSID:NIHMS1664627", + ], + )], + allow_sympy_reserved_names=True, + options={ + "report": { + "species": {"PB2": "YES"}, + "species_precision": {"PB2": 5}, + "nodes": "all", + "links": "all", + }, + "quality": { + "timestep": 1, + "area_units": "M2", + "rate_units": "SEC", + "rtol": 1e-08, + "atol": 1e-08, + }, + }, +) +"""A lead plumbosolvency model [BEMS20]_. -# .. [BEMS20] -# J. B. Burkhardt, et al. (2020) -# "Framework for Modeling Lead in Premise Plumbing Systems Using EPANET". -# `Journal of water resources planning and management`. -# **146** (12). -# https://doi.org/10.1061/(asce)wr.1943-5452.0001304 +.. [BEMS20] + J. B. Burkhardt, et al. (2020) + "Framework for Modeling Lead in Premise Plumbing Systems Using EPANET". + `Journal of water resources planning and management`. + **146** (12). + https://doi.org/10.1061/(asce)wr.1943-5452.0001304 -# """ -# # add the species, coefficients and reactions -# lead_ppm.add_bulk_species("PB2", "ug", note="dissolved lead (Pb)") -# lead_ppm.add_constant_coeff("M", global_value=0.117, note="Desorption rate (ug/m^2/s)", units="ug * m^(-1) * s^(-1)") -# lead_ppm.add_constant_coeff("E", global_value=140.0, note="saturation/plumbosolvency level (ug/L)", units="ug/L") -# lead_ppm.add_parameterized_coeff("F", global_value=0, note="determines which pipes have reactions") -# lead_ppm.add_pipe_reaction("PB2", "RATE", expression="F*Av*M*(E - PB2)/E") -# lead_ppm.add_tank_reaction("PB2", "RATE", expression="0") +""" +# add the species, coefficients and reactions +lead_ppm.add_bulk_species("PB2", "ug", note="dissolved lead (Pb)") +lead_ppm.add_constant_coeff("M", global_value=0.117, note="Desorption rate (ug/m^2/s)", units="ug * m^(-1) * s^(-1)") +lead_ppm.add_constant_coeff("E", global_value=140.0, note="saturation/plumbosolvency level (ug/L)", units="ug/L") +lead_ppm.add_parameterized_coeff("F", global_value=0, note="determines which pipes have reactions") +lead_ppm.add_pipe_reaction("PB2", "RATE", expression="F*Av*M*(E - PB2)/E") +lead_ppm.add_tank_reaction("PB2", "RATE", expression="0") From a68835bb0d8cdb8c970551accb7268943f6f2c7c Mon Sep 17 00:00:00 2001 From: dbhart Date: Tue, 19 Sep 2023 17:08:52 -0600 Subject: [PATCH 24/75] Updates to documentation, organization, and utilities --- .../apidoc/wntr.epanet.msx.enums.rst | 7 + .../apidoc/wntr.epanet.msx.exceptions.rst | 7 + documentation/apidoc/wntr.epanet.msx.io.rst | 7 + documentation/apidoc/wntr.epanet.msx.rst | 19 + .../apidoc/wntr.epanet.msx.toolkit.rst | 7 + documentation/apidoc/wntr.epanet.rst | 1 + documentation/apidoc/wntr.reaction.rst | 2 +- .../apidoc/wntr.reaction.toolkitmsx.rst | 7 - .../apidoc/wntr.utils.disjoint_mapping.rst | 8 + documentation/apidoc/wntr.utils.rst | 2 +- wntr/__init__.py | 1 + wntr/epanet/__init__.py | 1 + wntr/epanet/msx/__init__.py | 4 + wntr/epanet/msx/enums.py | 239 ++++++ wntr/epanet/msx/exceptions.py | 254 ++++++ wntr/epanet/msx/io.py | 757 +++++++++++++++++ wntr/epanet/msx/toolkit.py | 749 ++++++++++++++++ wntr/network/io.py | 4 +- wntr/network/model.py | 2 +- wntr/reaction/__init__.py | 7 +- wntr/reaction/base.py | 381 ++------- wntr/reaction/dynamics.py | 48 +- wntr/reaction/exceptions.py | 189 ----- wntr/reaction/io.py | 797 +----------------- wntr/reaction/library.py | 214 ++--- wntr/reaction/model.py | 409 +++++---- wntr/reaction/options.py | 12 +- wntr/reaction/toolkitmsx.py | 514 ----------- wntr/reaction/variables.py | 62 +- ...eactions.py => test_reaction_variables.py} | 152 ++-- wntr/utils/disjoint_mapping.py | 207 +++++ wntr/utils/enumtools.py | 119 +++ 32 files changed, 3005 insertions(+), 2184 deletions(-) create mode 100644 documentation/apidoc/wntr.epanet.msx.enums.rst create mode 100644 documentation/apidoc/wntr.epanet.msx.exceptions.rst create mode 100644 documentation/apidoc/wntr.epanet.msx.io.rst create mode 100644 documentation/apidoc/wntr.epanet.msx.rst create mode 100644 documentation/apidoc/wntr.epanet.msx.toolkit.rst delete mode 100644 documentation/apidoc/wntr.reaction.toolkitmsx.rst create mode 100644 documentation/apidoc/wntr.utils.disjoint_mapping.rst create mode 100644 wntr/epanet/msx/__init__.py create mode 100644 wntr/epanet/msx/enums.py create mode 100644 wntr/epanet/msx/exceptions.py create mode 100644 wntr/epanet/msx/io.py create mode 100644 wntr/epanet/msx/toolkit.py delete mode 100644 wntr/reaction/exceptions.py delete mode 100644 wntr/reaction/toolkitmsx.py rename wntr/tests/{test_reactions.py => test_reaction_variables.py} (53%) create mode 100644 wntr/utils/disjoint_mapping.py create mode 100644 wntr/utils/enumtools.py diff --git a/documentation/apidoc/wntr.epanet.msx.enums.rst b/documentation/apidoc/wntr.epanet.msx.enums.rst new file mode 100644 index 000000000..2f6312275 --- /dev/null +++ b/documentation/apidoc/wntr.epanet.msx.enums.rst @@ -0,0 +1,7 @@ +wntr.epanet.msx.enums module +============================ + +.. automodule:: wntr.epanet.msx.enums + :members: + :no-undoc-members: + :show-inheritance: diff --git a/documentation/apidoc/wntr.epanet.msx.exceptions.rst b/documentation/apidoc/wntr.epanet.msx.exceptions.rst new file mode 100644 index 000000000..0f920ebf8 --- /dev/null +++ b/documentation/apidoc/wntr.epanet.msx.exceptions.rst @@ -0,0 +1,7 @@ +wntr.epanet.msx.exceptions module +================================= + +.. automodule:: wntr.epanet.msx.exceptions + :members: + :no-undoc-members: + :show-inheritance: diff --git a/documentation/apidoc/wntr.epanet.msx.io.rst b/documentation/apidoc/wntr.epanet.msx.io.rst new file mode 100644 index 000000000..eb608d561 --- /dev/null +++ b/documentation/apidoc/wntr.epanet.msx.io.rst @@ -0,0 +1,7 @@ +wntr.epanet.msx.io module +========================= + +.. automodule:: wntr.epanet.msx.io + :members: + :no-undoc-members: + :show-inheritance: diff --git a/documentation/apidoc/wntr.epanet.msx.rst b/documentation/apidoc/wntr.epanet.msx.rst new file mode 100644 index 000000000..0e115a092 --- /dev/null +++ b/documentation/apidoc/wntr.epanet.msx.rst @@ -0,0 +1,19 @@ +wntr.epanet.msx module +====================== + +.. automodule:: wntr.epanet.msx + :members: + :no-undoc-members: + :show-inheritance: + + +Submodules +---------- + +.. toctree:: + + wntr.epanet.msx.enums + wntr.epanet.msx.exceptions + wntr.epanet.msx.io + wntr.epanet.msx.toolkit + diff --git a/documentation/apidoc/wntr.epanet.msx.toolkit.rst b/documentation/apidoc/wntr.epanet.msx.toolkit.rst new file mode 100644 index 000000000..4ae1e206a --- /dev/null +++ b/documentation/apidoc/wntr.epanet.msx.toolkit.rst @@ -0,0 +1,7 @@ +wntr.epanet.msx.toolkit module +============================== + +.. automodule:: wntr.epanet.msx.toolkit + :members: + :no-undoc-members: + :show-inheritance: diff --git a/documentation/apidoc/wntr.epanet.rst b/documentation/apidoc/wntr.epanet.rst index 1af96c98b..501523332 100644 --- a/documentation/apidoc/wntr.epanet.rst +++ b/documentation/apidoc/wntr.epanet.rst @@ -14,6 +14,7 @@ Submodules wntr.epanet.exceptions wntr.epanet.io + wntr.epanet.msx wntr.epanet.toolkit wntr.epanet.util diff --git a/documentation/apidoc/wntr.reaction.rst b/documentation/apidoc/wntr.reaction.rst index cf0d7e3d1..96221653a 100644 --- a/documentation/apidoc/wntr.reaction.rst +++ b/documentation/apidoc/wntr.reaction.rst @@ -6,6 +6,7 @@ wntr.reaction package :undoc-members: :show-inheritance: + Submodules ---------- @@ -18,5 +19,4 @@ Submodules wntr.reaction.library wntr.reaction.model wntr.reaction.options - wntr.reaction.toolkitmsx wntr.reaction.variables diff --git a/documentation/apidoc/wntr.reaction.toolkitmsx.rst b/documentation/apidoc/wntr.reaction.toolkitmsx.rst deleted file mode 100644 index ed46dfcad..000000000 --- a/documentation/apidoc/wntr.reaction.toolkitmsx.rst +++ /dev/null @@ -1,7 +0,0 @@ -wntr.reaction.toolkitmsx module -=============================== - -.. automodule:: wntr.reaction.toolkitmsx - :members: - :undoc-members: - :show-inheritance: diff --git a/documentation/apidoc/wntr.utils.disjoint_mapping.rst b/documentation/apidoc/wntr.utils.disjoint_mapping.rst new file mode 100644 index 000000000..de6ab742d --- /dev/null +++ b/documentation/apidoc/wntr.utils.disjoint_mapping.rst @@ -0,0 +1,8 @@ +wntr.utils.disjoint_mapping module +================================== + +.. automodule:: wntr.utils.disjoint_mapping + :members: + :inherited-members: + :no-undoc-members: + :show-inheritance: diff --git a/documentation/apidoc/wntr.utils.rst b/documentation/apidoc/wntr.utils.rst index e4f3145d6..a2b0893fe 100644 --- a/documentation/apidoc/wntr.utils.rst +++ b/documentation/apidoc/wntr.utils.rst @@ -13,6 +13,6 @@ Submodules .. toctree:: wntr.utils.citations + wntr.utils.disjoint_mapping wntr.utils.logger wntr.utils.ordered_set - wntr.utils.citations diff --git a/wntr/__init__.py b/wntr/__init__.py index d6e352ebe..80e030a5a 100644 --- a/wntr/__init__.py +++ b/wntr/__init__.py @@ -7,6 +7,7 @@ from wntr import graphics from wntr import gis from wntr import utils +from wntr import reaction __version__ = '1.0.0' diff --git a/wntr/epanet/__init__.py b/wntr/epanet/__init__.py index de5a4f410..9d33d715a 100644 --- a/wntr/epanet/__init__.py +++ b/wntr/epanet/__init__.py @@ -5,3 +5,4 @@ from .util import FlowUnits, MassUnits, HydParam, QualParam, EN import wntr.epanet.toolkit import wntr.epanet.exceptions +import wntr.epanet.msx diff --git a/wntr/epanet/msx/__init__.py b/wntr/epanet/msx/__init__.py new file mode 100644 index 000000000..d4bf03075 --- /dev/null +++ b/wntr/epanet/msx/__init__.py @@ -0,0 +1,4 @@ +"""The wntr.epanet.msx package provides EPANET-MSX compatibility functions for WNTR. +""" +from .io import MsxFile +import wntr.epanet.msx.toolkit diff --git a/wntr/epanet/msx/enums.py b/wntr/epanet/msx/enums.py new file mode 100644 index 000000000..38c15cd0e --- /dev/null +++ b/wntr/epanet/msx/enums.py @@ -0,0 +1,239 @@ +"""EPANET-MSX enum types, for use in toolkit API calls.""" + +from enum import IntEnum +from wntr.utils.enumtools import add_get + +@add_get(prefix='MSX_') +class ObjectType(IntEnum): + """The enumeration for object type used in EPANET-MSX. + + .. warning:: These enum values start with 0. + """ + NODE = 0 + LINK = 1 + PIPE = 1 + TANK = 2 + SPECIES = 3 + TERM = 4 + PARAMETER = 5 + CONSTANT = 6 + PATTERN = 7 + MAX_OBJECTS = 8 + + +@add_get(prefix='MSX_') +class SourceType(IntEnum): + """The enumeration for source type used in EPANET-MSX. + + .. warning:: These enum values start with -1. + """ + NOSOURCE = -1 + CONCEN = 0 + MASS = 1 + SETPOINT = 2 + FLOWPACED = 3 + + +@add_get(prefix='MSX_') +class UnitSystemType(IntEnum): + """The enumeration for the units system used in EPANET-MSX. + + .. warning:: These enum values start with 0. + """ + US = 0 + SI = 1 + + +@add_get(prefix='MSX_') +class FlowUnitsType(IntEnum): + """The enumeration for the flow units used in EPANET-MSX. + + .. warning:: These enum values start with 0. + """ + CFS = 0 + GPM = 1 + MGD = 2 + IMGD = 3 + AFD = 4 + LPS = 5 + LPM = 6 + MLD = 7 + CMH = 8 + CMD = 9 + + +@add_get(prefix='MSX_') +class MixType(IntEnum): + """The enumeration for the mixing model used in EPANET-MSX. + + .. warning:: These enum values start with 0. + """ + MIX1 = 0 + MIX2 = 1 + FIFO = 2 + LIFO = 3 + + +@add_get(prefix='MSX_') +class SpeciesType(IntEnum): + """The enumeration for species type used in EPANET-MSX. + + .. warning:: These enum values start with 0. + """ + BULK = 0 + WALL = 1 + + +@add_get(prefix='MSX_') +class ExpressionType(IntEnum): + """The enumeration for the expression type used in EPANET-MSX. + + .. warning:: These enum values start with 0. + """ + NO_EXPR = 0 + RATE = 1 + FORMULA = 2 + EQUIL = 3 + + +@add_get(prefix='MSX_') +class SolverType(IntEnum): + """The enumeration for the solver type used in EPANET-MSX. + + .. warning:: These enum values start with 0. + """ + EUL = 0 + RK5 = 1 + ROS2 = 2 + + +@add_get(prefix='MSX_') +class CouplingType(IntEnum): + """The enumeration for the coupling type option used in EPANET-MSX. + + .. warning:: These enum values start with 0. + """ + NO_COUPLING = 0 + FULL_COUPLING = 1 + + +@add_get(prefix='MSX_') +class MassUnitsType(IntEnum): + """The enumeration for mass units used in EPANET-MSX. + + .. warning:: These enum values start with 0. + """ + MG = 0 + UG = 1 + MOLE = 2 + MMOLE = 3 + + +@add_get(prefix='MSX_') +class AreaUnitsType(IntEnum): + """The enumeration for area units used in EPANET-MSX. + + .. warning:: These enum values start with 0. + """ + FT2 = 0 + M2 = 1 + CM2 = 2 + + +@add_get(prefix='MSX_') +class RateUnitsType(IntEnum): + """The enumeration for rate units used in EPANET-MSX. + + .. warning:: These enum values start with 0. + """ + SECONDS = 0 + MINUTES = 1 + HOURS = 2 + DAYS = 3 + + +@add_get(prefix='MSX_') +class UnitsType(IntEnum): + """The enumerations for units used in EPANET-MSX. + + .. warning:: These enum values start with 0. + """ + LENGTH_UNITS = 0 + DIAM_UNITS = 1 + AREA_UNITS = 2 + VOL_UNITS = 3 + FLOW_UNITS = 4 + CONC_UNITS = 5 + RATE_UNITS = 6 + MAX_UNIT_TYPES = 7 + + +@add_get(prefix='MSX_') +class HydVarType(IntEnum): + """The enumeration for hydraulic variable used in EPANET-MSX. + + .. warning:: These enum values start with 0. + """ + DIAMETER = 1 + FLOW = 2 + VELOCITY = 3 + REYNOLDS = 4 + SHEAR = 5 + FRICTION = 6 + AREAVOL = 7 + ROUGHNESS = 8 + LENGTH = 9 + MAX_HYD_VARS = 10 + + +@add_get(prefix='MSX_') +class TstatType(IntEnum): + """The enumeration used for time statistic in EPANET-MSX. + + .. warning:: These enum values start with 0. + """ + SERIES = 0 + AVERAGE = 1 + MINIMUM = 2 + MAXIMUM = 3 + RANGE = 4 + + +@add_get(prefix='MSX_') +class OptionType(IntEnum): + """The enumeration used for option in EPANET-MSX. + + .. warning:: These enum values start with 0. + """ + AREA_UNITS_OPTION = 0 + RATE_UNITS_OPTION = 1 + SOLVER_OPTION = 2 + COUPLING_OPTION = 3 + TIMESTEP_OPTION = 4 + RTOL_OPTION = 5 + ATOL_OPTION = 6 + COMPILER_OPTION =7 + MAXSEGMENT_OPTION = 8 + PECLETNUMBER_OPTION = 9 + + +@add_get(prefix='MSX_') +class CompilerType(IntEnum): + """The enumeration used for specifying compiler options in EPANET-MSX. + + .. warning:: These enum values start with 0. + """ + NO_COMPILER = 0 + VC = 1 + GC = 2 + + +@add_get(prefix='MSX_') +class FileModeType(IntEnum): + """The enumeration for file model used in EPANET-MSX. + + .. warning:: These enum values start with 0. + """ + SCRATCH_FILE = 0 + SAVED_FILE = 1 + USED_FILE = 2 diff --git a/wntr/epanet/msx/exceptions.py b/wntr/epanet/msx/exceptions.py new file mode 100644 index 000000000..9afaa3f0a --- /dev/null +++ b/wntr/epanet/msx/exceptions.py @@ -0,0 +1,254 @@ +# coding: utf-8 +"""EPANET-MSX error and exception classes.""" + +from enum import IntEnum +from typing import List +from ..exceptions import EpanetException, EN_ERROR_CODES, EpanetErrorEnum + + +MSX_ERROR_CODES = EN_ERROR_CODES.copy() +MSX_ERROR_CODES.update( + { + # MSX syntax errors + 401: "too many characters", + 402: "too few input items", + 403: "invalid keyword: '%s'", + 404: "invalid numeric value: '%s'", + 405: "reference to undefined object: '%s'", + 406: "illegal use of reserved name: '%s'", + 407: "name already used by another object: '%s'", + 408: "species already assigned an expression: '%s'", + 409: "illegal math expression", + 410: "option no longer supported", + 411: "term '%s' contains a cyclic reference", + # MSX runtime errors + 501: "insufficient memory available", + 502: "no EPANET data file supplied", + 503: "could not open MSX input file %s", + 504: "could not open hydraulic results file", + 505: "could not read hydraulic results file", + 506: "could not read MSX input file %s", + 507: "too few pipe reaction expressions", + 508: "too few tank reaction expressions", + 509: "could not open differential equation solver", + 510: "could not open algebraic equation solver", + 511: "could not open binary results file", + 512: "read/write error on binary results file", + 513: "could not integrate reaction rate expressions", + 514: "could not solve reaction equilibrium expressions", + 515: "reference made to an unknown type of object %s", + 516: "reference made to an illegal object index %s", + 517: "reference made to an undefined object ID %s", + 518: "invalid property values were specified", + 519: "an MSX project was not opened", + 520: "an MSX project is already opened", + 522: "could not compile chemistry functions", + 523: "could not load functions from compiled chemistry file", + 524: "illegal math operation", + } +) + + +class MSXErrors(IntEnum): + too_many_chars_msx = 401 + too_few_items = 402 + invalid_keyword = 403 + invalid_numeric_value_msx = 404 + undefined_msx_object = 405 + illegal_reserved_name = 406 + name_in_use = 407 + species_already_assigned = 408 + illegal_math_expression = 409 + option_deprecated = 410 + cyclic_reference = 411 + insufficient_memory_msx = 501 + no_epanet_datafile = 502 + open_msx_fail = 503 + open_hyd_fail_msx = 504 + read_hyd_fail_msx = 505 + read_msx_fail = 506 + not_enough_pipe_reactions = 507 + not_enough_tank_reactions = 508 + open_de_solver_fail = 509 + open_ae_solver_fail = 510 + open_bin_fail_msx = 511 + io_error_msx_bin = 512 + solve_rate_failed = 513 + solve_equil_failed = 514 + unknown_object_type = 515 + illegal_object_index = 516 + undefined_object_id = 517 + invalid_property_value = 518 + msx_project_not_open = 519 + msx_project_open = 520 + compile_chem_failed = 522 + load_compiled_chem_failed = 523 + illegal_math_operation = 524 + insufficient_memory = 101 + no_network = 102 + no_init_hyd = 103 + no_hydraulics = 104 + no_init_qual = 105 + no_results = 106 + hyd_file = 107 + hyd_init_and_hyd_file = 108 + modify_time_during_solve = 109 + solve_hyd_fail = 110 + solve_qual_fail = 120 + input_file_error = 200 + syntax_error = 201 + illegal_numeric_value = 202 + undefined_node = 203 + undefined_link = 204 + undefined_pattern = 205 + undefined_curve = 206 + control_on_cv_gpv = 207 + illegal_pda_limits = 208 + illegal_node_property = 209 + illegal_link_property = 211 + undefined_trace_node = 212 + invalid_option_value = 213 + too_many_chars_inp = 214 + duplicate_id = 215 + undefined_pump = 216 + invalid_energy_value = 217 + illegal_valve_tank = 219 + illegal_tank_valve = 219 + illegal_valve_valve = 220 + misplaced_rule = 221 + link_to_self = 222 + not_enough_nodes = 223 + no_tanks_or_res = 224 + invalid_tank_levels = 225 + missing_pump_data = 226 + invalid_head_curve = 227 + nonincreasing_x_curve = 230 + unconnected_node = 233 + unconnected_node_id = 234 + no_such_source_node = 240 + no_such_control = 241 + invalid_name_format = 250 + invalid_parameter_code = 251 + invalid_id_name = 252 + no_such_demand_category = 253 + missing_coords = 254 + invalid_vertex = 255 + no_such_rule = 257 + no_such_rule_clause = 258 + delete_node_still_linked = 259 + delete_node_is_trace = 260 + delete_node_in_control = 261 + modify_network_during_solve = 262 + node_not_a_tank = 263 + same_file_names = 301 + open_inp_fail = 302 + open_rpt_fail = 303 + open_bin_fail = 304 + open_hyd_fail = 305 + hyd_file_different_network = 306 + read_hyd_fail = 307 + save_bin_fail = 308 + save_rpt_fail = 309 + + +class EpanetMsxException(EpanetException): + def __init__(self, code: int, *args: List[object], line_num=None, line=None) -> None: + """An Exception class for EPANET-MSX Toolkit and IO exceptions. + + Parameters + ---------- + code : int or str or MSXErrors + The EPANET-MSX error code (int) or a string mapping to the MSXErrors enum members + args : additional non-keyword arguments, optional + If there is a string-format within the error code's text, these will be used to + replace the format, otherwise they will be output at the end of the Exception message. + line_num : int, optional + The line number, if reading an INP file, by default None + line : str, optional + The contents of the line, by default None + """ + if isinstance(code, (EpanetErrorEnum, MSXErrors)): + code = int(code) + elif isinstance(code, str): + try: + code = code.strip().replace("-", "_").replace(" ", "_") + code = int(MSXErrors[code]) + except KeyError: + return super(Exception, self).__init__("unknown error code: {}".format(repr(code)), *args) + elif not isinstance(code, int): + return super(Exception, self).__init__("unknown error code: {}".format(repr(code)), *args) + msg = MSX_ERROR_CODES.get(code, "unknown error") + if args is not None: + args = [*args] + if r"%" in msg and len(args) > 0: + msg = msg % args.pop(0) + if len(args) > 0: + msg = msg + " " + str(args) + if line_num: + msg = msg + ", at line {}".format(line_num) + if line: + msg = msg + ":\n " + str(line) + msg = "(Error {}) ".format(code) + msg + super(Exception, self).__init__(msg) + + +class MSXSyntaxError(EpanetMsxException, SyntaxError): + def __init__(self, code, *args, line_num=None, line=None) -> None: + """An MSX-specific error that is due to a syntax error in an msx-file. + + Parameters + ---------- + code : int or str or MSXErrors + The EPANET-MSX error code (int) or a string mapping to the MSXErrors enum members + args : additional non-keyword arguments, optional + If there is a string-format within the error code's text, these will be used to + replace the format, otherwise they will be output at the end of the Exception message. + line_num : int, optional + The line number, if reading an INP file, by default None + line : str, optional + The contents of the line, by default None + """ + super().__init__(code, *args, line_num=line_num, line=line) + + +class MSXKeyError(EpanetMsxException, KeyError): + def __init__(self, code, name, *args, line_num=None, line=None) -> None: + """An MSX-specific error that is due to a missing or unacceptably named variable/speces/etc. + + Parameters + ---------- + code : int or str or MSXErrors + The EPANET-MSX error code (int) or a string mapping to the MSXErrors enum members + name : str + The key/name/id that is missing + args : additional non-keyword arguments, optional + If there is a string-format within the error code's text, these will be used to + replace the format, otherwise they will be output at the end of the Exception message. + line_num : int, optional + The line number, if reading an INP file, by default None + line : str, optional + The contents of the line, by default None + """ + super().__init__(code, name, *args, line_num=line_num, line=line) + + +class MSXValueError(EpanetMsxException, ValueError): + def __init__(self, code, value, *args, line_num=None, line=None) -> None: + """An MSX-specific error that is related to an invalid value. + + Parameters + ---------- + code : int or str or MSXErrors + The EPANET-MSX error code (int) or a string mapping to the MSXErrors enum members + value : Any + The value that is invalid + args : additional non-keyword arguments, optional + If there is a string-format within the error code's text, these will be used to + replace the format, otherwise they will be output at the end of the Exception message. + line_num : int, optional + The line number, if reading an INP file, by default None + line : str, optional + The contents of the line, by default None + """ + + super().__init__(code, value, *args, line_num=line_num, line=line) diff --git a/wntr/epanet/msx/io.py b/wntr/epanet/msx/io.py new file mode 100644 index 000000000..5273f91a0 --- /dev/null +++ b/wntr/epanet/msx/io.py @@ -0,0 +1,757 @@ +# coding: utf-8 + +import datetime +from io import FileIO, TextIOWrapper +import logging +import sys + +from wntr.network.elements import Source +from wntr.reaction.base import LocationType, VariableType +from wntr.reaction.base import MSXComment +from wntr.reaction.model import MultispeciesReactionModel +from wntr.epanet.msx.exceptions import EpanetMsxException +from wntr.reaction.variables import Parameter, Species +from wntr.utils.citations import Citation + +sys_default_enc = sys.getdefaultencoding() + +logger = logging.getLogger(__name__) + +MAX_LINE = 1024 + +_INP_SECTIONS = [ + "[TITLE]", + "[OPTIONS]", + "[SPECIES]", + "[COEFFICIENTS]", + "[TERMS]", + "[PIPES]", + "[TANKS]", + "[SOURCES]", + "[QUALITY]", + "[PARAMETERS]", + "[DIFFUSIVITY]", + "[PATTERNS]", + "[REPORT]", +] + + +def _split_line(line): + _vc = line.split(";", 1) + _cmnt = None + _vals = None + if len(_vc) == 0: + pass + elif len(_vc) == 1: + _vals = _vc[0].split() + elif _vc[0] == "": + _cmnt = _vc[1].strip() + else: + _vals = _vc[0].split() + _cmnt = _vc[1].strip() + return _vals, _cmnt + + +class MsxFile(object): + def __init__(self): + self.sections = dict() + for sec in _INP_SECTIONS: + self.sections[sec] = [] + self.top_comments = [] + self.patterns = dict() + + def read(self, msx_file, rxn_model=None): + """ + Read an EPANET-MSX input file (.msx) and load data into a water quality + reactions model. Only MSX 2.0 files are recognized. + + Parameters + ---------- + msx_file : str + the filename of the .msx file to read in + rxn_model : WaterQualityReactionsModel, optional + the model to put data into, by default None (new model) + + Returns + ------- + WaterQualityReactionsModel + the model with the new species, reactions and other options added + """ + if rxn_model is None: + rxn_model = MultispeciesReactionModel() + self.rxn = rxn_model + # if not isinstance(msx_file, list): + # msx_file = [msx_file] + rxn_model.filename = msx_file + + self.patterns = dict() + self.top_comments = [] + self.sections = dict() + for sec in _INP_SECTIONS: + self.sections[sec] = [] + + def _read(): + section = None + lnum = 0 + edata = {"fname": msx_file} + with open(msx_file, "r", encoding=sys_default_enc) as f: + for line in f: + lnum += 1 + edata["lnum"] = lnum + line = line.strip() + nwords = len(line.split()) + if len(line) == 0 or nwords == 0: + # Blank line + continue + elif line.startswith("["): + vals = line.split(None, 1) + sec = vals[0].upper() + # Add handlers to deal with extra 'S'es (or missing 'S'es) in INP file + if sec not in _INP_SECTIONS: + trsec = sec.replace("]", "S]") + if trsec in _INP_SECTIONS: + sec = trsec + if sec not in _INP_SECTIONS: + trsec = sec.replace("S]", "]") + if trsec in _INP_SECTIONS: + sec = trsec + edata["sec"] = sec + if sec in _INP_SECTIONS: + section = sec + # logger.info('%(fname)s:%(lnum)-6d %(sec)13s section found' % edata) + continue + elif sec == "[END]": + # logger.info('%(fname)s:%(lnum)-6d %(sec)13s end of file found' % edata) + section = None + break + else: + logger.warning('%(fname)s:%(lnum)d: Invalid section "%(sec)s"' % edata) + raise EpanetMsxException(201, note='at line {}:\n{}'.format(lnum, line)) + elif section is None and line.startswith(";"): + self.top_comments.append(line[1:]) + continue + elif section is None: + logger.debug("Found confusing line: %s", repr(line)) + raise EpanetMsxException(201, note='at line {}:\n{}'.format(lnum, line)) + # We have text, and we are in a section + self.sections[section].append((lnum, line)) + try: + _read() + self._read_title() + self._read_options() + self._read_species() + self._read_coefficients() + self._read_terms() + self._read_pipes() + self._read_tanks() + self._read_sources() + self._read_quality() + self._read_parameters() + self._read_diffusivity() + self._read_patterns() + self._read_report() + return self.rxn + except Exception as e: + raise EpanetMsxException(200) from e + + def _read_title(self): + lines = [] + title = None + comments = "" + for lnum, line in self.sections["[TITLE]"]: + vals, comment = _split_line(line) + if title is None and vals is not None: + title = " ".join(vals) + if comment: + lines.append(comment.strip()) + if self.top_comments: + comments = "\n".join(self.top_comments) + if len(lines) > 0: + comments = comments + ("\n" if comments else "") + "\n".join(lines) + self.rxn.title = title + self.rxn.desc = comments + + def _read_options(self): + lines = [] + note = MSXComment() + for lnum, line in self.sections["[OPTIONS]"]: + vals, comment = _split_line(line) + try: + if len(vals) < 2: + raise EpanetMsxException(402, note="at line {} of [OPTIONS] section:\n{}".format(lnum, line)) + name, val = vals[0].upper(), vals[1].upper() + if name == "AREA_UNITS": + self.rxn._options.quality.area_units = val + elif name == "RATE_UNITS": + self.rxn._options.quality.rate_units = val + elif name == "SOLVER": + self.rxn._options.quality.solver = val + elif name == "COUPLING": + self.rxn._options.quality.coupling = val + elif name == "TIMESTEP": + self.rxn._options.quality.timestep = int(val) + elif name == "ATOL": + self.rxn._options.quality.atol = float(val) + elif name == "RTOL": + self.rxn._options.quality.rtol = float(val) + elif name == "COMPILER": + self.rxn._options.quality.compiler = val + elif name == "SEGMENTS": + self.rxn._options.quality.segments = int(val) + elif name == "PECLET": + self.rxn._options.quality.peclet = int(val) + else: + raise EpanetMsxException(403, note='at line {} of [OPTIONS] section:\n{}'.format(lnum, line)) + except ValueError: + raise EpanetMsxException(404, note='at line {} of [OPTIONS] section:\n{}'.format(lnum, line)) + except EpanetMsxException: + raise + except Exception as e: + raise EpanetMsxException(201, note='at line {} of [OPTIONS] section:\n{}'.format(lnum, line)) from e + + def _read_species(self): + lines = [] + note = MSXComment() + for lnum, line in self.sections["[SPECIES]"]: + vals, comment = _split_line(line) + if vals is None: + if comment is not None: + note.pre.append(comment) + continue + try: + if comment is not None: + note.post = comment + if len(vals) < 3: + raise EpanetMsxException(402, note='at line {} of [SPECIES] section:\n{}'.format(lnum, line)) + if len(vals) == 3: + species = self.rxn.add_species(vals[0], vals[1], vals[2], note=note) + elif len(vals) == 5: + species = self.rxn.add_species(vals[0], vals[1], vals[2], float(vals[3]), float(vals[4]), note=note) + else: + raise EpanetMsxException(201, note='at line {} of [SPECIES] section:\n{}'.format(lnum, line)) + except EpanetMsxException: + raise + except Exception as e: + raise EpanetMsxException(201, note='at line {} of [SPECIES] section:\n{}'.format(lnum, line)) from e + else: + note = MSXComment() + + def _read_coefficients(self): + lines = [] + note = MSXComment() + for lnum, line in self.sections["[COEFFICIENTS]"]: + vals, comment = _split_line(line) + if vals is None: + if comment is not None: + note.pre.append(comment) + continue + try: + if comment is not None: + note.post = comment + if len(vals) < 3: + raise EpanetMsxException(402, note='at line {} of [COEFFICIENTS] section:\n{}'.format(lnum, line)) + coeff = self.rxn.add_coefficient(vals[0], vals[1], float(vals[2]), note=note) + except EpanetMsxException: + raise + except Exception as e: + raise EpanetMsxException(201, note='at line {} of [COEFFICIENTS] section:\n{}'.format(lnum, line)) from e + else: + note = MSXComment() + + def _read_terms(self): + lines = [] + note = MSXComment() + for lnum, line in self.sections["[TERMS]"]: + vals, comment = _split_line(line) + if vals is None: + if comment is not None: + note.pre.append(comment) + continue + try: + if comment is not None: + note.post = comment + if len(vals) < 2: + raise SyntaxError("Invalid [TERMS] entry") + term = self.rxn.add_other_term(vals[0], " ".join(vals[1:]), note=note) + except EpanetMsxException: + raise + except Exception as e: + raise EpanetMsxException(201, note='at line {} of [TERMS] section:\n{}'.format(lnum, line)) from e + else: + note = MSXComment() + + def _read_pipes(self): + lines = [] + note = MSXComment() + for lnum, line in self.sections["[PIPES]"]: + vals, comment = _split_line(line) + if vals is None: + if comment is not None: + note.pre.append(comment) + continue + try: + if comment is not None: + note.post = comment + if len(vals) < 3: + raise SyntaxError("Invalid [PIPES] entry") + reaction = self.rxn.add_pipe_reaction(vals[1], vals[0], " ".join(vals[2:]), note=note) + except EpanetMsxException: + raise + except Exception as e: + raise EpanetMsxException(201, note='at line {} of [PIPES] section:\n{}'.format(lnum, line)) from e + else: + note = MSXComment() + + def _read_tanks(self): + lines = [] + note = MSXComment() + for lnum, line in self.sections["[TANKS]"]: + vals, comment = _split_line(line) + if vals is None: + if comment is not None: + note.pre.append(comment) + continue + try: + if comment is not None: + note.post = comment + if len(vals) < 3: + raise SyntaxError("Invalid [TANKS] entry") + reaction = self.rxn.add_tank_reaction(vals[1], vals[0], " ".join(vals[2:]), note=note) + except EpanetMsxException: + raise + except Exception as e: + raise EpanetMsxException(201, note='at line {} of [TANKS] section:\n{}'.format(lnum, line)) from e + else: + note = MSXComment() + + def _read_sources(self): + lines = [] + note = MSXComment() + for lnum, line in self.sections["[SOURCES]"]: + vals, comment = _split_line(line) + if vals is None: + if comment is not None: + note.pre.append(comment) + continue + try: + if comment is not None: + note.post = comment + if len(vals) == 4: + typ, node, spec, strength = vals + pat = None + else: + typ, node, spec, strength, pat = vals + if not self.rxn.has_variable(spec): + raise ValueError("Undefined species in [SOURCES] section: {}".format(spec)) + if spec not in self.rxn._sources.keys(): + self.rxn._sources[spec] = dict() + source = dict(source_type=typ, strength=strength, pattern=pat, note=note) + self.rxn._sources[spec][node] = source + except EpanetMsxException: + raise + except Exception as e: + raise EpanetMsxException(201, note='at line {} of [SOURCES] section:\n{}'.format(lnum, line)) from e + else: + note = MSXComment() + + def _read_quality(self): + lines = [] + note = MSXComment() + for lnum, line in self.sections["[QUALITY]"]: + vals, comment = _split_line(line) + if vals is None: + if comment is not None: + note.pre.append(comment) + continue + try: + if comment is not None: + note.post = comment + if len(vals) == 4: + cmd, netid, spec, concen = vals + else: + cmd, spec, concen = vals + if cmd[0].lower() not in ["g", "n", "l"]: + raise SyntaxError("Unknown first word in [QUALITY] section") + if not self.rxn.has_variable(spec): + raise ValueError("Undefined species in [QUALITY] section: {}".format(spec)) + if spec not in self.rxn._inital_quality.keys(): + self.rxn._inital_quality[spec] = dict(global_value=None, nodes=dict(), links=dict()) + if cmd[0].lower() == "g": + self.rxn._inital_quality[spec]["global_value"] = float(concen) + elif cmd[0].lower() == "n": + self.rxn._inital_quality[spec]["nodes"][netid] = float(concen) + elif cmd[1].lower() == "l": + self.rxn._inital_quality[spec]["links"][netid] = float(concen) + except EpanetMsxException: + raise + except Exception as e: + raise EpanetMsxException(201, note='at line {} of [QUALITY] section:\n{}'.format(lnum, line)) from e + else: + note = MSXComment() + + def _read_parameters(self): + lines = [] + note = MSXComment() + for lnum, line in self.sections["[PARAMETERS]"]: + vals, comment = _split_line(line) + if vals is None: + if comment is not None: + note.pre.append(comment) + continue + try: + if comment is not None: + note.post = comment + typ, netid, paramid, value = vals + coeff = self.rxn.get_variable(paramid) + if not isinstance(coeff, Parameter): + raise ValueError("Invalid parameter {}".format(paramid)) + value = float(value) + if typ.lower()[0] == "p": + coeff.pipe_values[netid] = value + elif typ.lower()[0] == "t": + coeff.tank_values[netid] = value + else: + raise ValueError("Invalid parameter type {}".format(typ)) + except EpanetMsxException: + raise + except Exception as e: + raise EpanetMsxException(201, note='at line {} of [PARAMETERS] section:\n{}'.format(lnum, line)) from e + else: + note = MSXComment() + + def _read_diffusivity(self): + lines = [] + note = MSXComment() + for lnum, line in self.sections["[DIFFUSIVITY]"]: + vals, comment = _split_line(line) + if vals is None: + if comment is not None: + note.pre.append(comment) + continue + try: + if comment is not None: + note.post = comment + if len(vals) != 2: + raise SyntaxError("Invalid [DIFFUSIVITIES] entry") + species = self.rxn.get_variable(vals[0]) + if not isinstance(species, Species): + raise RuntimeError("Invalid species {} in diffusivity".format(vals[0])) + species.diffusivity = float(vals[1]) + except EpanetMsxException: + raise + except Exception as e: + raise EpanetMsxException(201, note='at line {} of [DIFFUSIVITIES] section:\n{}'.format(lnum, line)) from e + else: + note = MSXComment() + + def _read_patterns(self): + _patterns = dict() + for lnum, line in self.sections["[PATTERNS]"]: + # read the lines for each pattern -- patterns can be multiple lines of arbitrary length + line = line.split(";")[0] + current = line.split() + if current == []: + continue + pattern_name = current[0] + if pattern_name not in _patterns: + _patterns[pattern_name] = [] + for i in current[1:]: + _patterns[pattern_name].append(float(i)) + else: + for i in current[1:]: + _patterns[pattern_name].append(float(i)) + for pattern_name, pattern in _patterns.items(): + # add the patterns to the water newtork model + self.rxn.add_pattern(pattern_name, pattern) + + def _read_report(self): + lines = [] + note = MSXComment() + for lnum, line in self.sections["[REPORT]"]: + vals, comment = _split_line(line) + if vals is None: + if comment is not None: + note.pre.append(comment) + continue + try: + if comment is not None: + note.post = comment + if len(vals) == 0: + continue + if len(vals) < 2: + raise SyntaxError("Invalid number of arguments in [REPORT] section") + cmd = vals[0][0].lower() + if cmd == "n": # NODES + if self.rxn._options.report.nodes is None: + if vals[1].upper() == "ALL": + self.rxn._options.report.nodes = "ALL" + else: + self.rxn._options.report.nodes = list() + self.rxn._options.report.nodes.extend(vals[1:]) + elif isinstance(self.rxn._options.report.nodes, list): + if vals[1].upper() == "ALL": + self.rxn._options.report.nodes = "ALL" + else: + self.rxn._options.report.nodes.extend(vals[1:]) + elif cmd == "l": # LINKS + if self.rxn._options.report.links is None: + if vals[1].upper() == "ALL": + self.rxn._options.report.links = "ALL" + else: + self.rxn._options.report.links = list() + self.rxn._options.report.links.extend(vals[1:]) + elif isinstance(self.rxn._options.report.links, list): + if vals[1].upper() == "ALL": + self.rxn._options.report.links = "ALL" + else: + self.rxn._options.report.links.extend(vals[1:]) + elif cmd == "f": + self.rxn._options.report.report_filename = vals[1] + elif cmd == "p": + self.rxn._options.report.pagesize = vals[1] + elif cmd == "s": + if not self.rxn.has_variable(vals[1]): + raise ValueError("Undefined species in [REPORT] section: {}".format(vals[1])) + self.rxn._options.report.species[vals[1]] = True if vals[2].lower().startswith("y") else False + if len(vals) == 4: + self.rxn._options.report.species_precision[vals[1]] = int(vals[3]) + else: + raise SyntaxError("Invalid syntax in [REPORT] section: unknown first word") + except EpanetMsxException: + raise + except Exception as e: + raise EpanetMsxException(201, note='at line {} of [REPORT] section:\n{}'.format(lnum, line)) from e + else: + note = MSXComment() + + def write(self, filename: str, rxn: MultispeciesReactionModel): + self.rxn = rxn + with open(filename, "w") as fout: + + fout.write("; WNTR-reactions MSX file generated {}\n".format(datetime.datetime.now())) + fout.write("\n") + self._write_title(fout) + self._write_options(fout) + self._write_species(fout) + self._write_coefficients(fout) + self._write_terms(fout) + self._write_pipes(fout) + self._write_tanks(fout) + self._write_sources(fout) + self._write_quality(fout) + self._write_diffusivity(fout) + self._write_parameters(fout) + self._write_patterns(fout) + self._write_report(fout) + fout.write("; END of MSX file generated by WNTR\n") + + def _write_title(self, fout): + fout.write("[TITLE]\n") + fout.write(" {}\n".format(self.rxn.title)) + fout.write("\n") + # if self.rxn.desc is not None: + # desc = self.rxn.desc.splitlines() + # desc = " ".join(desc) + # fout.write("; @desc={}\n".format(desc)) + # fout.write("\n") + # if self.rxn.citations is not None: + # if isinstance(self.rxn.citations, list): + # for citation in self.rxn.citations: + # fout.write("; @cite={}\n".format(citation.to_dict() if isinstance(citation, Citation) else str(citation))) + # fout.write("\n") + # else: + # citation = self.rxn.citations + # fout.write("; @cite={}\n".format(citation.to_dict() if isinstance(citation, Citation) else str(citation))) + # fout.write("\n") + + def _write_options(self, fout): + opts = self.rxn._options + fout.write("[OPTIONS]\n") + fout.write(" AREA_UNITS {}\n".format(opts.quality.area_units.upper())) + fout.write(" RATE_UNITS {}\n".format(opts.quality.rate_units.upper())) + fout.write(" SOLVER {}\n".format(opts.quality.solver.upper())) + fout.write(" COUPLING {}\n".format(opts.quality.coupling.upper())) + fout.write(" TIMESTEP {}\n".format(opts.quality.timestep)) + fout.write(" ATOL {}\n".format(opts.quality.atol)) + fout.write(" RTOL {}\n".format(opts.quality.rtol)) + fout.write(" COMPILER {}\n".format(opts.quality.compiler.upper())) + fout.write(" SEGMENTS {}\n".format(opts.quality.segments)) + fout.write(" PECLET {}\n".format(opts.quality.peclet)) + fout.write("\n") + + def _write_species(self, fout): + fout.write("[SPECIES]\n") + for var in self.rxn.variables(var_type=VariableType.BULK): + if isinstance(var.note, MSXComment): + fout.write("{}\n".format(var.note.wrap_msx_string(var.to_msx_string()))) + elif isinstance(var.note, str): + fout.write(" {} ; {}\n".format(var.to_msx_string(), var.note)) + else: + fout.write(" {}\n".format(var.to_msx_string())) + for var in self.rxn.variables(var_type=VariableType.WALL): + if isinstance(var.note, MSXComment): + fout.write("{}\n".format(var.note.wrap_msx_string(var.to_msx_string()))) + elif isinstance(var.note, str): + fout.write(" {} ; {}\n".format(var.to_msx_string(), var.note)) + else: + fout.write(" {}\n".format(var.to_msx_string())) + fout.write("\n") + + def _write_coefficients(self, fout): + fout.write("[COEFFICIENTS]\n") + for var in self.rxn.variables(var_type=VariableType.CONST): + if isinstance(var.note, MSXComment): + fout.write("{}\n".format(var.note.wrap_msx_string(var.to_msx_string()))) + elif isinstance(var.note, str): + fout.write(" {} ; {}\n".format(var.to_msx_string(), var.note)) + else: + fout.write(" {}\n".format(var.to_msx_string())) + for var in self.rxn.variables(var_type=VariableType.PARAM): + if isinstance(var.note, MSXComment): + fout.write("{}\n".format(var.note.wrap_msx_string(var.to_msx_string()))) + elif isinstance(var.note, str): + fout.write(" {} ; {}\n".format(var.to_msx_string(), var.note)) + else: + fout.write(" {}\n".format(var.to_msx_string())) + fout.write("\n") + + def _write_terms(self, fout): + fout.write("[TERMS]\n") + for var in self.rxn.variables(var_type=VariableType.TERM): + if isinstance(var.note, MSXComment): + fout.write("{}\n".format(var.note.wrap_msx_string(var.to_msx_string()))) + elif isinstance(var.note, str): + fout.write(" {} ; {}\n".format(var.to_msx_string(), var.note)) + else: + fout.write(" {}\n".format(var.to_msx_string())) + fout.write("\n") + + def _write_pipes(self, fout): + fout.write("[PIPES]\n") + for var in self.rxn.reactions(location=LocationType.PIPE): + if isinstance(var.note, MSXComment): + fout.write("{}\n".format(var.note.wrap_msx_string(var.to_msx_string()))) + elif isinstance(var.note, str): + fout.write(" {} ; {}\n".format(var.to_msx_string(), var.note)) + else: + fout.write(" {}\n".format(var.to_msx_string())) + fout.write("\n") + + def _write_tanks(self, fout): + fout.write("[TANKS]\n") + for var in self.rxn.reactions(location=LocationType.TANK): + if isinstance(var.note, MSXComment): + fout.write("{}\n".format(var.note.wrap_msx_string(var.to_msx_string()))) + elif isinstance(var.note, str): + fout.write(" {} ; {}\n".format(var.to_msx_string(), var.note)) + else: + fout.write(" {}\n".format(var.to_msx_string())) + fout.write("\n") + + def _write_sources(self, fout): + fout.write("[SOURCES]\n") + for species in self.rxn._sources.keys(): + for node, src in self.rxn._sources[species].items(): + if isinstance(src["note"], MSXComment): + fout.write( + src["note"].wrap_msx_string( + "{:<10s} {:<8s} {:<8s} {:12s} {:<12s}".format(src["source_type"], node, species, src["strength"], src["pattern"] if src["pattern"] is not None else "") + ) + ) + elif isinstance(src["note"], str): + fout.write( + " {:<10s} {:<8s} {:<8s} {} {:<12s} ; {}\n".format( + src["source_type"], node, species, src["strength"], src["pattern"] if src["pattern"] is not None else "", src["note"] + ) + ) + else: + fout.write( + " {:<10s} {:<8s} {:<8s} {} {:<12s}\n".format(src["source_type"], node, species, src["strength"], src["pattern"] if src["pattern"] is not None else "") + ) + if src["note"] is not None: + fout.write("\n") + fout.write("\n") + + def _write_quality(self, fout): + fout.write("[QUALITY]\n") + for species in self.rxn._inital_quality.keys(): + for typ, val in self.rxn._inital_quality[species].items(): + if typ == "global_value": + fout.write(" {:<8s} {:<8s} {}\n".format("GLOBAL", species, val)) + elif typ in ["nodes", "links"]: + for node, conc in val.items(): + fout.write(" {:<8s} {:<8s} {:<8s} {}\n".format(typ.upper()[0:4], node, species, conc)) + fout.write("\n") + + def _write_parameters(self, fout): + fout.write("[PARAMETERS]\n") + for var in self.rxn.variables(var_type=VariableType.PARAM): + had_entries = False + if not isinstance(var, Parameter): + pass + paramID = var.name + for pipeID, value in var.pipe_values.items(): + fout.write(" PIPE {:<8s} {:<8s} {}\n".format(pipeID, paramID, value)) + had_entries = True + for tankID, value in var.tank_values.items(): + fout.write(" PIPE {:<8s} {:<8s} {}\n".format(tankID, paramID, value)) + had_entries = True + if had_entries: + fout.write("\n") + fout.write("\n") + + def _write_patterns(self, fout): + fout.write("[PATTERNS]\n") + for pattern_name, pattern in self.rxn._patterns.items(): + num_columns = 10 + count = 0 + for i in pattern: # .multipliers: + if count % num_columns == 0: + fout.write("\n {:<8s} {:g}".format(pattern_name, i)) + else: + fout.write(" {:g}".format(i)) + count += 1 + fout.write("\n") + fout.write("\n") + + def _write_diffusivity(self, fout): + fout.write("[DIFFUSIVITY]\n") + for name in self.rxn.species_name_list: + spec: Species = self.rxn.get_variable(name) + if spec.diffusivity is not None: + fout.write(" {:<8s} {}\n".format(name, spec.diffusivity)) + fout.write("\n") + + def _write_report(self, fout): + fout.write("[REPORT]\n") + if self.rxn._options.report.nodes is not None: + if isinstance(self.rxn._options.report.nodes, str): + fout.write(" NODES {}\n".format(self.rxn.options.report.nodes)) + else: + fout.write(" NODES {}\n".format(" ".join(self.rxn.options.report.nodes))) + if self.rxn._options.report.links is not None: + if isinstance(self.rxn._options.report.links, str): + fout.write(" LINKS {}\n".format(self.rxn.options.report.links)) + else: + fout.write(" LINKS {}\n".format(" ".join(self.rxn.options.report.links))) + for spec, val in self.rxn._options.report.species.items(): + fout.write( + " SPECIES {:<8s} {:<3s} {}\n".format( + spec, + "YES" if val else "NO", + self.rxn._options.report.species_precision[spec] if spec in self.rxn._options.report.species_precision.keys() else "", + ) + ) + if self.rxn._options.report.report_filename: + fout.write(" FILE {}\n".format(self.rxn._options.report.report_filename)) + if self.rxn._options.report.pagesize: + fout.write(" PAGESIZE {}\n".format(self.rxn._options.report.pagesize)) + fout.write("\n") + + +class MsxBinFile(object): + def __init__(self): + pass + + def read(self, filename): + pass diff --git a/wntr/epanet/msx/toolkit.py b/wntr/epanet/msx/toolkit.py new file mode 100644 index 000000000..9cc971d80 --- /dev/null +++ b/wntr/epanet/msx/toolkit.py @@ -0,0 +1,749 @@ +""" +The wntr.reaction.toolkit module is a Python extension for the EPANET MSX +Programmers Toolkit DLLs. + +.. note:: + + Code in this section taken from code originally written by Junli Hao 07/29/2018, + "EPANET-MSX-Python-wrapper" on GitHub, licensed under the BSD license. See LICENSE.txt for more + details. + + +""" +import ctypes +from enum import IntEnum +import os +import os.path +import platform +import sys +from ctypes import byref +from typing import Union + +from pkg_resources import resource_filename + +from wntr.epanet.msx.enums import ObjectType, SourceType + +from ..toolkit import ENepanet +from ..util import SizeLimits +from .exceptions import EpanetMsxException, MSX_ERROR_CODES, MSXKeyError, MSXValueError + +epanet_toolkit = "wntr.epanet.toolkit" + +if os.name in ["nt", "dos"]: + libepanet = resource_filename(__name__, "../Windows/epanet2.dll") + libmsx = resource_filename(__name__, "../Windows/epanetmsx.dll") +elif sys.platform in ["darwin"]: + libepanet = resource_filename(__name__, "../Darwin/libepanet.dylib") + libmsx = resource_filename(__name__, "../Darwin/libepanetmsx.dylib") +else: + libepanet = resource_filename(__name__, "../Linux/libepanet2.so") + libmsx = resource_filename(__name__, "../Linux/libepanetmsx.so") + +import logging + +logger = logging.getLogger(__name__) + + +class MSXepanet(ENepanet): + def __init__(self, inpfile="", rptfile="", binfile="", msxfile=""): + + self.ENlib = None + self.errcode = 0 + self.errcodelist = [] + self.cur_time = 0 + + self.Warnflag = False + self.Errflag = False + self.fileLoaded = False + + self.inpfile = inpfile + self.rptfile = rptfile + self.binfile = binfile + + libnames = ["epanetmsx", "epanetmsx_win32"] + if "64" in platform.machine(): + libnames.insert(0, "epanetmsx_amd64") + for lib in libnames: + try: + if os.name in ["nt", "dos"]: + libepanet = resource_filename(epanet_toolkit, "Windows/%s.dll" % lib) + self.ENlib = ctypes.windll.LoadLibrary(libepanet) + elif sys.platform in ["darwin"]: + libepanet = resource_filename(epanet_toolkit, "Darwin/lib%s.dylib" % lib) + self.ENlib = ctypes.cdll.LoadLibrary(libepanet) + else: + libepanet = resource_filename(epanet_toolkit, "Linux/lib%s.so" % lib) + self.ENlib = ctypes.cdll.LoadLibrary(libepanet) + return + except Exception as E1: + if lib == libnames[-1]: + raise E1 + pass + finally: + self._project = None + + return + + def _error(self, *args): + """Print the error text the corresponds to the error code returned""" + if not self.errcode: + return + # errtxt = self.ENlib.ENgeterror(self.errcode) + errtext = MSX_ERROR_CODES.get(self.errcode, 'unknown error') + if '%' in errtext and len(args) == 1: + errtext % args + if self.errcode >= 100: + self.Errflag = True + logger.error("EPANET error {} - {}".format(self.errcode, errtext)) + raise EpanetMsxException(self.errcode) + return + + # ----------running the simulation----------------------------------------------------- + def MSXopen(self, msxfile): + """Opens the MSX Toolkit to analyze a particular distribution system. + + Parameters + ---------- + msxfile : str + name of the MSX input file + """ + ierr = self.ENlib.MSXopen(ctypes.c_char_p(msxfile.encode())) + if ierr != 0: + raise EpanetMsxException(ierr, msxfile) + + def MSXclose(self): + """Closes down the Toolkit system (including all files being processed)""" + ierr = self.ENlib.MSXclose() + if ierr != 0: + raise EpanetMsxException(ierr) + + def MSXusehydfile(self, filename): + """Uses the contents of the specified file as the current binary hydraulics file + + Parameters + ---------- + filename : str + Name of the hydraulics file to use + """ + ierr = self.ENlib.MSXusehydfile(ctypes.c_char_p(filename.encode())) + if ierr != 0: + raise EpanetMsxException(ierr, filename) + + def MSXsolveH(self): + """Runs a complete hydraulic simulation with results + for all time periods written to the binary Hydraulics file.""" + ierr = self.ENlib.MSXsolveH() + if ierr != 0: + raise EpanetMsxException(ierr) + + def MSXinit(self, saveFlag=0): + """Initializes the MSX system before solving for water quality results in step-wise fashion + set saveFlag to 1 if water quality results should be saved to a scratch binary file, or to 0 is not saved to file""" + saveFlag = int(saveFlag) + ierr = self.ENlib.MSXinit(saveFlag) + if ierr != 0: + raise EpanetMsxException(ierr) + + def MSXsolveQ(self): + """solves for water quality over the entire simulation period and saves the results to an internal scratch file""" + ierr = self.ENlib.MSXsolveQ() + if ierr != 0: + raise EpanetMsxException(ierr) + + def MSXstep(self): + """Advances the water quality simulation one water quality time step. + The time remaining in the overall simulation is returned as tleft, the current time as t.""" + t = ctypes.c_long() + tleft = ctypes.c_long() + ierr = self.ENlib.MSXstep(ctypes.byref(t), ctypes.byref(tleft)) + if ierr != 0: + raise EpanetMsxException(ierr) + out = [t.value, tleft.value] + return out + + def MSXsaveoutfile(self, filename): + """saves water quality results computed for each node, link and reporting time period to a named binary file + + Parameters + ---------- + filename : str + Save a binary results file + """ + ierr = self.ENlib.MSXsaveoutfile(ctypes.c_char_p(filename.encode())) + if ierr != 0: + raise EpanetMsxException(ierr) + + def MSXsavemsxfile(self, filename): + """saves the data associated with the current MSX project into a new MSX input file + + Parameters + ---------- + filename : str + the name of the MSX input file to create + """ + ierr = self.ENlib.MSXsavemsxfile(ctypes.c_char_p(filename.encode())) + if ierr != 0: + raise EpanetMsxException(ierr, filename) + + def MSXreport(self): + """Writes water quality simulations results as instructed by the MSX input file to a text file""" + ierr = self.ENlib.MSXreport() + if ierr != 0: + raise EpanetMsxException(ierr) + + # ---------get parameters--------------------------------------------------------------- + def MSXgetindex(self, _type: Union[int, ObjectType], name): + """Retrieves the internal index of an MSX object given its name. + + Parameters + ---------- + _type : int, str or ObjectType + The type of object to get an index for + name : str + The name of the object to get an index for + + Returns + ------- + int + The internal index + + Raises + ------ + MSXKeyError + if an invalid str is passed for _type + MSXValueError + if _type is not a valid MSX object type + """ + try: + _type = ObjectType.get(_type) + except KeyError: + raise MSXKeyError(515, repr(_type)) + type_ind = int(_type) + ind = ctypes.c_int() + ierr = self.ENlib.MSXgetindex(type_ind, ctypes.c_char_p(name.encode()), ctypes.byref(ind)) + if ierr != 0: + raise EpanetMsxException(ierr, repr(dict(_type=_type, name=name))) + return ind.value + + def MSXgetIDlen(self, _type, index): + """Retrieves the number of characters in the ID name of an MSX object given its internal index number. + + Parameters + ---------- + _type : int, str or ObjectType + The type of object to get an index for + index : int + The index of the object to get the ID length for + + Returns + ------- + int + the length of the object ID + """ + try: + _type = ObjectType.get(_type) + except KeyError: + raise MSXKeyError(515, repr(_type)) + type_ind = int(_type) + len = ctypes.c_int() + ierr = self.ENlib.MSXgetIDlen(type_ind, ctypes.c_int(index), ctypes.byref(len)) + if ierr != 0: + raise EpanetMsxException(ierr, repr(dict(_type=_type, index=index))) + return len.value + + def MSXgetID(self, _type, index): + """Retrieves the ID name of an object given its internal index number + + Parameters + ---------- + _type : int, str or ObjectType + The type of object to get an index for + index : int + The index of the object to get the ID for + + Returns + ------- + str + the object ID + """ + try: + _type = ObjectType.get(_type) + except KeyError: + raise MSXKeyError(515, repr(_type)) + type_ind = int(_type) + maxlen = 32 + id = ctypes.create_string_buffer(maxlen) + ierr = self.ENlib.MSXgetID(type_ind, ctypes.c_int(index), ctypes.byref(id), ctypes.c_int(maxlen - 1)) + if ierr != 0: + raise EpanetMsxException(ierr, repr(dict(_type=_type, index=index))) + # the .decode() added my MF 6/3/21 + return id.value.decode() + + def MSXgetinitqual(self, _type, node_link_index, species_index): + """Retrieves the initial concentration of a particular chemical species assigned to a specific node + or link of the pipe network + + Parameters + ---------- + _type : str, int or ObjectType + the type of object + node_link_index : int + the object index + species_index : int + the species index + + Returns + ------- + float + the initial quality value for that node or link + + Raises + ------ + MSXKeyError + the type passed in for ``_type`` is not valid + MSXValueError + the value for ``_type`` is not valid + EpanetMsxException + any other error from the C-API + """ + try: + _type = ObjectType.get(_type) + except KeyError: + raise MSXKeyError(515, repr(_type)) + if _type not in [ObjectType.NODE, ObjectType.LINK]: + raise MSXValueError(515, repr(_type)) + type_ind = int(_type) + iniqual = ctypes.c_double() + ierr = self.ENlib.MSXgetinitqual(ctypes.c_int(type_ind), ctypes.c_int(node_link_index), ctypes.c_int(species_index), ctypes.byref(iniqual)) + if ierr != 0: + raise EpanetMsxException(ierr, repr(dict(_type=_type, node_link_index=node_link_index, species_index=species_index))) + return iniqual.value + + def MSXgetqual(self, _type, node_link_index, species_index): + """Retrieves a chemical species concentration at a given node or the average concentration along a link at the current simulation time step + + Parameters + ---------- + _type : str, int or ObjectType + the type of object + node_link_index : int + the object index + species_index : int + the species index + + Returns + ------- + float + the current quality value for that node or link + + Raises + ------ + MSXKeyError + the type passed in for ``_type`` is not valid + MSXValueError + the value for ``_type`` is not valid + EpanetMsxException + any other error from the C-API + """ + try: + _type = ObjectType.get(_type) + except KeyError: + raise MSXKeyError(515, repr(_type)) + if _type not in [ObjectType.NODE, ObjectType.LINK]: + raise MSXValueError(515, repr(_type)) + type_ind = int(_type) + qual = ctypes.c_double() + ierr = self.ENlib.MSXgetqual(ctypes.c_int(type_ind), ctypes.c_int(node_link_index), ctypes.c_int(species_index), ctypes.byref(qual)) + if ierr != 0: + raise EpanetMsxException(ierr, repr(dict(_type=_type, node_link_index=node_link_index, species_index=species_index))) + return qual.value + + def MSXgetconstant(self, constant_index): + """Retrieves the value of a particular reaction constant + + Parameters + ---------- + constant_index : int + index to the constant + + Returns + ------- + float + the value of the constant + + Raises + ------ + EpanetMsxException + a toolkit error occurred + """ + const = ctypes.c_double() + ierr = self.ENlib.MSXgetconstant(constant_index, ctypes.byref(const)) + if ierr != 0: + raise EpanetMsxException(ierr, constant_index) + return const.value + + def MSXgetparameter(self, _type, node_link_index, param_index): + """Retrieves the value of a particular reaction parameter for a given TANK or PIPE. + + Parameters + ---------- + _type : _type_ + _description_ + node_link_index : _type_ + _description_ + param_index : _type_ + _description_ + + Returns + ------- + _type_ + _description_ + + Raises + ------ + MSXKeyError + _description_ + MSXValueError + _description_ + EpanetMsxException + _description_ + """ + try: + _type = ObjectType.get(_type) + except KeyError: + raise MSXKeyError(515, repr(_type)) + if _type not in [ObjectType.NODE, ObjectType.LINK]: + raise MSXValueError(515, repr(_type)) + type_ind = int(_type) + param = ctypes.c_double() + ierr = self.ENlib.MSXgetparameter(ctypes.c_int(type_ind), ctypes.c_int(node_link_index), ctypes.c_int(param_index), ctypes.byref(param)) + if ierr != 0: + raise EpanetMsxException(ierr, repr(dict(_type=_type, node_link_index=node_link_index, param_index=param_index))) + return param.value + + def MSXgetsource(self, node_index, species_index): + """Retrieves information on any external source of a particular chemical species assigned to a specific node of the pipe network + """ + #level is returned with the baseline concentration (or mass flow rate) of the source + #pat is returned with the index of the time pattern used to add variability to the source's baseline level (0 if no pattern defined for the source)""" + level = ctypes.c_double() + _type = ctypes.c_int() + pat = ctypes.c_int() + ierr = self.ENlib.MSXgetsource(ctypes.c_int(node_index), ctypes.c_int(species_index), ctypes.byref(_type), ctypes.byref(level), ctypes.byref(pat)) + if ierr != 0: + raise EpanetMsxException(ierr, repr(dict(node_index=node_index, species_index=species_index))) + src_out = [SourceType.get(_type.value), level.value, pat.value] + return src_out + + def MSXgetpatternlen(self, pat): + """Retrieves the number of time periods within a SOURCE time pattern. + + Parameters + ---------- + pat : _type_ + _description_ + + Returns + ------- + _type_ + _description_ + + Raises + ------ + EpanetMsxException + _description_ + """ + len = ctypes.c_int() + ierr = self.ENlib.MSXgetpatternlen(pat, ctypes.byref(len)) + if ierr != 0: + raise EpanetMsxException(ierr) + return len.value + + def MSXgetpatternvalue(self, pat, period): + """Retrieves the multiplier at a specific time period for a given SOURCE time pattern + + Parameters + ---------- + pat : _type_ + _description_ + period : int + 1-indexed period of the pattern to retrieve + + Returns + ------- + _type_ + _description_ + + Raises + ------ + EpanetMsxException + _description_ + """ + val = ctypes.c_double() + ierr = self.ENlib.MSXgetpatternvalue(pat, period, ctypes.byref(val)) + if ierr != 0: + raise EpanetMsxException(ierr) + return val.value + + def MSXgetcount(self, _type): + """Retrieves the number of objects of a specified type. + + Parameters + ---------- + _type : _type_ + _description_ + + Returns + ------- + _type_ + _description_ + + Raises + ------ + MSXKeyError + _description_ + EpanetMsxException + _description_ + """ + try: + _type = ObjectType.get(_type) + except KeyError: + raise MSXKeyError(515, repr(_type)) + type_ind = int(_type) + count = ctypes.c_int() + ierr = self.ENlib.MSXgetcount(type_ind, ctypes.byref(count)) + if ierr != 0: + raise EpanetMsxException(ierr) + return count.value + + def MSXgetspecies(self, species_index): + """Retrieves the attributes of a chemical species given its internal index number. + species is the sequence number of the species (starting from 1 as listed in the MSX input file + + Parameters + ---------- + species_index : _type_ + _description_ + + Returns + ------- + _type_ + _description_ + + Raises + ------ + EpanetMsxException + _description_ + """ + type_ind = ctypes.c_int() + units = ctypes.create_string_buffer(15) + aTol = ctypes.c_double() + rTol = ctypes.c_double() + ierr = self.ENlib.MSXgetspecies(species_index, ctypes.byref(type_ind), ctypes.byref(units), ctypes.byref(aTol), ctypes.byref(rTol)) + if ierr != 0: + raise EpanetMsxException(ierr) + spe_out = [type_ind.value, units.value, aTol.value, rTol.value] + return spe_out + + def MSXgeterror(self, errcode, len=100): + """returns the text for an error message given its error code + + Parameters + ---------- + errcode : _type_ + _description_ + len : int, optional + _description_, by default 100 and minimum 80 + + Returns + ------- + _type_ + _description_ + """ + errmsg = ctypes.create_string_buffer(len) + self.ENlib.MSXgeterror(errcode, ctypes.byref(errmsg), len) + return errmsg.value.decode() + + # --------------set parameters----------------------------------- + + def MSXsetconstant(self, ind, value): + """assigns a new value to a specific reaction constant + + Parameters + ---------- + ind : _type_ + _description_ + value : _type_ + _description_ + + Raises + ------ + EpanetMsxException + _description_ + """ + ierr = self.ENlib.MSXsetconstant(ctypes.c_int(ind), ctypes.c_double(value)) + if ierr != 0: + raise EpanetMsxException(ierr) + + def MSXsetparameter(self, _type, ind, param, value): + """assigns a value to a particular reaction parameter for a given TANK or PIPE + + Parameters + ---------- + _type : _type_ + _description_ + ind : _type_ + _description_ + param : _type_ + _description_ + value : _type_ + _description_ + + Raises + ------ + MSXKeyError + _description_ + MSXValueError + _description_ + EpanetMsxException + _description_ + """ + try: + _type = ObjectType.get(_type) + except KeyError: + raise MSXKeyError(515, repr(_type)) + if _type not in [ObjectType.NODE, ObjectType.LINK]: + raise MSXValueError(515, repr(_type)) + type_ind = int(_type) + ierr = self.ENlib.MSXsetparameter(ctypes.c_int(type_ind), ctypes.c_int(ind), ctypes.c_int(param), ctypes.c_double(value)) + if ierr != 0: + raise EpanetMsxException(ierr) + + def MSXsetinitqual(self, _type, ind, spe, value): + """Retrieves the initial concentration of a particular chemical species assigned to a specific node + or link of the pipe network. + + Parameters + ---------- + _type : _type_ + _description_ + ind : _type_ + _description_ + spe : _type_ + _description_ + value : _type_ + _description_ + + Raises + ------ + MSXKeyError + _description_ + MSXValueError + _description_ + EpanetMsxException + _description_ + """ + try: + _type = ObjectType.get(_type) + except KeyError: + raise MSXKeyError(515, repr(_type)) + if _type not in [ObjectType.NODE, ObjectType.LINK]: + raise MSXValueError(515, repr(_type)) + type_ind = int(_type) + ierr = self.ENlib.MSXsetinitqual(ctypes.c_int(type_ind), ctypes.c_int(ind), ctypes.c_int(spe), ctypes.c_double(value)) + if ierr != 0: + raise EpanetMsxException(ierr) + + def MSXsetsource(self, node, spe, _type, level, pat): + """sets the attributes of an external source of a particular chemical species in a specific node of the pipe network + + Parameters + ---------- + node : _type_ + _description_ + spe : _type_ + _description_ + _type : _type_ + _description_ + level : _type_ + _description_ + pat : _type_ + _description_ + + Raises + ------ + MSXKeyError + _description_ + EpanetMsxException + _description_ + """ + try: + _type = SourceType.get(_type) + except KeyError: + raise MSXKeyError(515, repr(_type)) + type_ind = int(_type) + ierr = self.ENlib.MSXsetsource(ctypes.c_int(node), ctypes.c_int(spe), ctypes.c_int(type_ind), ctypes.c_double(level), ctypes.c_int(pat)) + if ierr != 0: + raise EpanetMsxException(ierr) + + def MSXsetpattern(self, pat, mult): + """assigns a new set of multipliers to a given MSX SOURCE time pattern + + Parameters + ---------- + pat : _type_ + _description_ + mult : _type_ + _description_ + + Raises + ------ + EpanetMsxException + _description_ + """ + length = len(mult) + cfactors_type = ctypes.c_double * length + cfactors = cfactors_type() + for i in range(length): + cfactors[i] = float(mult[i]) + ierr = self.ENlib.MSXsetpattern(ctypes.c_int(pat), cfactors, ctypes.c_int(length)) + if ierr != 0: + raise EpanetMsxException(ierr) + + def MSXsetpatternvalue(self, pat, period, value): + """Sets the multiplier factor for a specific period within a SOURCE time pattern. + + Parameters + ---------- + pat : _type_ + _description_ + period : _type_ + _description_ + value : _type_ + _description_ + + Raises + ------ + EpanetMsxException + _description_ + """ + ierr = self.ENlib.MSXsetpatternvalue(ctypes.c_int(pat), ctypes.c_int(period), ctypes.c_double(value)) + if ierr != 0: + raise EpanetMsxException(ierr) + + def MSXaddpattern(self, patternid): + """Adds a new, empty MSX source time pattern to an MSX project. + + Parameters + ---------- + patternid : _type_ + _description_ + + Raises + ------ + EpanetMsxException + _description_ + """ + ierr = self.ENlib.MSXaddpattern(ctypes.c_char_p(patternid.encode())) + if ierr != 0: + raise EpanetMsxException(ierr) diff --git a/wntr/network/io.py b/wntr/network/io.py index 684388037..bde165583 100644 --- a/wntr/network/io.py +++ b/wntr/network/io.py @@ -70,7 +70,7 @@ def to_dict(wn) -> dict: version="wntr-{}".format(__version__), comment="WaterNetworkModel - all values given in SI units", name=wn.name, - citations=wntr.utils.citations.to_jsontypes(wn.citations), + citations=wntr.utils.citations.to_jsontypes(wn._citations), options=wn._options.to_dict(), curves=wn._curve_reg.to_list(), patterns=wn._pattern_reg.to_list(), @@ -124,7 +124,7 @@ def from_dict(d: dict, append=None): if "name" in d: wn.name = d["name"] if "citations" in d: - wn.citations = wntr.utils.citations.from_jsontypes(d["citations"]) + wn._citations = wntr.utils.citations.from_jsontypes(d["citations"]) if "options" in d: wn.options.__init__(**d["options"]) if "curves" in d: diff --git a/wntr/network/model.py b/wntr/network/model.py index 3c235e797..346a01f8d 100644 --- a/wntr/network/model.py +++ b/wntr/network/model.py @@ -73,7 +73,7 @@ def __init__(self, inp_file_name=None): # Network name self.name = None - self.citations: Union[str,Citation, List[Union[str,Citation]]] = list() + self._citations: Union[str,Citation, List[Union[str,Citation]]] = list() """A list of citations that document the source of this model. See also :class:`~wntr.utils.citations.Citation`.""" self._options = Options() diff --git a/wntr/reaction/__init__.py b/wntr/reaction/__init__.py index d8a87d3b8..7c166da59 100644 --- a/wntr/reaction/__init__.py +++ b/wntr/reaction/__init__.py @@ -5,4 +5,9 @@ # pyomo.dae # sympy -from . import base, dynamics, model, io, options, toolkitmsx, variables, library +from .base import VariableType, LocationType, DynamicsType, ReactionDynamics, ReactionVariable +from .options import MultispeciesOptions +from .variables import Species, OtherTerm, InternalVariable, BulkSpecies, WallSpecies, Parameter, Coefficient, Constant +from .dynamics import RateDynamics, FormulaDynamics, EquilibriumDynamics +from ..epanet.msx.exceptions import EpanetMsxException +from .model import MultispeciesReactionModel \ No newline at end of file diff --git a/wntr/reaction/base.py b/wntr/reaction/base.py index bd4e4c407..e795d8256 100644 --- a/wntr/reaction/base.py +++ b/wntr/reaction/base.py @@ -4,31 +4,38 @@ The base classes for the the wntr.reaction module. Other than the enum classes, the classes in this module are all abstract and/or mixin classes, and should not be instantiated directly. + +.. rubric:: Contents + +.. autosummary:: + + VariableType + LocationType + DynamicsType + ReactionVariable + ReactionDynamics + AbstractReactionModel + LinkedVariablesMixin + ExpressionMixin + MsxObjectMixin + MSXComment + """ import abc import enum import logging from abc import ABC, abstractmethod, abstractproperty -from collections.abc import MutableMapping from dataclasses import InitVar, dataclass, field from enum import Enum, IntFlag from typing import ( - Any, ClassVar, - Dict, Generator, - Hashable, - ItemsView, - Iterator, - KeysView, List, - Set, - Tuple, Union, - ValuesView, ) + has_sympy = False try: from sympy import Float, Symbol, init_printing, symbols @@ -44,8 +51,8 @@ has_sympy = False from wntr.network.model import WaterNetworkModel - -from .options import RxnOptions +from wntr.utils.enumtools import add_get +from wntr.reaction.options import MultispeciesOptions logger = logging.getLogger(__name__) @@ -75,19 +82,8 @@ """The sympy transforms to use in expression parsing""" -class KeyInOtherGroupError(KeyError): - """The key exists but is in a different disjoint group""" - - pass - - -class VariableNameExistsError(KeyError): - """The name already exists in the reaction model""" - - pass - - -class RxnVariableType(Enum): +@add_get(abbrev=True) +class VariableType(Enum): """The type of reaction variable. The following types are defined, and aliases of just the first character @@ -108,7 +104,7 @@ class RxnVariableType(Enum): .. autosummary:: - factory + get """ @@ -142,42 +138,9 @@ class RxnVariableType(Enum): PARAM = PARAMETER """Alias for :attr:`PARAMETER`""" - @classmethod - def factory(cls, value: Union[str, int, "RxnVariableType"]) -> "RxnVariableType": - """Convert a value to a valid RxnVariableType. - Parameters - ---------- - value : str or int or RxnVariableType - the value to change - - Returns - ------- - RxnVariableType - the equivalent variable type enum - - Raises - ------ - KeyError - the value is unknown/undefined - TypeError - the type of the value is wrong - """ - if value is None: - return - if isinstance(value, cls): - return value - if isinstance(value, int): - return cls(value) - if isinstance(value, str): - try: - return cls[value[0].upper()] - except KeyError: - raise KeyError(value) - raise TypeError("Invalid type '{}'".format(type(value))) - - -class RxnLocationType(Enum): +@add_get(abbrev=True) +class LocationType(Enum): """What type of network component does this reaction occur in The following types are defined, and aliases of just the first character @@ -195,7 +158,7 @@ class RxnLocationType(Enum): .. autosummary:: - factory + get """ @@ -208,42 +171,9 @@ class RxnLocationType(Enum): T = TANK """Alias for :attr:`TANK`""" - @classmethod - def factory(cls, value: Union[str, int, "RxnLocationType"]) -> "RxnLocationType": - """Convert a value to a valid RxnLocationType. - - Parameters - ---------- - value : str or int or RxnLocationType - the value to process - Returns - ------- - RxnLocationType - the equivalent enum object - - Raises - ------ - KeyError - the value is unknown/undefined - TypeError - the type of the value is wrong - """ - if value is None: - return - if isinstance(value, cls): - return value - if isinstance(value, int): - return cls(value) - if isinstance(value, str): - try: - return cls[value[0].upper()] - except KeyError: - raise KeyError(value) - raise TypeError("Invalid type '{}'".format(type(value))) - - -class RxnDynamicsType(Enum): +@add_get(abbrev=True) +class DynamicsType(Enum): """The type of reaction expression. The following types are defined, and aliases of just the first character @@ -261,7 +191,7 @@ class RxnDynamicsType(Enum): .. autosummary:: - factory + get """ @@ -278,224 +208,9 @@ class RxnDynamicsType(Enum): F = FORMULA """Alias for :attr:`FORMULA`""" - @classmethod - def factory(cls, value: Union[str, int, "RxnDynamicsType"]) -> "RxnDynamicsType": - """Convert a value to a RxnDynamicsType. - - Parameters - ---------- - value : str or int or RxnDynamicsType - the value to convert - - Returns - ------- - RxnDynamicsType - the enum value - - Raises - ------ - KeyError - the value is unknown/undefined - TypeError - the type of the value is wrong - """ - if value is None: - return - if isinstance(value, cls): - return value - if isinstance(value, int): - return cls(value) - if isinstance(value, str): - try: - return cls[value[0].upper()] - except KeyError: - raise KeyError(value) - raise TypeError("Invalid type '{}'".format(type(value))) - - -class DisjointMapping(MutableMapping): - - __data: Dict[Hashable, Hashable] = None - __key_groupnames: Dict[Hashable, str] = None - __groups: Dict[str, "DisjointMappingGroup"] = None - __usage: Dict[Hashable, Set[Any]] = None - - def __init__(self, *args, **kwargs): - self.__data: Dict[Hashable, Any] = dict(*args, **kwargs) - self.__key_groupnames: Dict[Hashable, str] = dict() - self.__groups: Dict[str, "DisjointMappingGroup"] = dict() - self.__usage: Dict[Hashable, Set[Any]] = dict() - for k, v in self.__data.items(): - self.__key_groupnames[k] = None - self.__usage[k] = set() - - def add_disjoint_group(self, name): - if name in self.__groups.keys(): - raise KeyError("Disjoint group already exists within registry") - new = DisjointMappingGroup(name, self) - self.__groups.__setitem__(name, new) - return new - - def get_disjoint_group(self, name: str): - return self.__groups[name] - - def get_groupname(self, __key: Hashable): - return self.__key_groupnames[__key] - - def add_item_to_group(self, groupname, key, value): - current = self.__key_groupnames.get(key, None) - if current is not None and groupname != current: - raise KeyInOtherGroupError("The key '{}' is already used in a different group '{}'".format(key, groupname)) - if groupname is not None: - group = self.__groups[groupname] - group._data.__setitem__(key, value) - self.__key_groupnames[key] = groupname - return self.__data.__setitem__(key, value) - - def move_item_to_group(self, new_group_name, key): - value = self.__data[key] - current = self.get_groupname(key) - if new_group_name is not None: - new_group = self.__groups[new_group_name] - new_group._data[key] = value - if current is not None: - old_group = self.__groups[current] - old_group._data.__delitem__(key) - self.__key_groupnames[key] = new_group_name - - def remove_item_from_group(self, groupname, key): - current = self.__key_groupnames.get(key, None) - if groupname != current: - raise KeyInOtherGroupError("The key '{}' is in a different group '{}'".format(key, groupname)) - if groupname is not None: - self.__groups[groupname]._data.__delitem__(key) - - def __getitem__(self, __key: Any) -> Any: - return self.__data.__getitem__(__key) - - def __setitem__(self, __key: Any, __value: Any) -> None: - current = self.__key_groupnames.get(__key, None) - if current is not None: - self.__groups[current]._data[__key] = __value - return self.__data.__setitem__(__key, __value) - - def __delitem__(self, __key: Any) -> None: - current = self.__key_groupnames.get(__key, None) - if current is not None: - self.__groups[current]._data.__delitem__(__key) - return self.__data.__delitem__(__key) - - def __contains__(self, __key: object) -> bool: - return self.__data.__contains__(__key) - - def __iter__(self) -> Iterator: - return self.__data.__iter__() - - def __len__(self) -> int: - return self.__data.__len__() - - def keys(self) -> KeysView: - return self.__data.keys() - - def items(self) -> ItemsView: - return self.__data.items() - - def values(self) -> ValuesView: - return self.__data.values() - - def clear(self) -> None: - raise RuntimeError("You cannot clear this") - - def popitem(self) -> tuple: - raise RuntimeError("You cannot pop this") - - -class DisjointMappingGroup(MutableMapping): - """A dictionary that checks a namespace for existing entries. - - To create a new instance, pass a set to act as a namespace. If the namespace does not - exist, a new namespace will be instantiated. If it does exist, then a new, disjoint - dictionary will be created that checks the namespace keys before it will allow a new - item to be added to the dictionary. An item can only belong to one of the disjoint dictionaries - associated with the namespace. - - Examples - -------- - Assume there is a namespace `nodes` that has two distinct subsets of objects, `tanks` - and `reservoirs`. A name for a tank cannot also be used for a reservoir, and a node - cannot be both a `tank` and a `reservoir`. A DisjointNamespaceDict allows two separate - dictionaries to be kept, one for each subtype, but the keys within the two dictionaries - will be ensured to not overlap. - - Parameters - ---------- - __keyspace : set - the name of the namespace for consistency checking - *args, **kwargs : Any - regular arguments and keyword arguments passed to the underlying dictionary - - """ - - __name: str = None - __keyspace: DisjointMapping = None - _data: dict = None - - def __new__(cls, name: str, __keyspace: DisjointMapping): - if name is None: - raise TypeError("A name must be specified") - if __keyspace is None: - raise TypeError("A registry must be specified") - newobj = super().__new__(cls) - return newobj - - def __init__(self, name: str, __keyspace: DisjointMapping): - if name is None: - raise TypeError("A name must be specified") - if __keyspace is None: - raise TypeError("A registry must be specified") - self.__name: str = name - self.__keyspace: DisjointMapping = __keyspace - self._data = dict() - - def __getitem__(self, __key: Any) -> Any: - return self._data[__key] - - def __setitem__(self, __key: Any, __value: Any) -> None: - return self.__keyspace.add_item_to_group(self.__name, __key, __value) - - def __delitem__(self, __key: Any) -> None: - return self.__keyspace.remove_item_from_group(self.__name, __key) - - def __contains__(self, __key: object) -> bool: - return self._data.__contains__(__key) - - def __iter__(self) -> Iterator: - return self._data.__iter__() - - def __len__(self) -> int: - return self._data.__len__() - - def keys(self) -> KeysView: - return self._data.keys() - - def items(self) -> ItemsView: - return self._data.items() - - def values(self) -> ValuesView: - return self._data.values() - - def clear(self) -> None: - raise RuntimeError("Cannot clear a group") - - def popitem(self) -> tuple: - raise RuntimeError("Cannot pop from a group") - - def __repr__(self) -> str: - return "{}(name={}, data={})".format(self.__class__.__name__, repr(self.__name), self._data) - @dataclass -class RxnVariable(ABC): +class ReactionVariable(ABC): """The base for a reaction variable. Parameters @@ -516,7 +231,7 @@ def __hash__(self) -> int: return hash(str(self)) @abstractproperty - def var_type(self) -> RxnVariableType: + def var_type(self) -> VariableType: """The variable type.""" raise NotImplementedError @@ -528,7 +243,7 @@ def is_species(self) -> bool: bool True if this is a species object, False otherwise """ - return self.var_type == RxnVariableType.BULK or self.var_type == RxnVariableType.WALL + return self.var_type == VariableType.BULK or self.var_type == VariableType.WALL def is_coeff(self) -> bool: """Check to see if this variable represents a coefficient (constant or parameter). @@ -538,9 +253,9 @@ def is_coeff(self) -> bool: bool True if this is a coefficient object, False otherwise """ - return self.var_type == RxnVariableType.CONST or self.var_type == RxnVariableType.PARAM + return self.var_type == VariableType.CONST or self.var_type == VariableType.PARAM - def is_term_function(self) -> bool: + def is_other_term(self) -> bool: """Check to see if this variable represents a function (MSX term). Returns @@ -548,7 +263,7 @@ def is_term_function(self) -> bool: bool True if this is a term/function object, False otherwise """ - return self.var_type == RxnVariableType.TERM + return self.var_type == VariableType.TERM @property def symbol(self): @@ -557,7 +272,7 @@ def symbol(self): @dataclass -class RxnReaction(ABC): +class ReactionDynamics(ABC): """The base for a reaction. Parameters @@ -572,7 +287,7 @@ class RxnReaction(ABC): species: str """The name of the species that this reaction describes""" - location: RxnLocationType + location: LocationType """The location this reaction occurs (pipes vs tanks)""" expression: str """The expression for the reaction dynamics (or, the right-hand-side of the equation)""" @@ -586,7 +301,7 @@ def __hash__(self) -> int: return hash(str(self)) @abstractproperty - def expr_type(self) -> RxnDynamicsType: + def expr_type(self) -> DynamicsType: """The type of reaction dynamics being described (or, the left-hand-side of the equation)""" raise NotImplementedError @@ -607,23 +322,23 @@ def to_key(cls, species, location): str a species/location unique name """ - location = RxnLocationType.factory(location) + location = LocationType.get(location) return str(species) + "." + location.name.lower() -class RxnModelRegistry(ABC): +class AbstractReactionModel(ABC): @abstractmethod def variables(self, var_type=None): """Generator over all defined variables, optionally limited by variable type""" raise NotImplementedError @abstractmethod - def add_variable(self, __variable: RxnVariable): + def add_variable(self, __variable: ReactionVariable): """Add a variable *object* to the model""" raise NotImplementedError @abstractmethod - def get_variable(self, name: str) -> RxnVariable: + def get_variable(self, name: str) -> ReactionVariable: """Get a specific variable by name""" raise NotImplementedError @@ -638,12 +353,12 @@ def reactions(self, location=None): raise NotImplementedError @abstractmethod - def add_reaction(self, __reaction: RxnReaction): + def add_reaction(self, __reaction: ReactionDynamics): """Add a reaction *object* to the model""" raise NotImplementedError @abstractmethod - def get_reaction(self, species, location=None) -> List[RxnReaction]: + def get_reaction(self, species, location=None) -> List[ReactionDynamics]: """Get reaction(s) for a species, optionally only for one location""" raise NotImplementedError @@ -658,12 +373,12 @@ class LinkedVariablesMixin: __variable_registry = None @property - def _variable_registry(self) -> RxnModelRegistry: + def _variable_registry(self) -> AbstractReactionModel: return self.__variable_registry @_variable_registry.setter def _variable_registry(self, value): - if value is not None and not isinstance(value, RxnModelRegistry): + if value is not None and not isinstance(value, AbstractReactionModel): raise TypeError("Linked model must be a RxnModelRegistry, got {}".format(type(value))) self.__variable_registry = value @@ -675,7 +390,7 @@ def validate(self): TypeError if the model registry isn't linked """ - if not isinstance(self._variable_registry, RxnModelRegistry): + if not isinstance(self._variable_registry, AbstractReactionModel): raise TypeError("This object is not connected to any RxnModelRegistry") @@ -700,7 +415,7 @@ def to_symbolic(self, transformations=EXPR_TRANSFORMS): return parse_expr(self.expression, transformations=transformations) -class MSXObject: +class MsxObjectMixin: def to_msx_string(self) -> str: """Get the expression as an EPANET-MSX input-file style string. @@ -711,6 +426,7 @@ def to_msx_string(self) -> str: """ raise NotImplementedError + @dataclass class MSXComment: pre: List[str] = field(default_factory=list) @@ -727,3 +443,4 @@ def wrap_msx_string(self, string) -> str: else: return '\n; ' + '\n\n; '.join(self.pre) + '\n\n ' + string + ' ; ' + self.post + diff --git a/wntr/reaction/dynamics.py b/wntr/reaction/dynamics.py index b7e50f3ac..3f64d50fc 100644 --- a/wntr/reaction/dynamics.py +++ b/wntr/reaction/dynamics.py @@ -20,7 +20,6 @@ \frac{d}{dt}C(species) = f(vars,...) - The classes in this module can be created directly. However, they are more powerful when either, a) created using API calls on a :class:`~wntr.reaction.model.WaterNetworkModel`, or, b) linked to a :class:`~wntr.reaction.model.WaterNetworkModel` model object after creation. @@ -30,12 +29,22 @@ that will convert object instances of these classes into sympy expressions and symbols. If the instances are linked to a model, then expressions can be expanded, validated, and even evaluated or simplified symbolically. + +.. rubric:: Contents + +.. autosummary:: + + RateDynamics + EquilibriumDynamics + FormulaDynamics + """ import enum import logging from dataclasses import InitVar, asdict, dataclass, field from enum import Enum, IntFlag from typing import Any, ClassVar, Dict, List, Set, Tuple, Union +from .base import MSXComment has_sympy = False try: @@ -52,17 +61,16 @@ has_sympy = False from wntr.network.model import WaterNetworkModel -from wntr.reaction.base import EXPR_TRANSFORMS, MSXObject, RxnVariableType +from wntr.reaction.base import EXPR_TRANSFORMS, MsxObjectMixin, VariableType from .base import ( ExpressionMixin, LinkedVariablesMixin, - MSXComment, - RxnDynamicsType, - RxnLocationType, - RxnModelRegistry, - RxnReaction, - RxnVariableType, + DynamicsType, + LocationType, + AbstractReactionModel, + ReactionDynamics, + VariableType, ) from .variables import Coefficient, Species, OtherTerm @@ -70,7 +78,7 @@ @dataclass(repr=False) -class RateDynamics(MSXObject, LinkedVariablesMixin, ExpressionMixin, RxnReaction): +class RateDynamics(MsxObjectMixin, LinkedVariablesMixin, ExpressionMixin, ReactionDynamics): r"""Used to supply the equation that expresses the rate of change of the given species with respect to time as a function of the other species in the model. @@ -94,15 +102,15 @@ class RateDynamics(MSXObject, LinkedVariablesMixin, ExpressionMixin, RxnReaction """ note: Union[str, Dict[str, str]] = None """A note or comment about this species reaction dynamics""" - variable_registry: InitVar[RxnModelRegistry] = field(default=None, compare=False) + variable_registry: InitVar[AbstractReactionModel] = field(default=None, compare=False) """A link to the reaction model with variables""" def __post_init__(self, variable_registry): self._variable_registry = variable_registry @property - def expr_type(self) -> RxnDynamicsType: - return RxnDynamicsType.RATE + def expr_type(self) -> DynamicsType: + return DynamicsType.RATE def to_symbolic(self, transformations=...): return super().to_symbolic(transformations) @@ -123,7 +131,7 @@ def to_dict(self) -> dict: @dataclass(repr=False) -class EquilibriumDynamics(MSXObject, LinkedVariablesMixin, ExpressionMixin, RxnReaction): +class EquilibriumDynamics(MsxObjectMixin, LinkedVariablesMixin, ExpressionMixin, ReactionDynamics): """Used for equilibrium expressions where it is assumed that the expression supplied is being equated to zero. .. math:: @@ -147,15 +155,15 @@ class EquilibriumDynamics(MSXObject, LinkedVariablesMixin, ExpressionMixin, RxnR note: Union[str, Dict[str, str]] = None """A note or comment about this species reaction dynamics""" - variable_registry: InitVar[RxnModelRegistry] = field(default=None, compare=False) + variable_registry: InitVar[AbstractReactionModel] = field(default=None, compare=False) """A link to the reaction model with variables""" def __post_init__(self, variable_registry): self._variable_registry = variable_registry @property - def expr_type(self) -> RxnDynamicsType: - return RxnDynamicsType.EQUIL + def expr_type(self) -> DynamicsType: + return DynamicsType.EQUIL def to_symbolic(self, transformations=...): return super().to_symbolic(transformations) @@ -175,7 +183,7 @@ def to_dict(self) -> dict: @dataclass(repr=False) -class FormulaDynamics(MSXObject, LinkedVariablesMixin, ExpressionMixin, RxnReaction): +class FormulaDynamics(MsxObjectMixin, LinkedVariablesMixin, ExpressionMixin, ReactionDynamics): """Used when the concentration of the named species is a simple function of the remaining species. .. math:: @@ -199,15 +207,15 @@ class FormulaDynamics(MSXObject, LinkedVariablesMixin, ExpressionMixin, RxnReact note: Union[str, Dict[str, str]] = None """A note or comment about this species reaction dynamics""" - variable_registry: InitVar[RxnModelRegistry] = field(default=None, compare=False) + variable_registry: InitVar[AbstractReactionModel] = field(default=None, compare=False) """A link to the reaction model with variables""" def __post_init__(self, variable_registry): self._variable_registry = variable_registry @property - def expr_type(self) -> RxnDynamicsType: - return RxnDynamicsType.FORMULA + def expr_type(self) -> DynamicsType: + return DynamicsType.FORMULA def to_symbolic(self, transformations=...): return super().to_symbolic(transformations) diff --git a/wntr/reaction/exceptions.py b/wntr/reaction/exceptions.py deleted file mode 100644 index bffb41070..000000000 --- a/wntr/reaction/exceptions.py +++ /dev/null @@ -1,189 +0,0 @@ -# coding: utf-8 -"""EPANET-MSX error and exception classes.""" - -from enum import IntEnum -from typing import List -from ..epanet.exceptions import EpanetException, EN_ERROR_CODES, EpanetErrorEnum - - -MSX_ERROR_CODES = EN_ERROR_CODES.copy() -MSX_ERROR_CODES.update({ - # MSX syntax errors - 401: "too many characters", - 402: "too few input items", - 403: "invalid keyword: '%s'", - 404: "invalid numeric value: '%s'", - 405: "reference to undefined object: '%s'", - 406: "illegal use of reserved name: '%s'", - 407: "name already used by another object: '%s'", - 408: "species already assigned an expression: '%s'", - 409: "illegal math expression", - 410: "option no longer supported", - 411: "term '%s' contains a cyclic reference", - # MSX runtime errors - 501: "insufficient memory available", - 502: "no EPANET data file supplied", - 503: "could not open MSX input file", - 504: "could not open hydraulic results file", - 505: "could not read hydraulic results file", - 506: "could not read MSX input file", - 507: "too few pipe reaction expressions", - 508: "too few tank reaction expressions", - 509: "could not open differential equation solver", - 510: "could not open algebraic equation solver", - 511: "could not open binary results file", - 512: "read/write error on binary results file", - 513: "could not integrate reaction rate expressions", - 514: "could not solve reaction equilibrium expressions", - 515: "reference made to an unknown type of object", - 516: "reference made to an illegal object index", - 517: "reference made to an undefined object ID", - 518: "invalid property values were specified", - 519: "an MSX project was not opened", - 520: "an MSX project is already opened", - 522: "could not compile chemistry functions", - 523: "could not load functions from compiled chemistry file", - 524: "illegal math operation", -}) - -class MSXErrors(IntEnum): - too_many_chars_msx = 401 - too_few_items = 402 - invalid_keyword = 403 - invalid_numeric_value_msx = 404 - undefined_msx_object = 405 - illegal_reserved_name = 406 - name_in_use = 407 - species_already_assigned = 408 - illegal_math_expression = 409 - option_deprecated = 410 - cyclic_reference = 411 - insufficient_memory_msx = 501 - no_epanet_datafile = 502 - open_msx_fail = 503 - open_hyd_fail_msx = 504 - read_hyd_fail_msx = 505 - read_msx_fail = 506 - not_enough_pipe_reactions = 507 - not_enough_tank_reactions = 508 - open_de_solver_fail = 509 - open_ae_solver_fail = 510 - open_bin_fail_msx = 511 - io_error_msx_bin = 512 - solve_rate_failed = 513 - solve_equil_failed = 514 - unknown_object_type = 515 - illegal_object_index = 516 - undefined_object_id = 517 - invalid_property_value = 518 - msx_project_not_open = 519 - msx_project_open = 520 - compile_chem_failed = 522 - load_compiled_chem_failed = 523 - illegal_math_operation = 524 - insufficient_memory = 101 - no_network = 102 - no_init_hyd = 103 - no_hydraulics = 104 - no_init_qual = 105 - no_results = 106 - hyd_file = 107 - hyd_init_and_hyd_file = 108 - modify_time_during_solve = 109 - solve_hyd_fail = 110 - solve_qual_fail = 120 - input_file_error = 200 - syntax_error = 201 - illegal_numeric_value = 202 - undefined_node = 203 - undefined_link = 204 - undefined_pattern = 205 - undefined_curve = 206 - control_on_cv_gpv = 207 - illegal_pda_limits = 208 - illegal_node_property = 209 - illegal_link_property = 211 - undefined_trace_node = 212 - invalid_option_value = 213 - too_many_chars_inp = 214 - duplicate_id = 215 - undefined_pump = 216 - invalid_energy_value = 217 - illegal_valve_tank = 219 - illegal_tank_valve = 219 - illegal_valve_valve = 220 - misplaced_rule = 221 - link_to_self = 222 - not_enough_nodes = 223 - no_tanks_or_res = 224 - invalid_tank_levels = 225 - missing_pump_data = 226 - invalid_head_curve = 227 - nonincreasing_x_curve = 230 - unconnected_node = 233 - unconnected_node_id = 234 - no_such_source_node = 240 - no_such_control = 241 - invalid_name_format = 250 - invalid_parameter_code = 251 - invalid_id_name = 252 - no_such_demand_category = 253 - missing_coords = 254 - invalid_vertex = 255 - no_such_rule = 257 - no_such_rule_clause = 258 - delete_node_still_linked = 259 - delete_node_is_trace = 260 - delete_node_in_control = 261 - modify_network_during_solve = 262 - node_not_a_tank = 263 - same_file_names = 301 - open_inp_fail = 302 - open_rpt_fail = 303 - open_bin_fail = 304 - open_hyd_fail = 305 - hyd_file_different_network = 306 - read_hyd_fail = 307 - save_bin_fail = 308 - save_rpt_fail = 309 - -class EpanetMsxException(EpanetException): - def __init__(self, code: int, *args: List[object], line_num=None, line=None) -> None: - if isinstance(code, (EpanetErrorEnum, MSXErrors)): - code = int(code) - elif isinstance(code, str): - try: - code = code.strip().replace('-','_').replace(' ','_') - code = int(MSXErrors[code]) - except KeyError: - return super(Exception, self).__init__('unknown error code: {}'.format(repr(code)), *args) - elif not isinstance(code, int): - return super(Exception, self).__init__('unknown error code: {}'.format(repr(code)), *args) - msg = MSX_ERROR_CODES.get(code, 'unknown error') - if args is not None: - args = [*args] - if r'%' in msg and len(args) > 0: - msg = msg % args.pop(0) - if len(args) > 0: - msg = msg + ' ' + str(args) - if line_num: - msg = msg + ", at line {}".format(line_num) - if line: - msg = msg + ':\n ' + str(line) - msg = '(Error {}) '.format(code) + msg - super(Exception, self).__init__(msg) - -class MSXSyntaxError(EpanetMsxException, SyntaxError): - def __init__(self, code, *args) -> None: - - super().__init__(code, *args) - -class MSXNameError(EpanetMsxException, NameError): - def __init__(self, code, name, *args) -> None: - - super().__init__(code, name, *args) - -class MSXValueError(EpanetMsxException, ValueError): - def __init__(self, code, name, *args) -> None: - - super().__init__(code, name, *args) diff --git a/wntr/reaction/io.py b/wntr/reaction/io.py index 64ad7b217..9949293de 100644 --- a/wntr/reaction/io.py +++ b/wntr/reaction/io.py @@ -1,754 +1,45 @@ # coding: utf-8 - -import datetime -from io import FileIO, TextIOWrapper -import logging -import sys - -from wntr.network.elements import Source -from wntr.reaction.base import MSXComment, RxnLocationType, RxnVariableType -from wntr.reaction.model import WaterQualityReactionsModel -from .exceptions import EpanetMsxException -from wntr.reaction.variables import Parameter, Species -from wntr.utils.citations import Citation - -sys_default_enc = sys.getdefaultencoding() - -logger = logging.getLogger(__name__) - -_INP_SECTIONS = [ - "[TITLE]", - "[OPTIONS]", - "[SPECIES]", - "[COEFFICIENTS]", - "[TERMS]", - "[PIPES]", - "[TANKS]", - "[SOURCES]", - "[QUALITY]", - "[PARAMETERS]", - "[DIFFUSIVITY]", - "[PATTERNS]", - "[REPORT]", -] - - -def _split_line(line): - _vc = line.split(";", 1) - _cmnt = None - _vals = None - if len(_vc) == 0: - pass - elif len(_vc) == 1: - _vals = _vc[0].split() - elif _vc[0] == "": - _cmnt = _vc[1].strip() - else: - _vals = _vc[0].split() - _cmnt = _vc[1].strip() - return _vals, _cmnt - - -class MsxFile(object): - def __init__(self): - self.sections = dict() - for sec in _INP_SECTIONS: - self.sections[sec] = [] - self.top_comments = [] - self.patterns = dict() - - def read(self, msx_file, rxn_model=None): - """ - Read an EPANET-MSX input file (.msx) and load data into a water quality - reactions model. Only MSX 2.0 files are recognized. - - Parameters - ---------- - msx_file : str - the filename of the .msx file to read in - rxn_model : WaterQualityReactionsModel, optional - the model to put data into, by default None (new model) - - Returns - ------- - WaterQualityReactionsModel - the model with the new species, reactions and other options added - """ - if rxn_model is None: - rxn_model = WaterQualityReactionsModel() - self.rxn = rxn_model - # if not isinstance(msx_file, list): - # msx_file = [msx_file] - rxn_model.filename = msx_file - - self.patterns = dict() - self.top_comments = [] - self.sections = dict() - for sec in _INP_SECTIONS: - self.sections[sec] = [] - - def _read(): - section = None - lnum = 0 - edata = {"fname": msx_file} - with open(msx_file, "r", encoding=sys_default_enc) as f: - for line in f: - lnum += 1 - edata["lnum"] = lnum - line = line.strip() - nwords = len(line.split()) - if len(line) == 0 or nwords == 0: - # Blank line - continue - elif line.startswith("["): - vals = line.split(None, 1) - sec = vals[0].upper() - # Add handlers to deal with extra 'S'es (or missing 'S'es) in INP file - if sec not in _INP_SECTIONS: - trsec = sec.replace("]", "S]") - if trsec in _INP_SECTIONS: - sec = trsec - if sec not in _INP_SECTIONS: - trsec = sec.replace("S]", "]") - if trsec in _INP_SECTIONS: - sec = trsec - edata["sec"] = sec - if sec in _INP_SECTIONS: - section = sec - # logger.info('%(fname)s:%(lnum)-6d %(sec)13s section found' % edata) - continue - elif sec == "[END]": - # logger.info('%(fname)s:%(lnum)-6d %(sec)13s end of file found' % edata) - section = None - break - else: - logger.warning('%(fname)s:%(lnum)d: Invalid section "%(sec)s"' % edata) - raise EpanetMsxException(201, note='at line {}:\n{}'.format(lnum, line)) - elif section is None and line.startswith(";"): - self.top_comments.append(line[1:]) - continue - elif section is None: - logger.debug("Found confusing line: %s", repr(line)) - raise EpanetMsxException(201, note='at line {}:\n{}'.format(lnum, line)) - # We have text, and we are in a section - self.sections[section].append((lnum, line)) - try: - _read() - self._read_title() - self._read_options() - self._read_species() - self._read_coefficients() - self._read_terms() - self._read_pipes() - self._read_tanks() - self._read_sources() - self._read_quality() - self._read_parameters() - self._read_diffusivity() - self._read_patterns() - self._read_report() - return self.rxn - except Exception as e: - raise EpanetMsxException(200) from e - - def _read_title(self): - lines = [] - title = None - comments = "" - for lnum, line in self.sections["[TITLE]"]: - vals, comment = _split_line(line) - if title is None and vals is not None: - title = " ".join(vals) - if comment: - lines.append(comment.strip()) - if self.top_comments: - comments = "\n".join(self.top_comments) - if len(lines) > 0: - comments = comments + ("\n" if comments else "") + "\n".join(lines) - self.rxn.title = title - self.rxn.desc = comments - - def _read_options(self): - lines = [] - note = MSXComment() - for lnum, line in self.sections["[OPTIONS]"]: - vals, comment = _split_line(line) - try: - if len(vals) < 2: - raise EpanetMsxException(402, note="at line {} of [OPTIONS] section:\n{}".format(lnum, line)) - name, val = vals[0].upper(), vals[1].upper() - if name == "AREA_UNITS": - self.rxn._options.quality.area_units = val - elif name == "RATE_UNITS": - self.rxn._options.quality.rate_units = val - elif name == "SOLVER": - self.rxn._options.quality.solver = val - elif name == "COUPLING": - self.rxn._options.quality.coupling = val - elif name == "TIMESTEP": - self.rxn._options.quality.timestep = int(val) - elif name == "ATOL": - self.rxn._options.quality.atol = float(val) - elif name == "RTOL": - self.rxn._options.quality.rtol = float(val) - elif name == "COMPILER": - self.rxn._options.quality.compiler = val - elif name == "SEGMENTS": - self.rxn._options.quality.segments = int(val) - elif name == "PECLET": - self.rxn._options.quality.peclet = int(val) - else: - raise EpanetMsxException(403, note='at line {} of [OPTIONS] section:\n{}'.format(lnum, line)) - except ValueError: - raise EpanetMsxException(404, note='at line {} of [OPTIONS] section:\n{}'.format(lnum, line)) - except EpanetMsxException: - raise - except Exception as e: - raise EpanetMsxException(201, note='at line {} of [OPTIONS] section:\n{}'.format(lnum, line)) from e - - def _read_species(self): - lines = [] - note = MSXComment() - for lnum, line in self.sections["[SPECIES]"]: - vals, comment = _split_line(line) - if vals is None: - if comment is not None: - note.pre.append(comment) - continue - try: - if comment is not None: - note.post = comment - if len(vals) < 3: - raise EpanetMsxException(402, note='at line {} of [SPECIES] section:\n{}'.format(lnum, line)) - if len(vals) == 3: - species = self.rxn.add_species(vals[0], vals[1], vals[2], note=note) - elif len(vals) == 5: - species = self.rxn.add_species(vals[0], vals[1], vals[2], float(vals[3]), float(vals[4]), note=note) - else: - raise EpanetMsxException(201, note='at line {} of [SPECIES] section:\n{}'.format(lnum, line)) - except EpanetMsxException: - raise - except Exception as e: - raise EpanetMsxException(201, note='at line {} of [SPECIES] section:\n{}'.format(lnum, line)) from e - else: - note = MSXComment() - - def _read_coefficients(self): - lines = [] - note = MSXComment() - for lnum, line in self.sections["[COEFFICIENTS]"]: - vals, comment = _split_line(line) - if vals is None: - if comment is not None: - note.pre.append(comment) - continue - try: - if comment is not None: - note.post = comment - if len(vals) < 3: - raise EpanetMsxException(402, note='at line {} of [COEFFICIENTS] section:\n{}'.format(lnum, line)) - coeff = self.rxn.add_coefficient(vals[0], vals[1], float(vals[2]), note=note) - except EpanetMsxException: - raise - except Exception as e: - raise EpanetMsxException(201, note='at line {} of [COEFFICIENTS] section:\n{}'.format(lnum, line)) from e - else: - note = MSXComment() - - def _read_terms(self): - lines = [] - note = MSXComment() - for lnum, line in self.sections["[TERMS]"]: - vals, comment = _split_line(line) - if vals is None: - if comment is not None: - note.pre.append(comment) - continue - try: - if comment is not None: - note.post = comment - if len(vals) < 2: - raise SyntaxError("Invalid [TERMS] entry") - term = self.rxn.add_other_term(vals[0], " ".join(vals[1:]), note=note) - except EpanetMsxException: - raise - except Exception as e: - raise EpanetMsxException(201, note='at line {} of [TERMS] section:\n{}'.format(lnum, line)) from e - else: - note = MSXComment() - - def _read_pipes(self): - lines = [] - note = MSXComment() - for lnum, line in self.sections["[PIPES]"]: - vals, comment = _split_line(line) - if vals is None: - if comment is not None: - note.pre.append(comment) - continue - try: - if comment is not None: - note.post = comment - if len(vals) < 3: - raise SyntaxError("Invalid [PIPES] entry") - reaction = self.rxn.add_pipe_reaction(vals[1], vals[0], " ".join(vals[2:]), note=note) - except EpanetMsxException: - raise - except Exception as e: - raise EpanetMsxException(201, note='at line {} of [PIPES] section:\n{}'.format(lnum, line)) from e - else: - note = MSXComment() - - def _read_tanks(self): - lines = [] - note = MSXComment() - for lnum, line in self.sections["[TANKS]"]: - vals, comment = _split_line(line) - if vals is None: - if comment is not None: - note.pre.append(comment) - continue - try: - if comment is not None: - note.post = comment - if len(vals) < 3: - raise SyntaxError("Invalid [TANKS] entry") - reaction = self.rxn.add_tank_reaction(vals[1], vals[0], " ".join(vals[2:]), note=note) - except EpanetMsxException: - raise - except Exception as e: - raise EpanetMsxException(201, note='at line {} of [TANKS] section:\n{}'.format(lnum, line)) from e - else: - note = MSXComment() - - def _read_sources(self): - lines = [] - note = MSXComment() - for lnum, line in self.sections["[SOURCES]"]: - vals, comment = _split_line(line) - if vals is None: - if comment is not None: - note.pre.append(comment) - continue - try: - if comment is not None: - note.post = comment - if len(vals) == 4: - typ, node, spec, strength = vals - pat = None - else: - typ, node, spec, strength, pat = vals - if not self.rxn.has_variable(spec): - raise ValueError("Undefined species in [SOURCES] section: {}".format(spec)) - if spec not in self.rxn._sources.keys(): - self.rxn._sources[spec] = dict() - source = dict(source_type=typ, strength=strength, pattern=pat, note=note) - self.rxn._sources[spec][node] = source - except EpanetMsxException: - raise - except Exception as e: - raise EpanetMsxException(201, note='at line {} of [SOURCES] section:\n{}'.format(lnum, line)) from e - else: - note = MSXComment() - - def _read_quality(self): - lines = [] - note = MSXComment() - for lnum, line in self.sections["[QUALITY]"]: - vals, comment = _split_line(line) - if vals is None: - if comment is not None: - note.pre.append(comment) - continue - try: - if comment is not None: - note.post = comment - if len(vals) == 4: - cmd, netid, spec, concen = vals - else: - cmd, spec, concen = vals - if cmd[0].lower() not in ["g", "n", "l"]: - raise SyntaxError("Unknown first word in [QUALITY] section") - if not self.rxn.has_variable(spec): - raise ValueError("Undefined species in [QUALITY] section: {}".format(spec)) - if spec not in self.rxn._inital_quality.keys(): - self.rxn._inital_quality[spec] = dict(global_value=None, nodes=dict(), links=dict()) - if cmd[0].lower() == "g": - self.rxn._inital_quality[spec]["global_value"] = float(concen) - elif cmd[0].lower() == "n": - self.rxn._inital_quality[spec]["nodes"][netid] = float(concen) - elif cmd[1].lower() == "l": - self.rxn._inital_quality[spec]["links"][netid] = float(concen) - except EpanetMsxException: - raise - except Exception as e: - raise EpanetMsxException(201, note='at line {} of [QUALITY] section:\n{}'.format(lnum, line)) from e - else: - note = MSXComment() - - def _read_parameters(self): - lines = [] - note = MSXComment() - for lnum, line in self.sections["[PARAMETERS]"]: - vals, comment = _split_line(line) - if vals is None: - if comment is not None: - note.pre.append(comment) - continue - try: - if comment is not None: - note.post = comment - typ, netid, paramid, value = vals - coeff = self.rxn.get_variable(paramid) - if not isinstance(coeff, Parameter): - raise ValueError("Invalid parameter {}".format(paramid)) - value = float(value) - if typ.lower()[0] == "p": - coeff.pipe_values[netid] = value - elif typ.lower()[0] == "t": - coeff.tank_values[netid] = value - else: - raise ValueError("Invalid parameter type {}".format(typ)) - except EpanetMsxException: - raise - except Exception as e: - raise EpanetMsxException(201, note='at line {} of [PARAMETERS] section:\n{}'.format(lnum, line)) from e - else: - note = MSXComment() - - def _read_diffusivity(self): - lines = [] - note = MSXComment() - for lnum, line in self.sections["[DIFFUSIVITY]"]: - vals, comment = _split_line(line) - if vals is None: - if comment is not None: - note.pre.append(comment) - continue - try: - if comment is not None: - note.post = comment - if len(vals) != 2: - raise SyntaxError("Invalid [DIFFUSIVITIES] entry") - species = self.rxn.get_variable(vals[0]) - if not isinstance(species, Species): - raise RuntimeError("Invalid species {} in diffusivity".format(vals[0])) - species.diffusivity = float(vals[1]) - except EpanetMsxException: - raise - except Exception as e: - raise EpanetMsxException(201, note='at line {} of [DIFFUSIVITIES] section:\n{}'.format(lnum, line)) from e - else: - note = MSXComment() - - def _read_patterns(self): - _patterns = dict() - for lnum, line in self.sections["[PATTERNS]"]: - # read the lines for each pattern -- patterns can be multiple lines of arbitrary length - line = line.split(";")[0] - current = line.split() - if current == []: - continue - pattern_name = current[0] - if pattern_name not in _patterns: - _patterns[pattern_name] = [] - for i in current[1:]: - _patterns[pattern_name].append(float(i)) - else: - for i in current[1:]: - _patterns[pattern_name].append(float(i)) - for pattern_name, pattern in _patterns.items(): - # add the patterns to the water newtork model - self.rxn.add_pattern(pattern_name, pattern) - - def _read_report(self): - lines = [] - note = MSXComment() - for lnum, line in self.sections["[REPORT]"]: - vals, comment = _split_line(line) - if vals is None: - if comment is not None: - note.pre.append(comment) - continue - try: - if comment is not None: - note.post = comment - if len(vals) == 0: - continue - if len(vals) < 2: - raise SyntaxError("Invalid number of arguments in [REPORT] section") - cmd = vals[0][0].lower() - if cmd == "n": # NODES - if self.rxn._options.report.nodes is None: - if vals[1].upper() == "ALL": - self.rxn._options.report.nodes = "ALL" - else: - self.rxn._options.report.nodes = list() - self.rxn._options.report.nodes.extend(vals[1:]) - elif isinstance(self.rxn._options.report.nodes, list): - if vals[1].upper() == "ALL": - self.rxn._options.report.nodes = "ALL" - else: - self.rxn._options.report.nodes.extend(vals[1:]) - elif cmd == "l": # LINKS - if self.rxn._options.report.links is None: - if vals[1].upper() == "ALL": - self.rxn._options.report.links = "ALL" - else: - self.rxn._options.report.links = list() - self.rxn._options.report.links.extend(vals[1:]) - elif isinstance(self.rxn._options.report.links, list): - if vals[1].upper() == "ALL": - self.rxn._options.report.links = "ALL" - else: - self.rxn._options.report.links.extend(vals[1:]) - elif cmd == "f": - self.rxn._options.report.report_filename = vals[1] - elif cmd == "p": - self.rxn._options.report.pagesize = vals[1] - elif cmd == "s": - if not self.rxn.has_variable(vals[1]): - raise ValueError("Undefined species in [REPORT] section: {}".format(vals[1])) - self.rxn._options.report.species[vals[1]] = True if vals[2].lower().startswith("y") else False - if len(vals) == 4: - self.rxn._options.report.species_precision[vals[1]] = int(vals[3]) - else: - raise SyntaxError("Invalid syntax in [REPORT] section: unknown first word") - except EpanetMsxException: - raise - except Exception as e: - raise EpanetMsxException(201, note='at line {} of [REPORT] section:\n{}'.format(lnum, line)) from e - else: - note = MSXComment() - - def write(self, filename: str, rxn: WaterQualityReactionsModel): - self.rxn = rxn - with open(filename, "w") as fout: - - fout.write("; WNTR-reactions MSX file generated {}\n".format(datetime.datetime.now())) - fout.write("\n") - self._write_title(fout) - self._write_options(fout) - self._write_species(fout) - self._write_coefficients(fout) - self._write_terms(fout) - self._write_pipes(fout) - self._write_tanks(fout) - self._write_sources(fout) - self._write_quality(fout) - self._write_diffusivity(fout) - self._write_parameters(fout) - self._write_patterns(fout) - self._write_report(fout) - fout.write("; END of MSX file generated by WNTR\n") - - def _write_title(self, fout): - fout.write("[TITLE]\n") - fout.write(" {}\n".format(self.rxn.title)) - fout.write("\n") - # if self.rxn.desc is not None: - # desc = self.rxn.desc.splitlines() - # desc = " ".join(desc) - # fout.write("; @desc={}\n".format(desc)) - # fout.write("\n") - # if self.rxn.citations is not None: - # if isinstance(self.rxn.citations, list): - # for citation in self.rxn.citations: - # fout.write("; @cite={}\n".format(citation.to_dict() if isinstance(citation, Citation) else str(citation))) - # fout.write("\n") - # else: - # citation = self.rxn.citations - # fout.write("; @cite={}\n".format(citation.to_dict() if isinstance(citation, Citation) else str(citation))) - # fout.write("\n") - - def _write_options(self, fout): - opts = self.rxn._options - fout.write("[OPTIONS]\n") - fout.write(" AREA_UNITS {}\n".format(opts.quality.area_units.upper())) - fout.write(" RATE_UNITS {}\n".format(opts.quality.rate_units.upper())) - fout.write(" SOLVER {}\n".format(opts.quality.solver.upper())) - fout.write(" COUPLING {}\n".format(opts.quality.coupling.upper())) - fout.write(" TIMESTEP {}\n".format(opts.quality.timestep)) - fout.write(" ATOL {}\n".format(opts.quality.atol)) - fout.write(" RTOL {}\n".format(opts.quality.rtol)) - fout.write(" COMPILER {}\n".format(opts.quality.compiler.upper())) - fout.write(" SEGMENTS {}\n".format(opts.quality.segments)) - fout.write(" PECLET {}\n".format(opts.quality.peclet)) - fout.write("\n") - - def _write_species(self, fout): - fout.write("[SPECIES]\n") - for var in self.rxn.variables(var_type=RxnVariableType.BULK): - if isinstance(var.note, MSXComment): - fout.write("{}\n".format(var.note.wrap_msx_string(var.to_msx_string()))) - elif isinstance(var.note, str): - fout.write(" {} ; {}\n".format(var.to_msx_string(), var.note)) - else: - fout.write(" {}\n".format(var.to_msx_string())) - for var in self.rxn.variables(var_type=RxnVariableType.WALL): - if isinstance(var.note, MSXComment): - fout.write("{}\n".format(var.note.wrap_msx_string(var.to_msx_string()))) - elif isinstance(var.note, str): - fout.write(" {} ; {}\n".format(var.to_msx_string(), var.note)) - else: - fout.write(" {}\n".format(var.to_msx_string())) - fout.write("\n") - - def _write_coefficients(self, fout): - fout.write("[COEFFICIENTS]\n") - for var in self.rxn.variables(var_type=RxnVariableType.CONST): - if isinstance(var.note, MSXComment): - fout.write("{}\n".format(var.note.wrap_msx_string(var.to_msx_string()))) - elif isinstance(var.note, str): - fout.write(" {} ; {}\n".format(var.to_msx_string(), var.note)) - else: - fout.write(" {}\n".format(var.to_msx_string())) - for var in self.rxn.variables(var_type=RxnVariableType.PARAM): - if isinstance(var.note, MSXComment): - fout.write("{}\n".format(var.note.wrap_msx_string(var.to_msx_string()))) - elif isinstance(var.note, str): - fout.write(" {} ; {}\n".format(var.to_msx_string(), var.note)) - else: - fout.write(" {}\n".format(var.to_msx_string())) - fout.write("\n") - - def _write_terms(self, fout): - fout.write("[TERMS]\n") - for var in self.rxn.variables(var_type=RxnVariableType.TERM): - if isinstance(var.note, MSXComment): - fout.write("{}\n".format(var.note.wrap_msx_string(var.to_msx_string()))) - elif isinstance(var.note, str): - fout.write(" {} ; {}\n".format(var.to_msx_string(), var.note)) - else: - fout.write(" {}\n".format(var.to_msx_string())) - fout.write("\n") - - def _write_pipes(self, fout): - fout.write("[PIPES]\n") - for var in self.rxn.reactions(location=RxnLocationType.PIPE): - if isinstance(var.note, MSXComment): - fout.write("{}\n".format(var.note.wrap_msx_string(var.to_msx_string()))) - elif isinstance(var.note, str): - fout.write(" {} ; {}\n".format(var.to_msx_string(), var.note)) - else: - fout.write(" {}\n".format(var.to_msx_string())) - fout.write("\n") - - def _write_tanks(self, fout): - fout.write("[TANKS]\n") - for var in self.rxn.reactions(location=RxnLocationType.TANK): - if isinstance(var.note, MSXComment): - fout.write("{}\n".format(var.note.wrap_msx_string(var.to_msx_string()))) - elif isinstance(var.note, str): - fout.write(" {} ; {}\n".format(var.to_msx_string(), var.note)) - else: - fout.write(" {}\n".format(var.to_msx_string())) - fout.write("\n") - - def _write_sources(self, fout): - fout.write("[SOURCES]\n") - for species in self.rxn._sources.keys(): - for node, src in self.rxn._sources[species].items(): - if isinstance(src["note"], MSXComment): - fout.write( - src["note"].wrap_msx_string( - "{:<10s} {:<8s} {:<8s} {:12s} {:<12s}".format(src["source_type"], node, species, src["strength"], src["pattern"] if src["pattern"] is not None else "") - ) - ) - elif isinstance(src["note"], str): - fout.write( - " {:<10s} {:<8s} {:<8s} {} {:<12s} ; {}\n".format( - src["source_type"], node, species, src["strength"], src["pattern"] if src["pattern"] is not None else "", src["note"] - ) - ) - else: - fout.write( - " {:<10s} {:<8s} {:<8s} {} {:<12s}\n".format(src["source_type"], node, species, src["strength"], src["pattern"] if src["pattern"] is not None else "") - ) - if src["note"] is not None: - fout.write("\n") - fout.write("\n") - - def _write_quality(self, fout): - fout.write("[QUALITY]\n") - for species in self.rxn._inital_quality.keys(): - for typ, val in self.rxn._inital_quality[species].items(): - if typ == "global_value": - fout.write(" {:<8s} {:<8s} {}\n".format("GLOBAL", species, val)) - elif typ in ["nodes", "links"]: - for node, conc in val.items(): - fout.write(" {:<8s} {:<8s} {:<8s} {}\n".format(typ.upper()[0:4], node, species, conc)) - fout.write("\n") - - def _write_parameters(self, fout): - fout.write("[PARAMETERS]\n") - for var in self.rxn.variables(var_type=RxnVariableType.PARAM): - had_entries = False - if not isinstance(var, Parameter): - pass - paramID = var.name - for pipeID, value in var.pipe_values.items(): - fout.write(" PIPE {:<8s} {:<8s} {}\n".format(pipeID, paramID, value)) - had_entries = True - for tankID, value in var.tank_values.items(): - fout.write(" PIPE {:<8s} {:<8s} {}\n".format(tankID, paramID, value)) - had_entries = True - if had_entries: - fout.write("\n") - fout.write("\n") - - def _write_patterns(self, fout): - fout.write("[PATTERNS]\n") - for pattern_name, pattern in self.rxn._patterns.items(): - num_columns = 10 - count = 0 - for i in pattern: # .multipliers: - if count % num_columns == 0: - fout.write("\n {:<8s} {:g}".format(pattern_name, i)) - else: - fout.write(" {:g}".format(i)) - count += 1 - fout.write("\n") - fout.write("\n") - - def _write_diffusivity(self, fout): - fout.write("[DIFFUSIVITY]\n") - for name in self.rxn.species_name_list: - spec: Species = self.rxn.get_variable(name) - if spec.diffusivity is not None: - fout.write(" {:<8s} {}\n".format(name, spec.diffusivity)) - fout.write("\n") - - def _write_report(self, fout): - fout.write("[REPORT]\n") - if self.rxn._options.report.nodes is not None: - if isinstance(self.rxn._options.report.nodes, str): - fout.write(" NODES {}\n".format(self.rxn.options.report.nodes)) - else: - fout.write(" NODES {}\n".format(" ".join(self.rxn.options.report.nodes))) - if self.rxn._options.report.links is not None: - if isinstance(self.rxn._options.report.links, str): - fout.write(" LINKS {}\n".format(self.rxn.options.report.links)) - else: - fout.write(" LINKS {}\n".format(" ".join(self.rxn.options.report.links))) - for spec, val in self.rxn._options.report.species.items(): - fout.write( - " SPECIES {:<8s} {:<3s} {}\n".format( - spec, - "YES" if val else "NO", - self.rxn._options.report.species_precision[spec] if spec in self.rxn._options.report.species_precision.keys() else "", - ) - ) - if self.rxn._options.report.report_filename: - fout.write(" FILE {}\n".format(self.rxn._options.report.report_filename)) - if self.rxn._options.report.pagesize: - fout.write(" PAGESIZE {}\n".format(self.rxn._options.report.pagesize)) - fout.write("\n") - - -class MsxBinFile(object): - def __init__(self): - pass - - def read(self, filename): - pass +"""Mulispecies reaction model I/O functions. + +.. rubric:: Contents + +.. autosummary:: + + to_dict + from_dict + +""" + +import wntr.epanet.msx +import json + +from wntr.utils.citations import Citation, to_jsontypes + + +def to_dict(msx): + from wntr import __version__ + rep = dict( + version="wntr-{}".format(__version__), + name=msx.name if msx.name else msx._msxfile, + comment=msx.title if msx.title else "WaterQualityModel - units assumed to be internally consistent", + citations=to_jsontypes(msx._citations), + options=msx._options.to_dict(), + variables=dict( + species=[v.to_dict() for v in msx._species.values()], + coefficients=[v.to_dict() for v in msx._coeffs.values()], + other_terms=[v.to_dict() for v in msx._terms.values()], + ), + reactions=dict( + pipes=[v.to_dict() for v in msx._pipe_dynamics.values()], + tanks=[v.to_dict() for v in msx._tank_dynamics.values()], + ), + patterns=msx._patterns.copy(), + initial_quality=msx._initial_quality.copy(), + ) + # rep["sources"] = dict() + # for sp, v in msx._sources: + # if v is not None and len(v) > 0: + # rep["sources"][sp] = dict() + # for node, source in v.items(): + # rep["sources"][sp][node] = source.to_dict() + return rep diff --git a/wntr/reaction/library.py b/wntr/reaction/library.py index 6409cc017..553be9993 100644 --- a/wntr/reaction/library.py +++ b/wntr/reaction/library.py @@ -19,102 +19,119 @@ """ import logging -from ..utils.citations import Citation -from .model import WaterQualityReactionsModel +from wntr.utils.citations import Citation +from wntr.reaction.model import MultispeciesReactionModel logger = logging.getLogger(__name__) # ===================== Nicotine-chlorine model # -nicotine = WaterQualityReactionsModel( - title="Nicotine - Chlorine reaction", - desc="Values in libarary are for test purposes ONLY.", -) -"""A nicotine-chlorine reaction model""" - -nicotine.options.quality.area_units = "M2" -nicotine.options.quality.rate_units = "MIN" -nicotine.options.quality.timestep = 1 -nicotine.add_bulk_species("Nx", units="MG", note="Nicotine") -nicotine.add_bulk_species("HOCL", units="MG", note="Free chlorine") -nicotine.add_constant_coeff("kd", global_value=2.33e-3, units="min^(-1)", note="decay rate") -nicotine.add_constant_coeff("K1", global_value=5.92e-2, units="L * min^(-1) * mg^(-1)", note="decay constant for chlorine as function of mass(Nic)") -nicotine.add_constant_coeff("K2", global_value=1.84e-1, units="L * min^(-1) * mg^(-1)", note="decay constant for nicotine as function of mass(Cl)") -nicotine.add_other_term("RXCL", expression="kd * HOCL + K1 * Nx * HOCL") -nicotine.add_other_term("RXN", expression="K2 * Nx * HOCL") -nicotine.add_pipe_reaction("Nx", "rate", expression="-RXN") -nicotine.add_pipe_reaction("HOCL", "rate", expression="-RXCL") -nicotine.add_tank_reaction("Nx", "rate", "0") -nicotine.add_tank_reaction("HOCL", "rate", "0") +def nicotine() -> MultispeciesReactionModel: + """A nicotine-chlorine reaction model""" + msx = MultispeciesReactionModel() + msx.name = "nicotine" + msx.title = ("Nicotine - Chlorine reaction",) + msx.options.quality.area_units = "M2" + msx.options.quality.rate_units = "MIN" + msx.options.quality.timestep = 1 + msx.add_bulk_species("Nx", units="MG", note="Nicotine") + msx.add_bulk_species("HOCL", units="MG", note="Free chlorine") + msx.add_constant_coeff("kd", global_value=2.33e-3, units="min^(-1)", note="decay rate") + msx.add_constant_coeff("K1", global_value=5.92e-2, units="L * min^(-1) * mg^(-1)", note="decay constant for chlorine as function of mass(Nic)") + msx.add_constant_coeff("K2", global_value=1.84e-1, units="L * min^(-1) * mg^(-1)", note="decay constant for nicotine as function of mass(Cl)") + msx.add_other_term("RXCL", expression="kd * HOCL + K1 * Nx * HOCL") + msx.add_other_term("RXN", expression="K2 * Nx * HOCL") + msx.add_pipe_reaction("Nx", "rate", expression="-RXN") + msx.add_pipe_reaction("HOCL", "rate", expression="-RXCL") + msx.add_tank_reaction("Nx", "rate", "0") + msx.add_tank_reaction("HOCL", "rate", "0") + return msx # ===================== Nicotine-chlorine reactive intermediate species # -nicotine_ri = WaterQualityReactionsModel( - title="Nicotine - Chlorine reaction with reactive intermediate", - desc="Values in libarary are for test purposes ONLY.", -) -"""A nicotine-chlorine reaction with a reactive intermediate""" -# Set the options -nicotine_ri.options.quality.area_units = "M2" -nicotine_ri.options.quality.rate_units = "MIN" -nicotine_ri.options.quality.timestep = 1 -nicotine_ri.options.quality.atol = 1.0e-10 -nicotine_ri.options.quality.rtol = 1.0e-10 -# Add species -nicotine_ri.add_bulk_species("Nx", units="MG", note="Nicotine") -nicotine_ri.add_bulk_species("HOCL", units="MG", note="Free Chlorine") -nicotine_ri.add_bulk_species("NX2", units="MG", note="Intermediate Nicotine Reactive") -# Add coefficients -nicotine_ri.add_constant_coeff("kd", 3.0e-5, note="decay rate", units="1/min") -nicotine_ri.add_constant_coeff("K1", global_value=9.75e-2, units="L * min^(-1) * mg^(-1)", note="decay constant for chlorine as function of mass(Nic)") -nicotine_ri.add_constant_coeff("K2", global_value=5.73e-1, units="L * min^(-1) * mg^(-1)", note="decay constant for nicotine as function of mass(Cl)") -nicotine_ri.add_constant_coeff("K3", global_value=1.34e-2, units="L * min^(-1) * mg^(-1)", note="decay constant for nicotine as function of mass(N2)") -nicotine_ri.add_constant_coeff("K4", global_value=2.19e-2, units="L * min^(-1) * mg^(-1)", note="decay constant for nicotine as function of mass(Cl)") -# Add terms (named subexpressions) -nicotine_ri.add_other_term("RXCL", expression="kd*HOCL + K1*Nx*HOCL + K3*NX2*HOCL") -nicotine_ri.add_other_term("RXN", expression="K2*Nx*HOCL") -nicotine_ri.add_other_term("RXNX2", expression="K2*Nx*HOCL - K4*NX2*HOCL") -# Add pipe reactions, one per species -nicotine_ri.add_pipe_reaction("Nx", "RATE", expression="-RXN") -nicotine_ri.add_pipe_reaction("HOCL", "RATE", expression="-RXCL") -nicotine_ri.add_pipe_reaction("NX2", "RATE", expression="RXNX2") -# Tank reactions actually aren't necessary since there aren't any wall species -nicotine_ri.add_tank_reaction("Nx", "RATE", expression="-RXN") -nicotine_ri.add_tank_reaction("HOCL", "RATE", expression="-RXCL") -nicotine_ri.add_tank_reaction("NX2", "RATE", expression="RXNX2") +def nicotine_ri() -> MultispeciesReactionModel: + """A nicotine-chlorine reaction with a reactive intermediate""" + msx = MultispeciesReactionModel() + msx.name = 'nicotine_ri' + msx.title = ("Nicotine - Chlorine reaction with reactive intermediate",) + # Set the options + msx.options.quality.area_units = "M2" + msx.options.quality.rate_units = "MIN" + msx.options.quality.timestep = 1 + msx.options.quality.atol = 1.0e-10 + msx.options.quality.rtol = 1.0e-10 + # Add species + msx.add_bulk_species("Nx", units="MG", note="Nicotine") + msx.add_bulk_species("HOCL", units="MG", note="Free Chlorine") + msx.add_bulk_species("NX2", units="MG", note="Intermediate Nicotine Reactive") + # Add coefficients + msx.add_constant_coeff("kd", 3.0e-5, note="decay rate", units="1/min") + msx.add_constant_coeff("K1", global_value=9.75e-2, units="L * min^(-1) * mg^(-1)", note="decay constant for chlorine as function of mass(Nic)") + msx.add_constant_coeff("K2", global_value=5.73e-1, units="L * min^(-1) * mg^(-1)", note="decay constant for nicotine as function of mass(Cl)") + msx.add_constant_coeff("K3", global_value=1.34e-2, units="L * min^(-1) * mg^(-1)", note="decay constant for nicotine as function of mass(N2)") + msx.add_constant_coeff("K4", global_value=2.19e-2, units="L * min^(-1) * mg^(-1)", note="decay constant for nicotine as function of mass(Cl)") + # Add terms (named subexpressions) + msx.add_other_term("RXCL", expression="kd*HOCL + K1*Nx*HOCL + K3*NX2*HOCL") + msx.add_other_term("RXN", expression="K2*Nx*HOCL") + msx.add_other_term("RXNX2", expression="K2*Nx*HOCL - K4*NX2*HOCL") + # Add pipe reactions, one per species + msx.add_pipe_reaction("Nx", "RATE", expression="-RXN") + msx.add_pipe_reaction("HOCL", "RATE", expression="-RXCL") + msx.add_pipe_reaction("NX2", "RATE", expression="RXNX2") + # Tank reactions actually aren't necessary since there aren't any wall species + msx.add_tank_reaction("Nx", "RATE", expression="-RXN") + msx.add_tank_reaction("HOCL", "RATE", expression="-RXCL") + msx.add_tank_reaction("NX2", "RATE", expression="RXNX2") + return msx # ===================== Lead plumbosolvency model # -lead_ppm = WaterQualityReactionsModel( - title="Lead Plumbosolvency Model (from Burkhardt et al 2020)", - desc="Parameters for EPA HPS Simulator Model", - citations=[Citation( - title="Framework for Modeling Lead in Premise Plumbing Systems Using EPANET", - year=2020, - author=[ - "Jonathan B. Burkhardt", - "Hyoungmin Woo", - "James Mason", - "Feng Shang", - "Simoni Triantafyllidou", - "Michael R. Schock", - "Darren Lytle", - "Regan Murray", - ], - citation_class="article", - journaltitle="J Water Resour Plan Manag", - volume=146, - number=12, - fulldate="2020-12-01", - doi="10.1061/(asce)wr.1943-5452.0001304", - eprint=[ - "PMID:33627937", - "PMCID:PMC7898126", - "NIHMSID:NIHMS1664627", - ], - )], - allow_sympy_reserved_names=True, - options={ +def lead_ppm() -> MultispeciesReactionModel: + """A lead plumbosolvency model [BWMS20]_. + + .. [BWMS20] + J. B. Burkhardt, et al. (2020) + "Framework for Modeling Lead in Premise Plumbing Systems Using EPANET". + `Journal of water resources planning and management`. + **146** (12). + https://doi.org/10.1061/(asce)wr.1943-5452.0001304 + + """ + msx = MultispeciesReactionModel() + msx.name = 'lead_ppm' + msx.title = "Lead Plumbosolvency Model (from Burkhardt et al 2020)" + msx.desc = "Parameters for EPA HPS Simulator Model" + msx.citations.append( + Citation( + "article", + "BWMS20", + fields=dict( + title="Framework for Modeling Lead in Premise Plumbing Systems Using EPANET", + year=2020, + author=[ + "Jonathan B. Burkhardt", + "Hyoungmin Woo", + "James Mason", + "Feng Shang", + "Simoni Triantafyllidou", + "Michael R. Schock", + "Darren Lytle", + "Regan Murray", + ], + journaltitle="J Water Resour Plan Manag", + volume=146, + number=12, + date="2020-12-01", + doi="10.1061/(asce)wr.1943-5452.0001304", + eprint=[ + "PMID:33627937", + "PMCID:PMC7898126", + "NIHMSID:NIHMS1664627", + ], + ), + ) + ) + msx.options = { "report": { "species": {"PB2": "YES"}, "species_precision": {"PB2": 5}, @@ -128,22 +145,11 @@ "rtol": 1e-08, "atol": 1e-08, }, - }, -) -"""A lead plumbosolvency model [BEMS20]_. - -.. [BEMS20] - J. B. Burkhardt, et al. (2020) - "Framework for Modeling Lead in Premise Plumbing Systems Using EPANET". - `Journal of water resources planning and management`. - **146** (12). - https://doi.org/10.1061/(asce)wr.1943-5452.0001304 - -""" -# add the species, coefficients and reactions -lead_ppm.add_bulk_species("PB2", "ug", note="dissolved lead (Pb)") -lead_ppm.add_constant_coeff("M", global_value=0.117, note="Desorption rate (ug/m^2/s)", units="ug * m^(-1) * s^(-1)") -lead_ppm.add_constant_coeff("E", global_value=140.0, note="saturation/plumbosolvency level (ug/L)", units="ug/L") -lead_ppm.add_parameterized_coeff("F", global_value=0, note="determines which pipes have reactions") -lead_ppm.add_pipe_reaction("PB2", "RATE", expression="F*Av*M*(E - PB2)/E") -lead_ppm.add_tank_reaction("PB2", "RATE", expression="0") + } + msx.add_bulk_species("PB2", "ug", note="dissolved lead (Pb)") + msx.add_constant_coeff("M", global_value=0.117, note="Desorption rate (ug/m^2/s)", units="ug * m^(-1) * s^(-1)") + msx.add_constant_coeff("E", global_value=140.0, note="saturation/plumbosolvency level (ug/L)", units="ug/L") + msx.add_parameterized_coeff("F", global_value=0, note="determines which pipes have reactions") + msx.add_pipe_reaction("PB2", "RATE", expression="F*Av*M*(E - PB2)/E") + msx.add_tank_reaction("PB2", "RATE", expression="0") + return msx \ No newline at end of file diff --git a/wntr/reaction/model.py b/wntr/reaction/model.py index 5b7b3cd13..f1984b225 100644 --- a/wntr/reaction/model.py +++ b/wntr/reaction/model.py @@ -2,7 +2,11 @@ """ Water quality reactions model. -TODO: FIXME: Make sure that we throw the same errors (text/number) as MSX would throw +.. rubric:: Contents + +.. autosummary:: + + MultispeciesReactionModel """ @@ -24,7 +28,9 @@ Tuple, Union, ) + from wntr.network.elements import Source +from wntr.utils.disjoint_mapping import DisjointMapping, KeyExistsError has_sympy = False try: @@ -40,97 +46,72 @@ convert_xor = None has_sympy = False +import wntr.reaction.io from wntr.network.model import WaterNetworkModel +from wntr.utils.citations import Citation -from ..utils.citations import Citation from .base import ( HYDRAULIC_VARIABLES, SYMPY_RESERVED, - DisjointMapping, + DynamicsType, LinkedVariablesMixin, - RxnDynamicsType, - RxnLocationType, - RxnModelRegistry, - RxnReaction, - RxnVariable, - RxnVariableType, - VariableNameExistsError, + LocationType, + ReactionDynamics, + AbstractReactionModel, + ReactionVariable, + VariableType, ) from .dynamics import EquilibriumDynamics, FormulaDynamics, RateDynamics -from .options import RxnOptions +from .options import MultispeciesOptions from .variables import ( BulkSpecies, Coefficient, Constant, InternalVariable, + OtherTerm, Parameter, Species, - OtherTerm, WallSpecies, ) logger = logging.getLogger(__name__) +__all__ = ["MultispeciesReactionModel"] + -@dataclass -class WaterQualityReactionsModel(RxnModelRegistry): +class MultispeciesReactionModel(AbstractReactionModel): """Water quality reactions model object. Parameters ---------- - title : str, optional - The title of reaction model - desc : str, optional - A long description of the model - filename : str, optional - The original filename - citations : list of Citation or str, optional - It is appropriate to cite sources for water quality models - allow_sympy_reserved_names : bool, optional - Should the extra names from sympy be excluded, by default False - options : RxnOptions, optional - Reaction MSX options, by default a new object - _wn : WaterNetworkModel - The water network model to use, by default None + msx_file_name : str, optional + The name of the MSX input file to read + """ - # FIXME: Make the __init__ just minimal, with a filename - # do the rest of stuff directly on the MSX object, make it as - # close to WNM as possible - - title: str = None - """A one-line title for the model""" - - desc: str = None - """A multi-line string describing the model""" - - filename: str = None - """The original filename""" - - citations: List[Union[Citation, str]] = "you ought to provide citations for your model" - """A list of citations for the sources of this model's dynamics""" - - allow_sympy_reserved_names: InitVar[bool] = False - """Allow sympy reserved names (I, E, pi)""" - - options: InitVar[RxnOptions] = None - """A link to the options object""" - - _wn: WaterNetworkModel = None - """A link to a water network model""" - - def __post_init__(self, allow_sympy_reserved_names=False, options=None): - if self._wn is not None and not isinstance(self._wn, WaterNetworkModel): - raise TypeError("Did not receive a WaterNetworkModel or None as first argument, got {}".format(self._wn)) - if isinstance(options, property): - options = RxnOptions() - elif not isinstance(options, RxnOptions): - options = RxnOptions.factory(options) - self._options = options - if isinstance(self.citations, str): - self.citations = [self.citations] - elif isinstance(self.citations, Citation): - self.citations = [self.citations] + def __init__(self, msx_file_name=None): + self.name: str = None + """A one-line title for the model""" + + self.title: str = None + """The title line from the MSX file""" + + self._msxfile: str = msx_file_name + """The original filename""" + + self._citations: List[Union[Citation, str]] = list() + """A list of citations for the sources of this model's dynamics""" + + self._allow_sympy_reserved_names: InitVar[bool] = True + """Allow sympy reserved names (I, E, pi)""" + + self._options: InitVar[MultispeciesOptions] = None + """A link to the options object""" + + self._wn: WaterNetworkModel = None + """A link to a water network model""" + + self._options = MultispeciesOptions() self._variables: DisjointMapping = DisjointMapping() self._species = self._variables.add_disjoint_group("species") @@ -150,11 +131,16 @@ def __post_init__(self, allow_sympy_reserved_names=False, options=None): for v in HYDRAULIC_VARIABLES: self._variables[v["name"]] = InternalVariable(v["name"], note=v["note"]) - if not allow_sympy_reserved_names: + if not self._allow_sympy_reserved_names: for name in SYMPY_RESERVED: self._variables[name] = InternalVariable(name, note="sympy reserved name") + if msx_file_name is not None: + from wntr.epanet.msx.io import MsxFile - def _is_variable_registered(self, var_or_name: Union[str, RxnVariable]) -> bool: + inp = MsxFile() + inp.read(msx_file_name, self) + + def _is_variable_registered(self, var_or_name: Union[str, ReactionVariable]) -> bool: name = str(var_or_name) if name in self._variables.keys(): return True @@ -191,11 +177,11 @@ def coefficient_name_list(self) -> List[str]: return list(self._coeffs.keys()) @property - def function_name_list(self) -> List[str]: + def other_term_name_list(self) -> List[str]: """A list of all defined function (MSX 'terms') names""" return list(self._terms.keys()) - def variables(self, var_type: RxnVariableType = None): + def variables(self, var_type: VariableType = None): """A generator to loop over the variables. Parameters @@ -208,13 +194,13 @@ def variables(self, var_type: RxnVariableType = None): RxnVariable a variable defined within the model """ - var_type = RxnVariableType.factory(var_type) + var_type = VariableType.get(var_type) for v in self._variables.values(): if var_type is not None and v.var_type != var_type: continue yield v - def add_variable(self, var_or_type: Union[RxnVariable, RxnVariableType], name: str = None, **kwargs): + def add_variable(self, var_or_type: Union[ReactionVariable, VariableType], name: str = None, **kwargs): """Add an new variable to the model, or add an existing, unlinked variable object to the model. Parameters @@ -235,19 +221,19 @@ def add_variable(self, var_or_type: Union[RxnVariable, RxnVariableType], name: s VariableNameExistsError if the variable or name uses the same name an existing variable already uses """ - if not isinstance(var_or_type, (RxnVariable,)): + if not isinstance(var_or_type, (ReactionVariable,)): try: - var_or_type = RxnVariableType.factory(var_or_type) + var_or_type = VariableType.get(var_or_type) except Exception as e: raise TypeError("Cannot add an object that is not a RxnVariable subclass or create a new object without a valid var_type") from e if name is None: raise ValueError("When adding a new variable, a name must be supplied") typ = var_or_type - if typ is RxnVariableType.BULK or typ is RxnVariableType.WALL: + if typ is VariableType.BULK or typ is VariableType.WALL: self.add_species(var_or_type, name, **kwargs) - elif typ is RxnVariableType.CONST or typ is RxnVariableType.PARAM: + elif typ is VariableType.CONST or typ is VariableType.PARAM: self.add_coefficient(var_or_type, name, **kwargs) - elif typ is RxnVariableType.TERM: + elif typ is VariableType.TERM: self.add_other_term(var_or_type, name, **kwargs) else: raise TypeError("Cannot create new objects of the INTERNAL type using this function") @@ -256,25 +242,25 @@ def add_variable(self, var_or_type: Union[RxnVariable, RxnVariableType], name: s raise ValueError("When adding an existing variable object, no other arguments may be supplied") __variable = var_or_type if self._is_variable_registered(__variable): - raise VariableNameExistsError("A variable with this name already exists in the model") + raise KeyExistsError("A variable with this name already exists in the model") typ = __variable.var_type name = __variable.name if isinstance(__variable, LinkedVariablesMixin): __variable._variable_registry = self - if typ is RxnVariableType.BULK or typ is RxnVariableType.WALL: + if typ is VariableType.BULK or typ is VariableType.WALL: self._variables.add_item_to_group("species", name, __variable) self._inital_quality[name] = dict(global_value=None, nodes=dict(), links=dict()) self._sources[name] = dict() - elif typ is RxnVariableType.CONST or typ is RxnVariableType.PARAM: + elif typ is VariableType.CONST or typ is VariableType.PARAM: self._variables.add_item_to_group("coeffs", name, __variable) - elif typ is RxnVariableType.TERM: + elif typ is VariableType.TERM: self._variables.add_item_to_group("funcs", name, __variable) else: self._variables.add_item_to_group(None, name, __variable) def add_species( self, - species_type: Union[str, Literal[RxnVariableType.BULK], Literal[RxnVariableType.WALL]], + species_type: Union[str, Literal[VariableType.BULK], Literal[VariableType.WALL]], name: str, units: str, atol: float = None, @@ -313,19 +299,19 @@ def add_species( TypeError if atol and rtol are not both None or both a float """ - species_type = RxnVariableType.factory(species_type) - if species_type not in [RxnVariableType.BULK, RxnVariableType.WALL]: + species_type = VariableType.get(species_type) + if species_type not in [VariableType.BULK, VariableType.WALL]: raise ValueError("Species must be BULK or WALL, got {:s}".format(species_type)) if self._is_variable_registered(name): - raise VariableNameExistsError("The variable {} already exists in this model".format(name)) + raise KeyExistsError("The variable {} already exists in this model".format(name)) if (atol is None) ^ (rtol is None): raise TypeError("atol and rtol must be the same type, got {} and {}".format(atol, rtol)) - if species_type is RxnVariableType.BULK: + if species_type is VariableType.BULK: var = BulkSpecies(name=name, units=units, atol=atol, rtol=rtol, note=note, variable_registry=self) - elif species_type is RxnVariableType.WALL: + elif species_type is VariableType.WALL: var = WallSpecies(name=name, units=units, atol=atol, rtol=rtol, note=note, variable_registry=self) self._species[name] = var - self._inital_quality[name] = dict([('global', None), ('nodes', dict()), ('links', dict())]) + self._inital_quality[name] = dict([("global", None), ("nodes", dict()), ("links", dict())]) self._sources[name] = dict() return var @@ -358,7 +344,7 @@ def add_bulk_species(self, name: str, units: str, atol: float = None, rtol: floa TypeError if atol and rtol are not both None or both a float """ - return self.add_species(RxnVariableType.BULK, name, units, atol, rtol, note) + return self.add_species(VariableType.BULK, name, units, atol, rtol, note) def add_wall_species(self, name: str, units: str, atol: float = None, rtol: float = None, note: str = None) -> WallSpecies: """Add a new wall species to the model. @@ -389,10 +375,10 @@ def add_wall_species(self, name: str, units: str, atol: float = None, rtol: floa TypeError if atol and rtol are not both None or both a float """ - return self.add_species(RxnVariableType.WALL, name, units, atol, rtol, note) + return self.add_species(VariableType.WALL, name, units, atol, rtol, note) def add_coefficient( - self, coeff_type: Union[str, Literal[RxnVariableType.CONST], Literal[RxnVariableType.PARAM]], name: str, global_value: float, note: str = None, units: str = None, **kwargs + self, coeff_type: Union[str, Literal[VariableType.CONST], Literal[VariableType.PARAM]], name: str, global_value: float, note: str = None, units: str = None, **kwargs ) -> Coefficient: """Add a new coefficient to the model. @@ -424,14 +410,14 @@ def add_coefficient( VariableNameExistsError if a variable with this name already exists in the model """ - coeff_type = RxnVariableType.factory(coeff_type) - if coeff_type not in [RxnVariableType.CONST, RxnVariableType.PARAM]: + coeff_type = VariableType.get(coeff_type) + if coeff_type not in [VariableType.CONST, VariableType.PARAM]: raise ValueError("coeff_type must be CONST or PARAM, got {:s}".format(coeff_type)) if self._is_variable_registered(name): - raise VariableNameExistsError("The variable {} already exists in this model".format(name)) - if coeff_type is RxnVariableType.CONST: + raise KeyExistsError("The variable {} already exists in this model".format(name)) + if coeff_type is VariableType.CONST: var = Constant(name=name, global_value=global_value, note=note, units=units, variable_registry=self) - elif coeff_type is RxnVariableType.PARAM: + elif coeff_type is VariableType.PARAM: var = Parameter(name=name, global_value=global_value, note=note, units=units, variable_registry=self, **kwargs) self._coeffs[name] = var return var @@ -464,7 +450,7 @@ def add_constant_coeff(self, name: str, global_value: float, note: str = None, u VariableNameExistsError if a variable with this name already exists in the model """ - return self.add_coefficient(RxnVariableType.CONST, name=name, global_value=global_value, note=note, units=units) + return self.add_coefficient(VariableType.CONST, name=name, global_value=global_value, note=note, units=units) def add_parameterized_coeff( self, name: str, global_value: float, note: str = None, units: str = None, pipe_values: Dict[str, float] = None, tank_values: Dict[str, float] = None @@ -500,7 +486,7 @@ def add_parameterized_coeff( VariableNameExistsError if a variable with this name already exists in the model """ - return self.add_coefficient(RxnVariableType.PARAM, name=name, global_value=global_value, note=note, units=units, _pipe_values=pipe_values, _tank_values=tank_values) + return self.add_coefficient(VariableType.PARAM, name=name, global_value=global_value, note=note, units=units, _pipe_values=pipe_values, _tank_values=tank_values) def add_other_term(self, name: str, expression: str, note: str = None) -> OtherTerm: """Add a new user-defined function to the model. @@ -529,22 +515,46 @@ def add_other_term(self, name: str, expression: str, note: str = None) -> OtherT if a variable with this name already exists in the model """ if self._is_variable_registered(name): - raise VariableNameExistsError("The variable {} already exists in this model".format(name)) + raise KeyExistsError("The variable {} already exists in this model".format(name)) var = OtherTerm(name=name, expression=expression, note=note, variable_registry=self) self._terms[name] = var return var def remove_variable(self, name: str): + """Remove a variable from the model. + + Parameters + ---------- + name : str + variable name + """ if name in self._inital_quality.keys(): self._inital_quality.__delitem__(name) if name in self._sources.keys(): self._sources.__delitem__(name) return self._variables.__delitem__(name) - def get_variable(self, name: str) -> RxnVariable: + def get_variable(self, name: str) -> ReactionVariable: + """Get a variable based on its name (symbol). + + Parameters + ---------- + name : str + The variable name + + Returns + ------- + ReactionVariable + the variable with the name in question + + Raises + ------ + KeyError + a variable with that name does not exist + """ return self._variables[name] - def reactions(self, location: RxnLocationType = None): + def reactions(self, location: LocationType = None): """A generator for iterating through reactions in the model. Parameters @@ -554,73 +564,154 @@ def reactions(self, location: RxnLocationType = None): Yields ------ - RxnReaction + ReactionDynamics a reaction defined within the model """ - location = RxnLocationType.factory(location) + location = LocationType.get(location) for v in self._dynamics.values(): if location is not None and v.location != location: continue yield v - def add_reaction(self, location: RxnLocationType, species: Union[str, Species], dynamics: Union[str, int, RxnDynamicsType], expression: str, note: str = None): + def add_reaction(self, location: LocationType, species: Union[str, Species], dynamics: Union[str, int, DynamicsType], expression: str, note: str = None): + """Add a multispecies water quality reaction to the model. + + Parameters + ---------- + location : LocationType + where the reaction is taking place + species : Union[str, Species] + the species with the dynamics that are being described + dynamics : Union[str, int, DynamicsType] + the type of reaction dynamics used to describe this species changes through time + expression : str + the right-hand-side of the reaction dynamics equation + note : str, optional + a note about this reaction, by default None + + Returns + ------- + ReactionDynamics + the resulting reaction object + + Raises + ------ + ValueError + species does not exist + RuntimeError + species already has reaction defined FIXME: this should be an MSX error + ValueError + invalid dynamics type + ValueError + invalid location type + """ # TODO: accept a "both" or "all" value for location - location = RxnLocationType.factory(location) + location = LocationType.get(location) species = str(species) if species not in self._species.keys(): raise ValueError("The species {} does not exist in the model, failed to add reaction.".format(species)) - _key = RxnReaction.to_key(species, location) + _key = ReactionDynamics.to_key(species, location) if _key in self._dynamics.keys(): raise RuntimeError("The species {} already has a {} reaction defined. Use set_reaction instead.") - dynamics = RxnDynamicsType.factory(dynamics) + dynamics = DynamicsType.get(dynamics) new = None - if dynamics is RxnDynamicsType.EQUIL: + if dynamics is DynamicsType.EQUIL: new = EquilibriumDynamics(species=species, location=location, expression=expression, note=note, variable_registry=self) - elif dynamics is RxnDynamicsType.RATE: + elif dynamics is DynamicsType.RATE: new = RateDynamics(species=species, location=location, expression=expression, note=note, variable_registry=self) - elif dynamics is RxnDynamicsType.FORMULA: + elif dynamics is DynamicsType.FORMULA: new = FormulaDynamics(species=species, location=location, expression=expression, note=note, variable_registry=self) else: raise ValueError("Invalid dynamics type, {}".format(dynamics)) - if location is RxnLocationType.PIPE: + if location is LocationType.PIPE: self._pipe_dynamics[str(new)] = new - elif location is RxnLocationType.TANK: + elif location is LocationType.TANK: self._tank_dynamics[str(new)] = new else: raise ValueError("Invalid location type, {}".format(location)) return new - def add_pipe_reaction(self, species: Union[str, Species], dynamics: Union[str, int, RxnDynamicsType], expression: str, note: str = None) -> RxnReaction: - return self.add_reaction(RxnLocationType.PIPE, species=species, dynamics=dynamics, expression=expression, note=note) + def add_pipe_reaction(self, species: Union[str, Species], dynamics: Union[str, int, DynamicsType], expression: str, note: str = None) -> ReactionDynamics: + """Add a pipe reaction. See also :meth:`add_reaction`. + + Parameters + ---------- + species : Union[str, Species] + the species with the dynamics that are being described + dynamics : Union[str, int, DynamicsType] + the type of reaction dynamics used to describe this species changes through time + expression : str + the right-hand-side of the reaction dynamics equation + note : str, optional + a note about this reaction, by default None + + Returns + ------- + ReactionDynamics + the reaction object + """ + return self.add_reaction(LocationType.PIPE, species=species, dynamics=dynamics, expression=expression, note=note) + + def add_tank_reaction(self, species: Union[str, Species], dynamics: Union[str, int, DynamicsType], expression: str, note: str = None) -> ReactionDynamics: + """Add a pipe reaction. See also :meth:`add_reaction`. + + Parameters + ---------- + species : Union[str, Species] + the species with the dynamics that are being described + dynamics : Union[str, int, DynamicsType] + the type of reaction dynamics used to describe this species changes through time + expression : str + the right-hand-side of the reaction dynamics equation + note : str, optional + a note about this reaction, by default None + + Returns + ------- + ReactionDynamics + the reaction object + """ + return self.add_reaction(LocationType.TANK, species=species, dynamics=dynamics, expression=expression, note=note) + + def remove_reaction(self, species: Union[str, Species], location: Union[str, int, LocationType, Literal["all"]]): + """Remove a reaction for a species from the model - def add_tank_reaction(self, species: Union[str, Species], dynamics: Union[str, int, RxnDynamicsType], expression: str, note: str = None) -> RxnReaction: - return self.add_reaction(RxnLocationType.TANK, species=species, dynamics=dynamics, expression=expression, note=note) + Parameters + ---------- + species : str or Species + the species to remove a reaction for + location : str, int, LocationType or 'all' + the location of the reaction to delete, with 'all' meaning both wall and pipe reactions - def remove_reaction(self, species: Union[str, Species], location: Union[str, int, RxnLocationType, Literal["all"]]): + Raises + ------ + ValueError + if the value for `location` is invalid + """ if location != "all": - location = RxnLocationType.factory(location) + location = LocationType.get(location) species = str(species) if location is None: raise TypeError('location cannot be None when removing a reaction. Use "all" for all locations.') elif location == "all": - name = RxnReaction.to_key(species, RxnLocationType.PIPE) + name = ReactionDynamics.to_key(species, LocationType.PIPE) try: self._pipe_dynamics.__delitem__(name) except KeyError: pass - name = RxnReaction.to_key(species, RxnLocationType.TANK) + name = ReactionDynamics.to_key(species, LocationType.TANK) try: self._tank_dynamics.__delitem__(name) except KeyError: pass - elif location is RxnLocationType.PIPE: - name = RxnReaction.to_key(species, RxnLocationType.PIPE) + elif location is LocationType.PIPE: + name = ReactionDynamics.to_key(species, LocationType.PIPE) try: self._pipe_dynamics.__delitem__(name) except KeyError: pass - elif location is RxnLocationType.TANK: - name = RxnReaction.to_key(species, RxnLocationType.TANK) + elif location is LocationType.TANK: + name = ReactionDynamics.to_key(species, LocationType.TANK) try: self._tank_dynamics.__delitem__(name) except KeyError: @@ -629,11 +720,25 @@ def remove_reaction(self, species: Union[str, Species], location: Union[str, int raise ValueError("Invalid location, {}".format(location)) def get_reaction(self, species, location): + """Get a reaction for a species at either a pipe or tank. + + Parameters + ---------- + species : str or Species + the species to get a reaction for + location : str, int, or LocationType + the location of the reaction + + Returns + ------- + ReactionDynamics + the requested reaction object + """ species = str(species) - location = RxnLocationType.factory(location) - if location == RxnLocationType.PIPE: + location = LocationType.get(location) + if location == LocationType.PIPE: return self._pipe_dynamics.get(species, None) - elif location == RxnLocationType.TANK: + elif location == LocationType.TANK: return self._tank_dynamics.get(species, None) def init_printing(self, *args, **kwargs): @@ -641,15 +746,27 @@ def init_printing(self, *args, **kwargs): init_printing(*args, **kwargs) @property - def options(self) -> RxnOptions: + def citations(self) -> List[Union[str, Citation]]: + """A list of citation strings or Citation objects. + The Citation object from wntr.utils does not have to be used, but an object of + a different type should have a "to_dict" method to ensure that dictionary and + json conversions work as intended. + """ + return self._citations + + @property + def options(self) -> MultispeciesOptions: """The multispecies reaction model options.""" return self._options @options.setter def options(self, value): - if not isinstance(value, RxnOptions): + if isinstance(value, dict): + self._options = MultispeciesOptions.factory(value) + elif not isinstance(value, MultispeciesOptions): raise TypeError("Expected a RxnOptions object, got {}".format(type(value))) - self._options = value + else: + self._options = value def link_water_network_model(self, wn: WaterNetworkModel): self._wn = wn @@ -658,26 +775,14 @@ def add_pattern(self, name, pat): self._patterns[name] = pat def to_dict(self) -> dict: - rep = dict() - rep["version"] = 'wntr.reactions-0.0.1' - rep["title"] = self.title - rep["desc"] = self.desc - rep["original_filename"] = self.filename - rep["citations"] = [(c.to_dict() if isinstance(c, Citation) else c) for c in self.citations] - rep["options"] = self._options.to_dict() - rep["variables"] = dict() - rep["variables"]["species"] = [v.to_dict() for v in self._species.values()] - rep["variables"]["coefficients"] = [v.to_dict() for v in self._coeffs.values()] - rep["variables"]["other_terms"] = [v.to_dict() for v in self._terms.values()] - rep["reactions"] = dict() - rep["reactions"]["pipes"] = [v.to_dict() for v in self._pipe_dynamics.values()] - rep["reactions"]["tanks"] = [v.to_dict() for v in self._tank_dynamics.values()] - rep["patterns"] = self._patterns.copy() - rep["initial_quality"] = self._inital_quality.copy() - # rep["sources"] = dict() - # for sp, v in self._sources: - # if v is not None and len(v) > 0: - # rep["sources"][sp] = dict() - # for node, source in v.items(): - # rep["sources"][sp][node] = source.to_dict() - return rep + """Convert this water quality model to a dictionary""" + wntr.reaction.io.to_dict() + + def from_dict(self, d) -> dict: + """Append to this water quality model from a dictionary""" + wntr.reaction.io.from_dict(d, append=self) + + def __repr__(self): + if self._msxfile or self.name: + return "{}({})".format(self.__class__.__name__, repr(self._msxfile) if self._msxfile else repr(self.name)) + return super().__repr__() diff --git a/wntr/reaction/options.py b/wntr/reaction/options.py index 69eb722a4..1f113f52e 100644 --- a/wntr/reaction/options.py +++ b/wntr/reaction/options.py @@ -1,3 +1,7 @@ +# coding: utf-8 +"""Options for multispecies reaction models. +""" + import re import logging import copy @@ -180,7 +184,7 @@ def __init__(self, **kwargs): self.__dict__[k] = v -class RxnOptions(_OptionsBase): +class MultispeciesOptions(_OptionsBase): """ Water network model options class. @@ -190,12 +194,6 @@ class RxnOptions(_OptionsBase): Parameters ---------- - title : str - The title to print in the .msx file - - time : TimeOptions - Contains all timing options for the scenarios - quality : QualityOptions Contains water quality simulation options and source definitions diff --git a/wntr/reaction/toolkitmsx.py b/wntr/reaction/toolkitmsx.py deleted file mode 100644 index cca0a09c5..000000000 --- a/wntr/reaction/toolkitmsx.py +++ /dev/null @@ -1,514 +0,0 @@ -""" -The wntr.reaction.toolkit module is a Python extension for the EPANET MSX -Programmers Toolkit DLLs. - -.. note:: - - Code in this section taken from code originally written by Junli Hao 07/29/2018, - "EPANET-MSX-Python-wrapper" on GitHub, licensed under the BSD license. See LICENSE.txt for more - details. - - -""" -import ctypes -import os -import os.path -import platform -import sys -from ctypes import byref - -from pkg_resources import resource_filename - -from ..epanet.toolkit import ENepanet -from ..epanet.util import SizeLimits -from .exceptions import EpanetMsxException - -epanet_toolkit = "wntr.epanet.toolkit" - -if os.name in ["nt", "dos"]: - libepanet = resource_filename(__name__, "Windows/epanet2.dll") - libmsx = resource_filename(__name__, "Windows/epanetmsx.dll") -elif sys.platform in ["darwin"]: - libepanet = resource_filename(__name__, "Darwin/libepanet.dylib") - libmsx = resource_filename(__name__, "Darwin/libepanetmsx.dylib") -else: - libepanet = resource_filename(__name__, "Linux/libepanet2.so") - libmsx = resource_filename(__name__, "Linux/libepanetmsx.so") - -import logging - -logger = logging.getLogger(__name__) - - -class MSXepanet(ENepanet): - def __init__(self, inpfile="", rptfile="", binfile="", version=2.2): - - self.ENlib = None - self.errcode = 0 - self.errcodelist = [] - self.cur_time = 0 - - self.Warnflag = False - self.Errflag = False - self.fileLoaded = False - - self.inpfile = inpfile - self.rptfile = rptfile - self.binfile = binfile - - if float(version) == 2.0: - libnames = ["epanetmsx"] - if "64" in platform.machine(): - libnames.insert(0, "epanetmsx_amd64") - elif float(version) == 2.2: - libnames = ["epanetmsx", "epanetmsx_win32"] - if "64" in platform.machine(): - libnames.insert(0, "epanetmsx_amd64") - for lib in libnames: - try: - if os.name in ["nt", "dos"]: - libepanet = resource_filename(epanet_toolkit, "Windows/%s.dll" % lib) - self.ENlib = ctypes.windll.LoadLibrary(libepanet) - elif sys.platform in ["darwin"]: - libepanet = resource_filename(epanet_toolkit, "Darwin/lib%s.dylib" % lib) - self.ENlib = ctypes.cdll.LoadLibrary(libepanet) - else: - libepanet = resource_filename(epanet_toolkit, "Linux/lib%s.so" % lib) - self.ENlib = ctypes.cdll.LoadLibrary(libepanet) - return - except Exception as E1: - if lib == libnames[-1]: - raise E1 - pass - finally: - self._project = None - - return - - # ----------running the simulation----------------------------------------------------- - def MSXopen(self, nomeinp): - """Opens the MSX Toolkit to analyze a particular distribution system - Arguments: - nomeinp: name of the msx input file - """ - ierr = self.ENlib.MSXopen(ctypes.c_char_p(nomeinp.encode())) - if ierr != 0: - raise EpanetMsxException(ierr) - - def MSXclose( - self, - ): - """Closes down the Toolkit system (including all files being processed)""" - ierr = self.ENlib.MSXclose() - if ierr != 0: - raise EpanetMsxException(ierr) - - def MSXusehydfile(self, fname): - """Uses the contents of the specified file as the current binary hydraulics file""" - ierr = self.ENlib.MSXusehydfile(ctypes.c_char_p(fname.encode())) - if ierr != 0: - raise EpanetMsxException(ierr) - - def MSXsolveH( - self, - ): - """Runs a complete hydraulic simulation with results - for all time periods written to the binary Hydraulics file.""" - ierr = self.ENlib.MSXsolveH() - if ierr != 0: - raise EpanetMsxException(ierr) - - def MSXinit(self, saveFlag=0): - """Initializes the MSX system before solving for water quality results in step-wise fashion - set saveFlag to 1 if water quality results should be saved to a scratch binary file, or to 0 is not saved to file""" - ierr = self.ENlib.MSXinit(saveFlag) - if ierr != 0: - raise EpanetMsxException(ierr) - - def MSXsolveQ( - self, - ): - """solves for water quality over the entire simulation period and saves the results to an internal scratch file""" - ierr = self.ENlib.MSXsolveQ() - if ierr != 0: - raise EpanetMsxException(ierr) - - def MSXstep( - self, - ): - """Advances the water quality simulation one water quality time step. - The time remaining in the overall simulation is returned as tleft, the current time as t.""" - t = ctypes.c_long() - tleft = ctypes.c_long() - ierr = self.ENlib.MSXstep(ctypes.byref(t), ctypes.byref(tleft)) - if ierr != 0: - raise EpanetMsxException(ierr) - out = [t.value, tleft.value] - return out - - def MSXsaveoutfile(self, fname): - """saves water quality results computed for each node, link and reporting time period to a named binary file""" - ierr = self.ENlib.MSXsaveoutfile(ctypes.c_char_p(fname.encode())) - if ierr != 0: - raise EpanetMsxException(ierr) - - def MSXsavemsxfile(self, fname): - """saves the data associated with the current MSX project into a new MSX input file""" - ierr = self.ENlib.MSXsavemsxfile(ctypes.c_char_p(fname.encode())) - if ierr != 0: - raise EpanetMsxException(ierr) - - def MSXreport( - self, - ): - """Writes water quality simulations results as instructed by the MSX input file to a text file""" - ierr = self.ENlib.MSXreport() - if ierr != 0: - raise EpanetMsxException(ierr) - - # ---------get parameters--------------------------------------------------------------- - def MSXgetindex(self, type, name): - """Retrieves the internal index of an MSX object given its name. - Arguments: - type (int) - MSX_SPECIES - 3 (for a chemical species) - MSX_CONSTANT - 6 (for a reaction constant - MSX_PARAMETER - 5 (for a reaction parameter) - MSX_PATTERN - 7 (for a time pattern)""" - type_ind = 100 # in case the type input is in text - if type == "MSX_SPECIES" or type == 3: - type_ind = 3 - if type == "MSX_CONSTANT" or type == 6: - type_ind = 6 - if type == "MSX_PARAMETER" or type == 5: - type_ind = 5 - if type == "MSX_PATTERN" or type == 7: - type_ind = 7 - if type_ind == 100: - raise Exception("unrecognized type") - ind = ctypes.c_int() - ierr = self.ENlib.MSXgetindex(type_ind, ctypes.c_char_p(name.encode()), ctypes.byref(ind)) - if ierr != 0: - raise EpanetMsxException(ierr) - return ind.value - - def MSXgetIDlen(self, type, index): - """Retrieves the number of characters in the ID name of an MSX object given its internal index number. - Arguments: - type - int: - MSX_SPECIES - 3 (for a chemical species) - MSX_CONSTANT - 6 (for a reaction constant - MSX_PARAMETER - 5 (for a reaction parameter) - MSX_PATTERN - 7 (for a time pattern)""" - type_ind = 100 # in case the type input is in text - if type == "MSX_SPECIES" or type == 3: - type_ind = 3 - if type == "MSX_CONSTANT" or type == 6: - type_ind = 6 - if type == "MSX_PARAMETER" or type == 5: - type_ind = 5 - if type == "MSX_PATTERN" or type == 7: - type_ind = 7 - if type_ind == 100: - raise Exception("unrecognized type") - len = ctypes.c_int() - ierr = self.ENlib.MSXgetIDlen(type_ind, ctypes.c_int(index), ctypes.byref(len)) - if ierr != 0: - raise EpanetMsxException(ierr) - return len.value - - def MSXgetID(self, type, index): - """Retrieves the ID name of an object given its internal index number - Arguments: - type: - MSX_SPECIES - 3 (for a chemical species) - MSX_CONSTANT - 6 (for a reaction constant - MSX_PARAMETER - 5 (for a reaction parameter) - MSX_PATTERN - 7 (for a time pattern) - maxlen: maxi number of characters that id can hold not counting null termination character""" - type_ind = 100 # in case the type input is in text - if type == "MSX_SPECIES" or type == 3: - type_ind = 3 - if type == "MSX_CONSTANT" or type == 6: - type_ind = 6 - if type == "MSX_PARAMETER" or type == 5: - type_ind = 5 - if type == "MSX_PATTERN" or type == 7: - type_ind = 7 - if type_ind == 100: - raise Exception("unrecognized type") - maxlen = 32 - id = ctypes.create_string_buffer(maxlen) - ierr = self.ENlib.MSXgetID(type_ind, ctypes.c_int(index), ctypes.byref(id), ctypes.c_int(maxlen - 1)) - if ierr != 0: - raise EpanetMsxException(ierr) - # the .decode() added my MF 6/3/21 - return id.value.decode() - - def MSXgetinitqual(self, type, ind, spe): - """Retrieves the initial concentration of a particular chemical species assigned to a specific node - or link of the pipe network. - Arguments: - type is type of object: MSX_NODE (0), MSX_LINK (1) - ind is the internal sequence number (starting from 1) assigned to the node or link - speicies is the sequence number of teh species (starting from 1)""" - type_ind = 100 - if type == "MSX_NODE" or type == 0: - type_ind = 0 - if type == "MSX_LINK" or type == 1: - type_ind = 1 - if type_ind == 100: - raise Exception("unrecognized type") - iniqual = ctypes.c_double() - ierr = self.ENlib.MSXgetinitqual(ctypes.c_int(type_ind), ctypes.c_int(ind), ctypes.c_int(spe), ctypes.byref(iniqual)) - if ierr != 0: - raise EpanetMsxException(ierr) - return iniqual.value - - def MSXgetqual(self, type, ind, spe): - """Retrieves a chemical species concentration at a given node or the average concentration along a link at the current simulation time step - Arguments: - type is type of object: MSX_NODE (0), MSX_LINK (1) - ind is the internal sequence number (starting from 1) assigned to the node or link - speicies is the sequence number of teh species (starting from 1) - concentrations expressed as: mass units per liter for bulk species and mass per unit area for surface species""" - type_ind = 100 - if type == "MSX_NODE" or type == 0: - type_ind = 0 - if type == "MSX_LINK" or type == 1: - type_ind = 1 - if type_ind == 100: - raise Exception("unrecognized type") - qual = ctypes.c_double() - ierr = self.ENlib.MSXgetqual(ctypes.c_int(type_ind), ctypes.c_int(ind), ctypes.c_int(spe), ctypes.byref(qual)) - if ierr != 0: - raise EpanetMsxException(ierr) - return qual.value - - def MSXgetconstant(self, ind): - """Retrieves the value of a particular reaction constant - Arguments: - ind is the sequence number of the reaction constant (starting from 1) as it appeared in the MSX input file""" - const = ctypes.c_double() - ierr = self.ENlib.MSXgetconstant(ind, ctypes.byref(const)) - if ierr != 0: - raise EpanetMsxException(ierr) - return const.value - - def MSXgetparameter(self, type, ind, param_ind): - """Retrieves the value of a particular reaction parameter for a give TANK or PIPE - Arguments: - type is the type of object: MSX_NODE (0) or MSX_LINK (1) - ind is the internal sequence number(starting from 1) assigned to the node or link - param is the sequence number of the parameter (starting from 1 as listed in the MSX input file)""" - type_ind = 100 # in case type input is in text - if type == "MSX_NODE" or type == 0: - type_ind = 0 - if type == "MSX_LINK" or type == 1: - type_ind = 1 - if type_ind == 100: - raise Exception("unrecognized type") - param = ctypes.c_double() - ierr = self.ENlib.MSXgetparameter(ctypes.c_int(type_ind), ctypes.c_int(ind), ctypes.c_int(param_ind), ctypes.byref(param)) - if ierr != 0: - raise EpanetMsxException(ierr) - return param.value - - def MSXgetsource(self, node, spe): - """Retrieves information on any external source of a particular chemical species assigned to a specific node of the pipe network - Arguments: - node is the internal sequence number (starting from 1) assigned to the node of interest - species is the sequence number of the species of interest (starting from 1 as listed in the MSX input file) - type is returned with the type of external source and will be one of the following pre-defined constants - MSX_NOSOURCE (-1) no source; MSX_CONCEN (0) a concentration source; MSX_MASS (1) mass booster source; - MSX_SETPOINT (2) setpoint source; MSX_FLOWPACED (3) flow paced source - level is returned with the baseline concentration (or mass flow rate) of the source - pat is returned with the index of the time pattern used to add variability to the source's baseline level (0 if no pattern defined for the source)""" - level = ctypes.c_double() - type = ctypes.c_int() - pat = ctypes.c_int() - ierr = self.ENlib.MSXgetsource(ctypes.c_int(node), ctypes.c_int(spe), ctypes.byref(type), ctypes.byref(level), ctypes.byref(pat)) - if ierr != 0: - raise EpanetMsxException(ierr) - src_out = [type.value, level.value, pat.value] - return src_out - - def MSXgetpatternlen(self, pat): - """Retrieves the number of time periods within a SOURCE time pattern - Arguments: - pat is the internal sequence number (starting from 1) of the pattern as appears in the MSX input file""" - len = ctypes.c_int() - ierr = self.ENlib.MSXgetpatternlen(pat, ctypes.byref(len)) - if ierr != 0: - raise EpanetMsxException(ierr) - return len.value - - def MSXgetpatternvalue(self, pat, period): - """Retrieves the multiplier at a specific time period for a given SOURCE time pattern - Arguments: - pat is the internal sequence number (starting from 1) of the pattern as appears in the MSX input file - period is the index of the time period (starting from 1) whose multiplier is being sought - value is the vlaue of teh pattern's multiplier in teh desired period""" - val = ctypes.c_double() - ierr = self.ENlib.MSXgetpatternvalue(pat, period, ctypes.byref(val)) - if ierr != 0: - raise EpanetMsxException(ierr) - return val.value - - def MSXgetcount(self, type): - """Retrieves the number of objects of a specified type. - Arguments: - MSX_SPECIES - 3 (for a chemical species) - MSX_CONSTANT - 6 (for a reaction constant - MSX_PARAMETER - 5 (for a reaction parameter) - MSX_PATTERN - 7 (for a time pattern) - maxlen: maxi number of characters that id can hold not counting null termination character""" - type_ind = 100 # in case the type input is in text - if type == "MSX_SPECIES" or type == 3: - type_ind = 3 - if type == "MSX_CONSTANT" or type == 6: - type_ind = 6 - if type == "MSX_PARAMETER" or type == 5: - type_ind = 5 - if type == "MSX_PATTERN" or type == 7: - type_ind = 7 - if type_ind == 100: - raise Exception("unrecognized type") - count = ctypes.c_int() - ierr = self.ENlib.MSXgetcount(type_ind, ctypes.byref(count)) - if ierr != 0: - raise EpanetMsxException(ierr) - return count.value - - def MSXgetspecies(self, spe): - """Retrieves the attributes of a chemical species given its internal index number. - species is the sequence number of the species (starting from 1 as listed in the MSX input file - type: MSX_BULK (defined as 0) and MSX_WALL (defined as 1) - units: C_style character string array that is returned with the mass units that were defined for the species in question(hold max 15 characters) - aTol returned with absolute concentration tolerance defined for the species - rTol returned with the relative concentration tolerance defined for the species""" - type_ind = ctypes.c_int() - units = ctypes.create_string_buffer(15) - aTol = ctypes.c_double() - rTol = ctypes.c_double() - ierr = self.ENlib.MSXgetspecies(spe, ctypes.byref(type_ind), ctypes.byref(units), ctypes.byref(aTol), ctypes.byref(rTol)) - if ierr != 0: - raise EpanetMsxException(ierr) - spe_out = [type_ind.value, units.value, aTol.value, rTol.value] - return spe_out - - def MSXgeterror(self, errcode, len=100): - """returns the text for an error message given its error code - arguments: - code is the code number of an error condition generated by EPANET-MSX - msg is a C-style string containing text of error message corresponding to error code - len is the max number of charaters that msg can contain (at least 80)""" - errmsg = ctypes.create_string_buffer(len) - self.ENlib.MSXgeterror(errcode, ctypes.byref(errmsg), len) - return errmsg.value.decode() - - # --------------set parameters----------------------------------- - - def MSXsetconstant(self, ind, value): - """assigns a new value to a specific reaction constant - Arguments: - ind is the sequence number of the reaction constant (starting from 1) as it appreaed in the MSX input file - value is the new value to be assigned to the constant""" - ierr = self.ENlib.MSXsetconstant(ctypes.c_int(ind), ctypes.c_double(value)) - if ierr != 0: - raise EpanetMsxException(ierr) - - def MSXsetparameter(self, type, ind, param, value): - """assigns a value to a particular reaction parameter for a given TANK or PIPE - Arguments: - type is the type of object: MSX_NODE (0) or MSX_LINK (1) - ind is the internal sequence number(starting from 1) assigned to the node or link - param is the sequence number of the parameter (starting from 1 as listed in the MSX input file""" - type_ind = 100 - if type == "MSX_NODE" or type == 0: - type_ind = 0 - if type == "MSX_LINK" or type == 1: - type_ind = 1 - if type_ind == 100: - raise Exception("unrecognized type") - ierr = self.ENlib.MSXsetparameter(ctypes.c_int(type_ind), ctypes.c_int(ind), ctypes.c_int(param), ctypes.c_double(value)) - if ierr != 0: - raise EpanetMsxException(ierr) - - def MSXsetinitqual(self, type, ind, spe, value): - """Retrieves the initial concentration of a particular chemical species assigned to a specific node - or link of the pipe network. - Arguments: - type is type of object: MSX_NODE (0), MSX_LINK (1) - ind is the internal sequence number (starting from 1) assigned to the node or link - speicies is the sequence number of teh species (starting from 1)""" - type_ind = 100 - if type == "MSX_NODE" or type == 0: - type_ind = 0 - if type == "MSX_LINK" or type == 1: - type_ind = 1 - if type_ind == 100: - raise Exception("unrecognized type") - ierr = self.ENlib.MSXsetinitqual(ctypes.c_int(type_ind), ctypes.c_int(ind), ctypes.c_int(spe), ctypes.c_double(value)) - if ierr != 0: - raise EpanetMsxException(ierr) - - def MSXsetsource(self, node, spe, type_n, level, pat): - """sets the attributes of an external source of a particular chemical species in a specific node of the pipe network - Arguments: - node is the internal sequence number (starting from 1) assigned to the node of interest - species is the sequence number of the species of interest (starting from 1 as listed in the MSX input file) - type is returned with the type of exteernal source and will be one of the following pre-defined constants - MSX_NOSOURCE (-1) no source; MSX_CONCEN (0) a concentration source; MSX_MASS (1) mass booster source; - MSX_SETPOINT (2) setpoint source; MSX_FLOWPACED (3) flow paced source - level is the baseline concentration (or mass flow rate) of the source - pat is the index of the time pattern used to add variability to the source's baseline level (0 if no pattern defined for the source)""" - type_ind = 100 - if type_n == "MSX_NOSOURCE" or type_n == -1: - type_ind = -1 - if type_n == "MSX_CONCEN" or type_n == 0: - type_ind = 0 - if type_n == "MSX_MASS" or type_n == 1: - type_ind = 1 - if type_n == "MSX_SETPOINT" or type_n == 2: - type_ind = 2 - if type_n == "MSX_FLOWPACED" or type_n == 3: - type_ind = 3 - if type_ind == 100: - raise Exception("unrecognized type") - ierr = self.ENlib.MSXsetsource(ctypes.c_int(node), ctypes.c_int(spe), ctypes.c_int(type_ind), ctypes.c_double(level), ctypes.c_int(pat)) - if ierr != 0: - raise EpanetMsxException(ierr) - - def MSXsetpattern(self, pat, mult): - """assigns a new set of multipliers to a given MSX SOURCE time pattern - Arguments: - pat is the internal sequence number (starting from 1) of the pattern as appears in the MSX input file - mult is an array of multiplier values to replace those preciously used by the pattern - len is the number of entries in mult""" - length = len(mult) - cfactors_type = ctypes.c_double * length - cfactors = cfactors_type() - for i in range(length): - cfactors[i] = float(mult[i]) - ierr = self.ENlib.MSXsetpattern(ctypes.c_int(pat), cfactors, ctypes.c_int(length)) - if ierr != 0: - raise EpanetMsxException(ierr) - - def MSXsetpatternvalue(self, pat, period, value): - """Sets the multiplier factor for a specific period within a SOURCE time pattern. - Arguments: - index: time pattern index - period: period within time pattern - value: multiplier factor for the period""" - ierr = self.ENlib.MSXsetpatternvalue(ctypes.c_int(pat), ctypes.c_int(period), ctypes.c_double(value)) - if ierr != 0: - raise EpanetMsxException(ierr) - - def MSXaddpattern(self, patternid): - """Adds a new, empty MSX source time pattern to an MSX project. - Arguments: - pattern id: c-string name of pattern""" - ierr = self.ENlib.MSXaddpattern(ctypes.c_char_p(patternid.encode())) - if ierr != 0: - raise EpanetMsxException(ierr) diff --git a/wntr/reaction/variables.py b/wntr/reaction/variables.py index a29ff9b55..aabbbe725 100644 --- a/wntr/reaction/variables.py +++ b/wntr/reaction/variables.py @@ -17,6 +17,20 @@ that will convert object instances of these classes into sympy expressions and symbols. If the instances are linked to a model, then expressions can be expanded, validated, and even evaluated or simplified symbolically. + +.. rubric:: Contents + +.. autosummary:: + + Species + BulkSpecies + WallSpecies + Coefficient + Constant + Parameter + OtherTerm + InternalVariable + """ import enum @@ -25,6 +39,7 @@ from dataclasses import InitVar, asdict, dataclass, field from enum import Enum, IntFlag from typing import Any, ClassVar, Dict, List, Set, Tuple, Union +from .base import MSXComment has_sympy = False try: @@ -47,18 +62,17 @@ RESERVED_NAMES, ExpressionMixin, LinkedVariablesMixin, - MSXComment, - MSXObject, - RxnModelRegistry, - RxnVariable, - RxnVariableType, + MsxObjectMixin, + AbstractReactionModel, + ReactionVariable, + VariableType, ) logger = logging.getLogger(__name__) @dataclass(repr=False) -class Species(MSXObject, LinkedVariablesMixin, RxnVariable): +class Species(MsxObjectMixin, LinkedVariablesMixin, ReactionVariable): units: str """The unit used for this species""" @@ -70,7 +84,7 @@ class Species(MSXObject, LinkedVariablesMixin, RxnVariable): """A note about this species, by default None""" diffusivity: float = None """The diffusivity value for this species, by default None""" - variable_registry: InitVar[RxnModelRegistry] = None + variable_registry: InitVar[AbstractReactionModel] = None def __post_init__(self, atol=None, rtol=None, reaction_model=None): if isinstance(atol, property): @@ -175,24 +189,24 @@ def to_dict(self): @dataclass(repr=False) class BulkSpecies(Species): @property - def var_type(self) -> RxnVariableType: - return RxnVariableType.BULK + def var_type(self) -> VariableType: + return VariableType.BULK @dataclass(repr=False) class WallSpecies(Species): @property - def var_type(self) -> RxnVariableType: - return RxnVariableType.WALL + def var_type(self) -> VariableType: + return VariableType.WALL @dataclass(repr=False) -class Coefficient(MSXObject, LinkedVariablesMixin, RxnVariable): +class Coefficient(MsxObjectMixin, LinkedVariablesMixin, ReactionVariable): global_value: float note: Union[str, Dict[str, str]] = None units: str = None - variable_registry: InitVar[RxnModelRegistry] = None + variable_registry: InitVar[AbstractReactionModel] = None def __post_init__(self, reaction_model): if self.name in RESERVED_NAMES: @@ -232,8 +246,8 @@ def to_dict(self): @dataclass(repr=False) class Constant(Coefficient): @property - def var_type(self) -> RxnVariableType: - return RxnVariableType.CONST + def var_type(self) -> VariableType: + return VariableType.CONST @dataclass(repr=False) @@ -252,8 +266,8 @@ def __post_init__(self, reaction_model): self._tank_values = dict() @property - def var_type(self) -> RxnVariableType: - return RxnVariableType.PARAM + def var_type(self) -> VariableType: + return VariableType.PARAM def get_value(self, pipe: str = None, tank: str = None) -> float: if pipe is not None and tank is not None: @@ -280,7 +294,7 @@ def to_dict(self): @dataclass(repr=False) -class OtherTerm(MSXObject, LinkedVariablesMixin, ExpressionMixin, RxnVariable): +class OtherTerm(MsxObjectMixin, LinkedVariablesMixin, ExpressionMixin, ReactionVariable): """A function definition used as a shortcut in reaction expressions (called a 'term' in EPANET-MSX) Parameters @@ -299,7 +313,7 @@ class OtherTerm(MSXObject, LinkedVariablesMixin, ExpressionMixin, RxnVariable): """The expression this named-function is equivalent to""" note: Union[str, Dict[str, str]] = None """A note about this function/term""" - variable_registry: InitVar[RxnModelRegistry] = field(default=None, compare=False) + variable_registry: InitVar[AbstractReactionModel] = field(default=None, compare=False) def __post_init__(self, reaction_model): if self.name in RESERVED_NAMES: @@ -310,8 +324,8 @@ def __repr__(self): return "{}(name={}, expression={}, note={})".format(self.__class__.__name__, repr(self.name), repr(self.expression), repr(self.note)) @property - def var_type(self) -> RxnVariableType: - return RxnVariableType.TERM + def var_type(self) -> VariableType: + return VariableType.TERM def to_msx_string(self) -> str: return "{:<8s} {:<64s}".format(self.name, self.expression) @@ -331,7 +345,7 @@ def to_dict(self): @dataclass(repr=False) -class InternalVariable(RxnVariable): +class InternalVariable(ReactionVariable): """A hydraulic variable or a placeholder for a built-in reserved word. For example, "Len" is the EPANET-MSX name for the length of a pipe, and "I" is a sympy @@ -344,5 +358,5 @@ def __repr__(self): return "{}(name={}, note={}, units={})".format(self.__class__.__name__, repr(self.name), repr(self.note), repr(self.units)) @property - def var_type(self) -> RxnVariableType: - return RxnVariableType.INTERNAL + def var_type(self) -> VariableType: + return VariableType.INTERNAL diff --git a/wntr/tests/test_reactions.py b/wntr/tests/test_reaction_variables.py similarity index 53% rename from wntr/tests/test_reactions.py rename to wntr/tests/test_reaction_variables.py index 41d07b098..480cb9a1d 100644 --- a/wntr/tests/test_reactions.py +++ b/wntr/tests/test_reaction_variables.py @@ -24,35 +24,35 @@ def tearDownClass(self): pass def test_ReactionVariable_reserved_name_exception(self): - self.assertRaises(ValueError, wntr.reaction.model.BulkSpecies, "D", "mg") - self.assertRaises(ValueError, wntr.reaction.model.WallSpecies, "Q", "mg") - self.assertRaises(ValueError, wntr.reaction.model.Constant, "Re", 0.52) - self.assertRaises(ValueError, wntr.reaction.model.Parameter, "Re", 0.52) - self.assertRaises(ValueError, wntr.reaction.model.OtherTerm, "Re", 0.52) + self.assertRaises(ValueError, wntr.reaction.BulkSpecies, "D", "mg") + self.assertRaises(ValueError, wntr.reaction.WallSpecies, "Q", "mg") + self.assertRaises(ValueError, wntr.reaction.Constant, "Re", 0.52) + self.assertRaises(ValueError, wntr.reaction.Parameter, "Re", 0.52) + self.assertRaises(ValueError, wntr.reaction.OtherTerm, "Re", 0.52) def test_RxnVariable_symbols_and_sympy(self): - species1 = wntr.reaction.model.BulkSpecies("Cl", "mg") + species1 = wntr.reaction.BulkSpecies("Cl", "mg") symbol1 = sympy.symbols("Cl") self.assertEqual(species1.symbol, symbol1) - const1 = wntr.reaction.model.Constant("Kb", 0.482) + const1 = wntr.reaction.Constant("Kb", 0.482) symbol2 = sympy.symbols("Kb") self.assertEqual(const1.symbol, symbol2) - param1 = wntr.reaction.model.Constant("Ka", 0.482) + param1 = wntr.reaction.Constant("Ka", 0.482) symbol3 = sympy.symbols("Ka") self.assertEqual(param1.symbol, symbol3) - term1 = wntr.reaction.model.OtherTerm("T0", "-3.2 * Kb * Cl^2", note="bar") + term1 = wntr.reaction.OtherTerm("T0", "-3.2 * Kb * Cl^2", note="bar") symbol4 = sympy.symbols("T0") self.assertEqual(term1.symbol, symbol4) def test_RxnVariable_values(self): - const1 = wntr.reaction.model.Constant("Kb", 0.482, note="test") + const1 = wntr.reaction.Constant("Kb", 0.482, note="test") self.assertEqual(const1.get_value(), const1.global_value) test_pipe_dict = {"PIPE": 0.38} test_tank_dict = {"TANK": 222.23} - param2 = wntr.reaction.model.Parameter("Kb", 0.482, note="test", _pipe_values=test_pipe_dict, _tank_values=test_tank_dict) + param2 = wntr.reaction.Parameter("Kb", 0.482, note="test", _pipe_values=test_pipe_dict, _tank_values=test_tank_dict) self.assertEqual(param2.get_value(), param2.global_value) self.assertEqual(param2.get_value(pipe="PIPE"), test_pipe_dict["PIPE"]) self.assertEqual(param2.get_value(pipe="FOO"), param2.global_value) @@ -60,11 +60,11 @@ def test_RxnVariable_values(self): self.assertRaises(TypeError, param2.get_value, pipe="PIPE", tank="TANK") def test_RxnVariable_string_functions(self): - species1 = wntr.reaction.model.BulkSpecies("Cl", "mg") - species2 = wntr.reaction.model.WallSpecies("Cl", "mg", 0.01, 0.0001, note="Testing stuff") - const1 = wntr.reaction.model.Constant("Kb", 0.482) - param1 = wntr.reaction.model.Parameter("Ka", 0.482, note="foo") - term1 = wntr.reaction.model.OtherTerm("T0", "-3.2 * Kb * Cl^2", note="bar") + species1 = wntr.reaction.BulkSpecies("Cl", "mg") + species2 = wntr.reaction.WallSpecies("Cl", "mg", 0.01, 0.0001, note="Testing stuff") + const1 = wntr.reaction.Constant("Kb", 0.482) + param1 = wntr.reaction.Parameter("Ka", 0.482, note="foo") + term1 = wntr.reaction.OtherTerm("T0", "-3.2 * Kb * Cl^2", note="bar") self.assertEqual(str(species1), "Cl") self.assertEqual(species1.to_msx_string(), "BULK Cl mg ;") @@ -78,8 +78,8 @@ def test_RxnVariable_string_functions(self): def test_Species_tolerances(self): # """RxnSpecies(*s) tolerance settings""" - species1 = wntr.reaction.model.BulkSpecies("Cl", "mg") - species2 = wntr.reaction.model.WallSpecies("Cl", "mg", 0.01, 0.0001, note="Testing stuff") + species1 = wntr.reaction.BulkSpecies("Cl", "mg") + species2 = wntr.reaction.WallSpecies("Cl", "mg", 0.01, 0.0001, note="Testing stuff") self.assertIsNone(species1.get_tolerances()) self.assertIsNotNone(species2.get_tolerances()) self.assertTupleEqual(species2.get_tolerances(), (0.01, 0.0001)) @@ -99,19 +99,19 @@ def test_Species_tolerances(self): def test_BulkSpecies_creation(self): # """BlukSpecies object creation (direct instantiation)""" - self.assertRaises(TypeError, wntr.reaction.model.BulkSpecies, "Re") - self.assertRaises(ValueError, wntr.reaction.model.BulkSpecies, "Re", "mg") - self.assertRaises(TypeError, wntr.reaction.model.BulkSpecies, "Cl", "mg", 0.01) - self.assertRaises(TypeError, wntr.reaction.model.BulkSpecies, "Cl", "mg", None, 0.01) - species = wntr.reaction.model.BulkSpecies("Cl", "mg") + self.assertRaises(TypeError, wntr.reaction.BulkSpecies, "Re") + self.assertRaises(ValueError, wntr.reaction.BulkSpecies, "Re", "mg") + self.assertRaises(TypeError, wntr.reaction.BulkSpecies, "Cl", "mg", 0.01) + self.assertRaises(TypeError, wntr.reaction.BulkSpecies, "Cl", "mg", None, 0.01) + species = wntr.reaction.BulkSpecies("Cl", "mg") self.assertEqual(species.name, "Cl") self.assertEqual(species.units, "mg") - self.assertEqual(species.var_type, wntr.reaction.model.RxnVariableType.BULK) + self.assertEqual(species.var_type, wntr.reaction.VariableType.BULK) self.assertIsNone(species.atol) self.assertIsNone(species.rtol) self.assertIsNone(species.note) - species = wntr.reaction.model.BulkSpecies("Cl", "mg", 0.01, 0.0001, note="Testing stuff") - self.assertEqual(species.var_type, wntr.reaction.model.RxnVariableType.BULK) + species = wntr.reaction.BulkSpecies("Cl", "mg", 0.01, 0.0001, note="Testing stuff") + self.assertEqual(species.var_type, wntr.reaction.VariableType.BULK) self.assertEqual(species.name, "Cl") self.assertEqual(species.units, "mg") self.assertEqual(species.atol, 0.01) @@ -120,19 +120,19 @@ def test_BulkSpecies_creation(self): def test_WallSpecies_creation(self): # """WallSpecies object creation (direct instantiation)""" - self.assertRaises(TypeError, wntr.reaction.model.WallSpecies, "Re") - self.assertRaises(ValueError, wntr.reaction.model.WallSpecies, "Re", "mg") - self.assertRaises(TypeError, wntr.reaction.model.WallSpecies, "Cl", "mg", 0.01) - self.assertRaises(TypeError, wntr.reaction.model.WallSpecies, "Cl", "mg", None, 0.01) - species = wntr.reaction.model.WallSpecies("Cl", "mg") + self.assertRaises(TypeError, wntr.reaction.WallSpecies, "Re") + self.assertRaises(ValueError, wntr.reaction.WallSpecies, "Re", "mg") + self.assertRaises(TypeError, wntr.reaction.WallSpecies, "Cl", "mg", 0.01) + self.assertRaises(TypeError, wntr.reaction.WallSpecies, "Cl", "mg", None, 0.01) + species = wntr.reaction.WallSpecies("Cl", "mg") self.assertEqual(species.name, "Cl") self.assertEqual(species.units, "mg") - self.assertEqual(species.var_type, wntr.reaction.model.RxnVariableType.WALL) + self.assertEqual(species.var_type, wntr.reaction.VariableType.WALL) self.assertIsNone(species.atol) self.assertIsNone(species.rtol) self.assertIsNone(species.note) - species = wntr.reaction.model.WallSpecies("Cl", "mg", 0.01, 0.0001, note="Testing stuff") - self.assertEqual(species.var_type, wntr.reaction.model.RxnVariableType.WALL) + species = wntr.reaction.WallSpecies("Cl", "mg", 0.01, 0.0001, note="Testing stuff") + self.assertEqual(species.var_type, wntr.reaction.VariableType.WALL) self.assertEqual(species.name, "Cl") self.assertEqual(species.units, "mg") self.assertEqual(species.atol, 0.01) @@ -140,78 +140,78 @@ def test_WallSpecies_creation(self): self.assertEqual(species.note, "Testing stuff") def test_Constant_creation(self): - self.assertRaises(TypeError, wntr.reaction.model.Constant, "Re") - self.assertRaises(ValueError, wntr.reaction.model.Constant, "Re", 2.48) - const1 = wntr.reaction.model.Constant("Kb", 0.482, note="test") + self.assertRaises(TypeError, wntr.reaction.Constant, "Re") + self.assertRaises(ValueError, wntr.reaction.Constant, "Re", 2.48) + const1 = wntr.reaction.Constant("Kb", 0.482, note="test") # FIXME: Find a way to suppress warning printing - # self.assertWarns(RuntimeWarning, wntr.reaction.model.Constant, 'Kb1', 0.83, pipe_values={'a',1}) + # self.assertWarns(RuntimeWarning, wntr.reaction.Constant, 'Kb1', 0.83, pipe_values={'a',1}) self.assertEqual(const1.name, "Kb") self.assertEqual(const1.global_value, 0.482) self.assertEqual(const1.get_value(), const1.global_value) - self.assertEqual(const1.var_type, wntr.reaction.model.RxnVariableType.CONST) + self.assertEqual(const1.var_type, wntr.reaction.VariableType.CONST) self.assertEqual(const1.note, "test") def test_Parameter_creation(self): - self.assertRaises(TypeError, wntr.reaction.model.Parameter, "Re") - self.assertRaises(ValueError, wntr.reaction.model.Parameter, "Re", 2.48) - param1 = wntr.reaction.model.Parameter("Kb", 0.482, note="test") + self.assertRaises(TypeError, wntr.reaction.Parameter, "Re") + self.assertRaises(ValueError, wntr.reaction.Parameter, "Re", 2.48) + param1 = wntr.reaction.Parameter("Kb", 0.482, note="test") self.assertEqual(param1.name, "Kb") self.assertEqual(param1.global_value, 0.482) self.assertEqual(param1.get_value(), param1.global_value) - self.assertEqual(param1.var_type, wntr.reaction.model.RxnVariableType.PARAM) + self.assertEqual(param1.var_type, wntr.reaction.VariableType.PARAM) self.assertEqual(param1.note, "test") test_pipe_dict = {"PIPE": 0.38} test_tank_dict = {"TANK": 222.23} - param2 = wntr.reaction.model.Parameter("Kb", 0.482, note="test", _pipe_values=test_pipe_dict, _tank_values=test_tank_dict) + param2 = wntr.reaction.Parameter("Kb", 0.482, note="test", _pipe_values=test_pipe_dict, _tank_values=test_tank_dict) self.assertDictEqual(param2.pipe_values, test_pipe_dict) self.assertDictEqual(param2.tank_values, test_tank_dict) def test_RxnTerm_creation(self): - self.assertRaises(TypeError, wntr.reaction.model.OtherTerm, "Re") - self.assertRaises(ValueError, wntr.reaction.model.OtherTerm, "Re", "1.0*Re") - term1 = wntr.reaction.model.OtherTerm("T0", "-3.2 * Kb * Cl^2", note="bar") + self.assertRaises(TypeError, wntr.reaction.OtherTerm, "Re") + self.assertRaises(ValueError, wntr.reaction.OtherTerm, "Re", "1.0*Re") + term1 = wntr.reaction.OtherTerm("T0", "-3.2 * Kb * Cl^2", note="bar") self.assertEqual(term1.name, "T0") self.assertEqual(term1.expression, "-3.2 * Kb * Cl^2") - self.assertEqual(term1.var_type, wntr.reaction.model.RxnVariableType.TERM) + self.assertEqual(term1.var_type, wntr.reaction.VariableType.TERM) self.assertEqual(term1.note, "bar") def test_RxnExpression_strings(self): - equil1 = wntr.reaction.model.EquilibriumDynamics("Cl", wntr.reaction.model.RxnLocationType.PIPE, "-Ka + Kb * Cl + T0") - rate1 = wntr.reaction.model.RateDynamics("Cl", wntr.reaction.model.RxnLocationType.TANK, "-Ka + Kb * Cl + T0", note="Foo Bar") - formula1 = wntr.reaction.model.FormulaDynamics("Cl", wntr.reaction.model.RxnLocationType.PIPE, "-Ka + Kb * Cl + T0") + equil1 = wntr.reaction.EquilibriumDynamics("Cl", wntr.reaction.LocationType.PIPE, "-Ka + Kb * Cl + T0") + rate1 = wntr.reaction.RateDynamics("Cl", wntr.reaction.LocationType.TANK, "-Ka + Kb * Cl + T0", note="Foo Bar") + formula1 = wntr.reaction.FormulaDynamics("Cl", wntr.reaction.LocationType.PIPE, "-Ka + Kb * Cl + T0") self.assertEqual(equil1.to_msx_string(), "EQUIL Cl -Ka + Kb * Cl + T0 ;") self.assertEqual(rate1.to_msx_string(), "RATE Cl -Ka + Kb * Cl + T0 ;Foo Bar") self.assertEqual(formula1.to_msx_string(), "FORMULA Cl -Ka + Kb * Cl + T0 ;") def test_Equilibrium_creation(self): - equil1 = wntr.reaction.model.EquilibriumDynamics("Cl", wntr.reaction.model.RxnLocationType.PIPE, "-Ka + Kb * Cl + T0") + equil1 = wntr.reaction.EquilibriumDynamics("Cl", wntr.reaction.LocationType.PIPE, "-Ka + Kb * Cl + T0") self.assertEqual(equil1.species, "Cl") self.assertEqual(equil1.expression, "-Ka + Kb * Cl + T0") - self.assertEqual(equil1.expr_type, wntr.reaction.model.RxnDynamicsType.EQUIL) + self.assertEqual(equil1.expr_type, wntr.reaction.DynamicsType.EQUIL) def test_Rate_creation(self): - rate1 = wntr.reaction.model.RateDynamics("Cl", wntr.reaction.model.RxnLocationType.TANK, "-Ka + Kb * Cl + T0", note="Foo Bar") + rate1 = wntr.reaction.RateDynamics("Cl", wntr.reaction.LocationType.TANK, "-Ka + Kb * Cl + T0", note="Foo Bar") self.assertEqual(rate1.species, "Cl") self.assertEqual(rate1.expression, "-Ka + Kb * Cl + T0") - self.assertEqual(rate1.expr_type, wntr.reaction.model.RxnDynamicsType.RATE) + self.assertEqual(rate1.expr_type, wntr.reaction.DynamicsType.RATE) self.assertEqual(rate1.note, "Foo Bar") def test_Formula_creation(self): - formula1 = wntr.reaction.model.FormulaDynamics("Cl", wntr.reaction.model.RxnLocationType.PIPE, "-Ka + Kb * Cl + T0") + formula1 = wntr.reaction.FormulaDynamics("Cl", wntr.reaction.LocationType.PIPE, "-Ka + Kb * Cl + T0") self.assertEqual(formula1.species, "Cl") self.assertEqual(formula1.expression, "-Ka + Kb * Cl + T0") - self.assertEqual(formula1.expr_type, wntr.reaction.model.RxnDynamicsType.FORMULA) + self.assertEqual(formula1.expr_type, wntr.reaction.DynamicsType.FORMULA) def test_WaterQualityReactionsModel_creation_specific_everything(self): - rxn_model1 = wntr.reaction.model.WaterQualityReactionsModel() - bulk1 = wntr.reaction.model.BulkSpecies("Cl", "mg") - wall1 = wntr.reaction.model.WallSpecies("ClOH", "mg", 0.01, 0.0001, note="Testing stuff") - const1 = wntr.reaction.model.Constant("Kb", 0.482) - param1 = wntr.reaction.model.Parameter("Ka", 0.482, note="foo") - term1 = wntr.reaction.model.OtherTerm("T0", "-3.2 * Kb * Cl^2", note="bar") - equil1 = wntr.reaction.model.EquilibriumDynamics(bulk1, wntr.reaction.model.RxnLocationType.PIPE, "-Ka + Kb * Cl + T0") - rate1 = wntr.reaction.model.RateDynamics(bulk1, wntr.reaction.model.RxnLocationType.TANK, "-Ka + Kb * Cl + T0", note="Foo Bar") - formula1 = wntr.reaction.model.FormulaDynamics(wall1, wntr.reaction.model.RxnLocationType.PIPE, "-Ka + Kb * Cl + T0") + rxn_model1 = wntr.reaction.MultispeciesReactionModel() + bulk1 = wntr.reaction.BulkSpecies("Cl", "mg") + wall1 = wntr.reaction.WallSpecies("ClOH", "mg", 0.01, 0.0001, note="Testing stuff") + const1 = wntr.reaction.Constant("Kb", 0.482) + param1 = wntr.reaction.Parameter("Ka", 0.482, note="foo") + term1 = wntr.reaction.OtherTerm("T0", "-3.2 * Kb * Cl^2", note="bar") + equil1 = wntr.reaction.EquilibriumDynamics(bulk1, wntr.reaction.LocationType.PIPE, "-Ka + Kb * Cl + T0") + rate1 = wntr.reaction.RateDynamics(bulk1, wntr.reaction.LocationType.TANK, "-Ka + Kb * Cl + T0", note="Foo Bar") + formula1 = wntr.reaction.FormulaDynamics(wall1, wntr.reaction.LocationType.PIPE, "-Ka + Kb * Cl + T0") bulk2 = rxn_model1.add_bulk_species("Cl", "mg") wall2 = rxn_model1.add_wall_species("ClOH", "mg", 0.01, 0.0001, note="Testing stuff") @@ -219,7 +219,7 @@ def test_WaterQualityReactionsModel_creation_specific_everything(self): param2 = rxn_model1.add_parameterized_coeff("Ka", 0.482, note="foo") term2 = rxn_model1.add_other_term("T0", "-3.2 * Kb * Cl^2", note="bar") equil2 = rxn_model1.add_pipe_reaction("Cl", "equil", "-Ka + Kb * Cl + T0") - rate2 = rxn_model1.add_tank_reaction("Cl", wntr.reaction.model.RxnDynamicsType.R, "-Ka + Kb * Cl + T0", note="Foo Bar") + rate2 = rxn_model1.add_tank_reaction("Cl", wntr.reaction.DynamicsType.R, "-Ka + Kb * Cl + T0", note="Foo Bar") formula2 = rxn_model1.add_reaction("PIPE", "ClOH", "formula", "-Ka + Kb * Cl + T0") self.assertEqual(bulk1, bulk2) self.assertEqual(wall1, wall2) @@ -231,22 +231,22 @@ def test_WaterQualityReactionsModel_creation_specific_everything(self): # self.assertEqual(formula1, formula2) def test_WaterQualityReactionsModel_creation_generic_species_coeffs(self): - bulk1 = wntr.reaction.model.BulkSpecies("Cl", "mg") - wall1 = wntr.reaction.model.WallSpecies("ClOH", "mg", 0.01, 0.0001, note="Testing stuff") - const1 = wntr.reaction.model.Constant("Kb", 0.482) - param1 = wntr.reaction.model.Parameter("Ka", 0.482, note="foo") - term1 = wntr.reaction.model.OtherTerm("T0", "-3.2 * Kb * Cl^2", note="bar") + bulk1 = wntr.reaction.BulkSpecies("Cl", "mg") + wall1 = wntr.reaction.WallSpecies("ClOH", "mg", 0.01, 0.0001, note="Testing stuff") + const1 = wntr.reaction.Constant("Kb", 0.482) + param1 = wntr.reaction.Parameter("Ka", 0.482, note="foo") + term1 = wntr.reaction.OtherTerm("T0", "-3.2 * Kb * Cl^2", note="bar") - rxn_model2 = wntr.reaction.model.WaterQualityReactionsModel() + rxn_model2 = wntr.reaction.MultispeciesReactionModel() - self.assertRaises(ValueError, rxn_model2.add_species, wntr.reaction.model.RxnVariableType.CONST, "Cl", "mg") + self.assertRaises(ValueError, rxn_model2.add_species, wntr.reaction.VariableType.CONST, "Cl", "mg") self.assertRaises(TypeError, rxn_model2.add_coefficient, None, "Kb", 0.482) self.assertRaises(ValueError, rxn_model2.add_coefficient, "Wall", "Kb", 0.482) bulk3 = rxn_model2.add_species("BULK", "Cl", "mg") - wall3 = rxn_model2.add_species(wntr.reaction.model.RxnVariableType.WALL, "ClOH", "mg", 0.01, 0.0001, note="Testing stuff") + wall3 = rxn_model2.add_species(wntr.reaction.VariableType.WALL, "ClOH", "mg", 0.01, 0.0001, note="Testing stuff") const3 = rxn_model2.add_coefficient("Consolation", "Kb", 0.482) - param3 = rxn_model2.add_coefficient(wntr.reaction.model.RxnVariableType.P, "Ka", 0.482, note="foo") + param3 = rxn_model2.add_coefficient(wntr.reaction.VariableType.P, "Ka", 0.482, note="foo") self.assertEqual(bulk3, bulk1) self.assertEqual(wall3, wall1) diff --git a/wntr/utils/disjoint_mapping.py b/wntr/utils/disjoint_mapping.py new file mode 100644 index 000000000..fb767057d --- /dev/null +++ b/wntr/utils/disjoint_mapping.py @@ -0,0 +1,207 @@ +# coding: utf-8 +"""A set of utility classes that is similar to the 'registry' objects in the wntr.network +class, but more general, and therefore usable for other extensions, such as multispecies +reaction modeling. +""" + +from collections.abc import MutableMapping +from typing import Any, Dict, Hashable, ItemsView, Iterator, KeysView, Set, ValuesView + + +class WrongGroupError(KeyError): + """The key exists but is in a different disjoint group""" + + pass + + +class KeyExistsError(KeyError): + """The name already exists in the reaction model""" + + pass + + +class DisjointMapping(MutableMapping): + """A mapping with keys that are also divided into disjoint groups of keys. + + The main purpose of this utility class is to perform implicit name collision checking + while also allowing both the groups and the main dictionary to be used as dictionaries + -- i.e., using `__*item__` methods and `mydict[key]` methods. + """ + + __data: Dict[Hashable, Hashable] = None + __key_groupnames: Dict[Hashable, str] = None + __groups: Dict[str, "DisjointMappingGroup"] = None + __usage: Dict[Hashable, Set[Any]] = None + + def __init__(self, *args, **kwargs): + self.__data: Dict[Hashable, Any] = dict(*args, **kwargs) + self.__key_groupnames: Dict[Hashable, str] = dict() + self.__groups: Dict[str, "DisjointMappingGroup"] = dict() + self.__usage: Dict[Hashable, Set[Any]] = dict() + for k, v in self.__data.items(): + self.__key_groupnames[k] = None + self.__usage[k] = set() + + def add_disjoint_group(self, name): + if name in self.__groups.keys(): + raise KeyError("Disjoint group already exists within registry") + new = DisjointMappingGroup(name, self) + self.__groups.__setitem__(name, new) + return new + + def get_disjoint_group(self, name: str): + return self.__groups[name] + + def get_groupname(self, __key: Hashable): + return self.__key_groupnames[__key] + + def add_item_to_group(self, groupname, key, value): + current = self.__key_groupnames.get(key, None) + if current is not None and groupname != current: + raise WrongGroupError("The key '{}' is already used in a different group '{}'".format(key, groupname)) + if groupname is not None: + group = self.__groups[groupname] + group._data.__setitem__(key, value) + self.__key_groupnames[key] = groupname + return self.__data.__setitem__(key, value) + + def move_item_to_group(self, new_group_name, key): + value = self.__data[key] + current = self.get_groupname(key) + if new_group_name is not None: + new_group = self.__groups[new_group_name] + new_group._data[key] = value + if current is not None: + old_group = self.__groups[current] + old_group._data.__delitem__(key) + self.__key_groupnames[key] = new_group_name + + def remove_item_from_group(self, groupname, key): + current = self.__key_groupnames.get(key, None) + if groupname != current: + raise WrongGroupError("The key '{}' is in a different group '{}'".format(key, groupname)) + if groupname is not None: + self.__groups[groupname]._data.__delitem__(key) + + def __getitem__(self, __key: Any) -> Any: + return self.__data.__getitem__(__key) + + def __setitem__(self, __key: Any, __value: Any) -> None: + current = self.__key_groupnames.get(__key, None) + if current is not None: + self.__groups[current]._data[__key] = __value + return self.__data.__setitem__(__key, __value) + + def __delitem__(self, __key: Any) -> None: + current = self.__key_groupnames.get(__key, None) + if current is not None: + self.__groups[current]._data.__delitem__(__key) + return self.__data.__delitem__(__key) + + def __contains__(self, __key: object) -> bool: + return self.__data.__contains__(__key) + + def __iter__(self) -> Iterator: + return self.__data.__iter__() + + def __len__(self) -> int: + return self.__data.__len__() + + def keys(self) -> KeysView: + return self.__data.keys() + + def items(self) -> ItemsView: + return self.__data.items() + + def values(self) -> ValuesView: + return self.__data.values() + + def clear(self) -> None: + raise RuntimeError("You cannot clear this") + + def popitem(self) -> tuple: + raise RuntimeError("You cannot pop this") + + +class DisjointMappingGroup(MutableMapping): + """A dictionary that checks a namespace for existing entries. + + To create a new instance, pass a set to act as a namespace. If the namespace does not + exist, a new namespace will be instantiated. If it does exist, then a new, disjoint + dictionary will be created that checks the namespace keys before it will allow a new + item to be added to the dictionary. An item can only belong to one of the disjoint dictionaries + associated with the namespace. + + Examples + -------- + Assume there is a namespace `nodes` that has two distinct subsets of objects, `tanks` + and `reservoirs`. A name for a tank cannot also be used for a reservoir, and a node + cannot be both a `tank` and a `reservoir`. A DisjointNamespaceDict allows two separate + dictionaries to be kept, one for each subtype, but the keys within the two dictionaries + will be ensured to not overlap. + + Parameters + ---------- + __keyspace : set + the name of the namespace for consistency checking + args, kwargs : Any + regular arguments and keyword arguments passed to the underlying dictionary + + """ + + __name: str = None + __keyspace: "DisjointMapping" = None + _data: dict = None + + def __new__(cls, name: str, __keyspace: "DisjointMapping"): + if name is None: + raise TypeError("A name must be specified") + if __keyspace is None: + raise TypeError("A registry must be specified") + newobj = super().__new__(cls) + return newobj + + def __init__(self, name: str, __keyspace: "DisjointMapping"): + if name is None: + raise TypeError("A name must be specified") + if __keyspace is None: + raise TypeError("A registry must be specified") + self.__name: str = name + self.__keyspace: DisjointMapping = __keyspace + self._data = dict() + + def __getitem__(self, __key: Any) -> Any: + return self._data[__key] + + def __setitem__(self, __key: Any, __value: Any) -> None: + return self.__keyspace.add_item_to_group(self.__name, __key, __value) + + def __delitem__(self, __key: Any) -> None: + return self.__keyspace.remove_item_from_group(self.__name, __key) + + def __contains__(self, __key: object) -> bool: + return self._data.__contains__(__key) + + def __iter__(self) -> Iterator: + return self._data.__iter__() + + def __len__(self) -> int: + return self._data.__len__() + + def keys(self) -> KeysView: + return self._data.keys() + + def items(self) -> ItemsView: + return self._data.items() + + def values(self) -> ValuesView: + return self._data.values() + + def clear(self) -> None: + raise RuntimeError("Cannot clear a group") + + def popitem(self) -> tuple: + raise RuntimeError("Cannot pop from a group") + + def __repr__(self) -> str: + return "{}(name={}, data={})".format(self.__class__.__name__, repr(self.__name), self._data) diff --git a/wntr/utils/enumtools.py b/wntr/utils/enumtools.py new file mode 100644 index 000000000..8dc847265 --- /dev/null +++ b/wntr/utils/enumtools.py @@ -0,0 +1,119 @@ +# coding: utf-8 +"""Decorators for use with enum classes. +""" + +from enum import Enum +from typing import Union +import functools + +def add_get(cls=None, *, prefix=None, abbrev=False): + """Decorator that will add a ``get()`` classmethod to an enum class. + + The get method behaves as follows. + For an integer, the integer value will be used to select the proper member. + For an :class:`Enum` object, the object's ``name`` will be used, and it will + be processed as a string. For a string, the method will: + + * capitalize the string + * remove leading or trailing spaces + * convert interior spaces or dashes to underscores + * optionally, remove a specified prefix from a string (using ``prefix``) + * optionally, try removing all letters except the first (if ``abbrev``) + + It will then try to get the member with the name corresponding to the converted + string. If ``abbrev`` is True, then the string will be truncated after trying + to use the full string as passed in. + + + Parameters + ---------- + prefix : str, optional + A prefix to strip off any string values passed in, by default None + abbrev : bool, optional + Allow truncating to the first character for checks, by default False + + + Returns + ------- + class + the modified class + """ + if prefix is None: + prefix = '' + if abbrev is None: + abbrev = False + if cls is None: + return functools.partial(add_get, prefix=prefix, abbrev=abbrev) + + @functools.wraps(cls) + def wrap(cls, prefix, abbrev): + + def get(cls, value: Union[str, int, Enum], prefix='', abbrev=False): + """Get the proper enum based on the name or value of the argument. + + For an integer, the integer value will be used to select the proper member. + If the value is the same class as this class, it will be returned unchanged. + For an :class:`Enum` object, the object's ``name`` will be used, and it will + be processed as a string. For a string, the method will: + + * capitalize the string + * remove leading or trailing spaces + * convert interior spaces or dashes to underscores + * optionally, remove a specified prefix from a string (using ``prefix``) + * optionally, try removing all letters except the first (if ``abbrev``) + + It will then try to get the member with the name corresponding to the converted + string. If ``abbrev`` is True, then the string will be truncated after trying + to use the full string as passed in. + + Parameters + ---------- + value : Union[str, int, Enum] + the value to be checked, if it is an Enum, then the name will be used + + Returns + ------- + Enum + the enum member that corresponds to the name or value passed in + + Raises + ------ + TypeError + if ``value`` is an invalid type + ValueError + if ``value`` is invalid + """ + name = str(value) + if isinstance(value, cls): + return value + elif isinstance(value, int): + return cls(value) + elif isinstance(value, str): + name = value.upper().strip().replace('-', '_').replace(' ', '_') + if name.startswith(prefix): + name = name[len(prefix):] + elif isinstance(value, Enum): + name = str(value.name).upper().strip().replace('-', '_').replace(' ', '_') + if name.startswith(prefix): + name = name[len(prefix):] + else: + raise TypeError('Invalid type for value: %s'%type(value)) + if abbrev: + try: + return cls[name] + except KeyError as e: + try: + return cls[name[0]] + except KeyError: + raise ValueError(repr(value)) from e + else: + try: + return cls[name] + except KeyError as e: + raise ValueError(repr(value)) from e + + setattr(cls, "get", classmethod(functools.partial(get, prefix=prefix, abbrev=abbrev))) + return cls + + return wrap(cls, prefix, abbrev) + From 51f2a7c07b60af3fa707149e0790183edb53198b Mon Sep 17 00:00:00 2001 From: dbhart Date: Wed, 20 Sep 2023 09:47:53 -0600 Subject: [PATCH 25/75] Rename --- documentation/apidoc/wntr.epanet.msx.rst | 7 +- documentation/apidoc/wntr.epanet.rst | 1 + documentation/apidoc/wntr.quality.base.rst | 7 + ....options.rst => wntr.quality.dynamics.rst} | 4 +- documentation/apidoc/wntr.quality.io.rst | 7 + documentation/apidoc/wntr.quality.library.rst | 7 + documentation/apidoc/wntr.quality.model.rst | 7 + documentation/apidoc/wntr.quality.options.rst | 7 + documentation/apidoc/wntr.quality.rst | 22 +++ .../apidoc/wntr.quality.variables.rst | 7 + documentation/apidoc/wntr.reaction.base.rst | 7 - .../apidoc/wntr.reaction.dynamics.rst | 7 - documentation/apidoc/wntr.reaction.io.rst | 7 - .../apidoc/wntr.reaction.library.rst | 7 - documentation/apidoc/wntr.reaction.model.rst | 7 - documentation/apidoc/wntr.reaction.rst | 22 --- .../apidoc/wntr.reaction.variables.rst | 7 - documentation/apidoc/wntr.rst | 2 +- documentation/apidoc/wntr.utils.enumtools.rst | 7 + documentation/apidoc/wntr.utils.rst | 1 + wntr/__init__.py | 2 +- wntr/epanet/msx/io.py | 82 ++++++++-- wntr/{reaction => quality}/__init__.py | 0 wntr/{reaction => quality}/base.py | 2 +- wntr/{reaction => quality}/dynamics.py | 2 +- wntr/{reaction => quality}/io.py | 0 wntr/{reaction => quality}/library.py | 2 +- wntr/{reaction => quality}/model.py | 6 +- wntr/{reaction => quality}/options.py | 0 wntr/{reaction => quality}/variables.py | 2 +- ...variables.py => test_quality_variables.py} | 152 +++++++++--------- wntr/utils/enumtools.py | 43 +++-- 32 files changed, 256 insertions(+), 187 deletions(-) create mode 100644 documentation/apidoc/wntr.quality.base.rst rename documentation/apidoc/{wntr.reaction.options.rst => wntr.quality.dynamics.rst} (55%) create mode 100644 documentation/apidoc/wntr.quality.io.rst create mode 100644 documentation/apidoc/wntr.quality.library.rst create mode 100644 documentation/apidoc/wntr.quality.model.rst create mode 100644 documentation/apidoc/wntr.quality.options.rst create mode 100644 documentation/apidoc/wntr.quality.rst create mode 100644 documentation/apidoc/wntr.quality.variables.rst delete mode 100644 documentation/apidoc/wntr.reaction.base.rst delete mode 100644 documentation/apidoc/wntr.reaction.dynamics.rst delete mode 100644 documentation/apidoc/wntr.reaction.io.rst delete mode 100644 documentation/apidoc/wntr.reaction.library.rst delete mode 100644 documentation/apidoc/wntr.reaction.model.rst delete mode 100644 documentation/apidoc/wntr.reaction.rst delete mode 100644 documentation/apidoc/wntr.reaction.variables.rst create mode 100644 documentation/apidoc/wntr.utils.enumtools.rst rename wntr/{reaction => quality}/__init__.py (100%) rename wntr/{reaction => quality}/base.py (99%) rename wntr/{reaction => quality}/dynamics.py (99%) rename wntr/{reaction => quality}/io.py (100%) rename wntr/{reaction => quality}/library.py (99%) rename wntr/{reaction => quality}/model.py (99%) rename wntr/{reaction => quality}/options.py (100%) rename wntr/{reaction => quality}/variables.py (99%) rename wntr/tests/{test_reaction_variables.py => test_quality_variables.py} (56%) diff --git a/documentation/apidoc/wntr.epanet.msx.rst b/documentation/apidoc/wntr.epanet.msx.rst index 0e115a092..83be9381a 100644 --- a/documentation/apidoc/wntr.epanet.msx.rst +++ b/documentation/apidoc/wntr.epanet.msx.rst @@ -1,16 +1,17 @@ -wntr.epanet.msx module +wntr.epanet.msx module ====================== .. automodule:: wntr.epanet.msx :members: :no-undoc-members: :show-inheritance: - - + + Submodules ---------- .. toctree:: + :maxdepth: 1 wntr.epanet.msx.enums wntr.epanet.msx.exceptions diff --git a/documentation/apidoc/wntr.epanet.rst b/documentation/apidoc/wntr.epanet.rst index 501523332..a4fc3f35d 100644 --- a/documentation/apidoc/wntr.epanet.rst +++ b/documentation/apidoc/wntr.epanet.rst @@ -11,6 +11,7 @@ Submodules ---------- .. toctree:: + :maxdepth: 1 wntr.epanet.exceptions wntr.epanet.io diff --git a/documentation/apidoc/wntr.quality.base.rst b/documentation/apidoc/wntr.quality.base.rst new file mode 100644 index 000000000..d3cc5ff4b --- /dev/null +++ b/documentation/apidoc/wntr.quality.base.rst @@ -0,0 +1,7 @@ +wntr.quality.base module +======================== + +.. automodule:: wntr.quality.base + :members: + :undoc-members: + :show-inheritance: diff --git a/documentation/apidoc/wntr.reaction.options.rst b/documentation/apidoc/wntr.quality.dynamics.rst similarity index 55% rename from documentation/apidoc/wntr.reaction.options.rst rename to documentation/apidoc/wntr.quality.dynamics.rst index 8d461d5b6..ef3204fe1 100644 --- a/documentation/apidoc/wntr.reaction.options.rst +++ b/documentation/apidoc/wntr.quality.dynamics.rst @@ -1,7 +1,7 @@ -wntr.reaction.options module +wntr.quality.dynamics module ============================ -.. automodule:: wntr.reaction.options +.. automodule:: wntr.reaction.quality :members: :undoc-members: :show-inheritance: diff --git a/documentation/apidoc/wntr.quality.io.rst b/documentation/apidoc/wntr.quality.io.rst new file mode 100644 index 000000000..117eedad9 --- /dev/null +++ b/documentation/apidoc/wntr.quality.io.rst @@ -0,0 +1,7 @@ +wntr.quality.io module +====================== + +.. automodule:: wntr.quality.io + :members: + :undoc-members: + :show-inheritance: diff --git a/documentation/apidoc/wntr.quality.library.rst b/documentation/apidoc/wntr.quality.library.rst new file mode 100644 index 000000000..b7ea696fa --- /dev/null +++ b/documentation/apidoc/wntr.quality.library.rst @@ -0,0 +1,7 @@ +wntr.quality.library module +=========================== + +.. automodule:: wntr.quality.library + :members: + :undoc-members: + :show-inheritance: diff --git a/documentation/apidoc/wntr.quality.model.rst b/documentation/apidoc/wntr.quality.model.rst new file mode 100644 index 000000000..907115f17 --- /dev/null +++ b/documentation/apidoc/wntr.quality.model.rst @@ -0,0 +1,7 @@ +wntr.quality.model module +========================= + +.. automodule:: wntr.quality.model + :members: + :undoc-members: + :show-inheritance: diff --git a/documentation/apidoc/wntr.quality.options.rst b/documentation/apidoc/wntr.quality.options.rst new file mode 100644 index 000000000..e492fec10 --- /dev/null +++ b/documentation/apidoc/wntr.quality.options.rst @@ -0,0 +1,7 @@ +wntr.quality.options module +=========================== + +.. automodule:: wntr.quality.options + :members: + :undoc-members: + :show-inheritance: diff --git a/documentation/apidoc/wntr.quality.rst b/documentation/apidoc/wntr.quality.rst new file mode 100644 index 000000000..0078e1b6e --- /dev/null +++ b/documentation/apidoc/wntr.quality.rst @@ -0,0 +1,22 @@ +wntr.quality package +==================== + +.. automodule:: wntr.quality + :members: + :undoc-members: + :show-inheritance: + + +Submodules +---------- + +.. toctree:: + :maxdepth: 1 + + wntr.quality.base + wntr.quality.dynamics + wntr.quality.io + wntr.quality.library + wntr.quality.model + wntr.quality.options + wntr.quality.variables diff --git a/documentation/apidoc/wntr.quality.variables.rst b/documentation/apidoc/wntr.quality.variables.rst new file mode 100644 index 000000000..a7efc4617 --- /dev/null +++ b/documentation/apidoc/wntr.quality.variables.rst @@ -0,0 +1,7 @@ +wntr.quality.variables module +============================= + +.. automodule:: wntr.quality.variables + :members: + :undoc-members: + :show-inheritance: diff --git a/documentation/apidoc/wntr.reaction.base.rst b/documentation/apidoc/wntr.reaction.base.rst deleted file mode 100644 index 6263973e7..000000000 --- a/documentation/apidoc/wntr.reaction.base.rst +++ /dev/null @@ -1,7 +0,0 @@ -wntr.reaction.base module -========================== - -.. automodule:: wntr.reaction.base - :members: - :undoc-members: - :show-inheritance: diff --git a/documentation/apidoc/wntr.reaction.dynamics.rst b/documentation/apidoc/wntr.reaction.dynamics.rst deleted file mode 100644 index a1f8ae82a..000000000 --- a/documentation/apidoc/wntr.reaction.dynamics.rst +++ /dev/null @@ -1,7 +0,0 @@ -wntr.reaction.dynamics module -============================== - -.. automodule:: wntr.reaction.dynamics - :members: - :undoc-members: - :show-inheritance: diff --git a/documentation/apidoc/wntr.reaction.io.rst b/documentation/apidoc/wntr.reaction.io.rst deleted file mode 100644 index de42d9c04..000000000 --- a/documentation/apidoc/wntr.reaction.io.rst +++ /dev/null @@ -1,7 +0,0 @@ -wntr.reaction.io module -======================= - -.. automodule:: wntr.reaction.io - :members: - :undoc-members: - :show-inheritance: diff --git a/documentation/apidoc/wntr.reaction.library.rst b/documentation/apidoc/wntr.reaction.library.rst deleted file mode 100644 index 730e22bce..000000000 --- a/documentation/apidoc/wntr.reaction.library.rst +++ /dev/null @@ -1,7 +0,0 @@ -wntr.reaction.library module -============================ - -.. automodule:: wntr.reaction.library - :members: - :undoc-members: - :show-inheritance: diff --git a/documentation/apidoc/wntr.reaction.model.rst b/documentation/apidoc/wntr.reaction.model.rst deleted file mode 100644 index 774082841..000000000 --- a/documentation/apidoc/wntr.reaction.model.rst +++ /dev/null @@ -1,7 +0,0 @@ -wntr.reaction.model module -========================== - -.. automodule:: wntr.reaction.model - :members: - :undoc-members: - :show-inheritance: diff --git a/documentation/apidoc/wntr.reaction.rst b/documentation/apidoc/wntr.reaction.rst deleted file mode 100644 index 96221653a..000000000 --- a/documentation/apidoc/wntr.reaction.rst +++ /dev/null @@ -1,22 +0,0 @@ -wntr.reaction package -===================== - -.. automodule:: wntr.reaction - :members: - :undoc-members: - :show-inheritance: - - -Submodules ----------- - -.. toctree:: - :maxdepth: 4 - - wntr.reaction.base - wntr.reaction.dynamics - wntr.reaction.io - wntr.reaction.library - wntr.reaction.model - wntr.reaction.options - wntr.reaction.variables diff --git a/documentation/apidoc/wntr.reaction.variables.rst b/documentation/apidoc/wntr.reaction.variables.rst deleted file mode 100644 index 9a7d32b2e..000000000 --- a/documentation/apidoc/wntr.reaction.variables.rst +++ /dev/null @@ -1,7 +0,0 @@ -wntr.reaction.variables module -============================== - -.. automodule:: wntr.reaction.variables - :members: - :undoc-members: - :show-inheritance: diff --git a/documentation/apidoc/wntr.rst b/documentation/apidoc/wntr.rst index 6b203c464..4b5369d1b 100644 --- a/documentation/apidoc/wntr.rst +++ b/documentation/apidoc/wntr.rst @@ -20,7 +20,7 @@ Subpackages wntr.metrics wntr.morph wntr.network - wntr.reaction + wntr.quality wntr.scenario wntr.sim wntr.utils diff --git a/documentation/apidoc/wntr.utils.enumtools.rst b/documentation/apidoc/wntr.utils.enumtools.rst new file mode 100644 index 000000000..c856c713c --- /dev/null +++ b/documentation/apidoc/wntr.utils.enumtools.rst @@ -0,0 +1,7 @@ +wntr.utils.enumtools module +=========================== + +.. automodule:: wntr.utils.enumtools + :members: + :no-undoc-members: + :show-inheritance: diff --git a/documentation/apidoc/wntr.utils.rst b/documentation/apidoc/wntr.utils.rst index a2b0893fe..14eef2793 100644 --- a/documentation/apidoc/wntr.utils.rst +++ b/documentation/apidoc/wntr.utils.rst @@ -14,5 +14,6 @@ Submodules wntr.utils.citations wntr.utils.disjoint_mapping + wntr.utils.enumtools wntr.utils.logger wntr.utils.ordered_set diff --git a/wntr/__init__.py b/wntr/__init__.py index 80e030a5a..ae9d24d5a 100644 --- a/wntr/__init__.py +++ b/wntr/__init__.py @@ -7,7 +7,7 @@ from wntr import graphics from wntr import gis from wntr import utils -from wntr import reaction +from wntr import quality __version__ = '1.0.0' diff --git a/wntr/epanet/msx/io.py b/wntr/epanet/msx/io.py index 5273f91a0..9ef37a66a 100644 --- a/wntr/epanet/msx/io.py +++ b/wntr/epanet/msx/io.py @@ -6,11 +6,11 @@ import sys from wntr.network.elements import Source -from wntr.reaction.base import LocationType, VariableType -from wntr.reaction.base import MSXComment -from wntr.reaction.model import MultispeciesReactionModel +from wntr.quality.base import LocationType, VariableType +from wntr.quality.base import MSXComment +from wntr.quality.model import MultispeciesReactionModel from wntr.epanet.msx.exceptions import EpanetMsxException -from wntr.reaction.variables import Parameter, Species +from wntr.quality.variables import Parameter, Species from wntr.utils.citations import Citation sys_default_enc = sys.getdefaultencoding() @@ -748,10 +748,74 @@ def _write_report(self, fout): fout.write(" PAGESIZE {}\n".format(self.rxn._options.report.pagesize)) fout.write("\n") +import wntr.network +import numpy as np +import pandas as pd + +def MsxBinFile(filename, wn: wntr.network.WaterNetworkModel): + duration = int(wn.options.time.duration) + + with open(filename, 'rb') as fin: + ftype = '=f4' + idlen = 32 + prolog = np.fromfile(fin, dtype = np.int32, count=6) + magic1 = prolog[0] + version = prolog[1] + nnodes = prolog[2] + nlinks = prolog[3] + nspecies = prolog[4] + reportstep = prolog[5] + species_list = [] + node_list = wn.node_name_list + link_list = wn.link_name_list + + for i in range(nspecies): + species_len = int(np.fromfile(fin, dtype = np.int32, count=1)) + species_name = ''.join(chr(f) for f in np.fromfile(fin, dtype = np.uint8, count=species_len) if f!=0) + species_list.append(species_name) + species_mass = [] + for i in range(nspecies): + species_mass.append(''.join(chr(f) for f in np.fromfile(fin, dtype = np.uint8, count=16) if f != 0)) + timerange = range(0, duration+1, reportstep) + + tr = len(timerange) + + row1 = ['node']*nnodes*len(species_list)+['link']*nlinks*len(species_list) + row2 = [] + for i in [nnodes,nlinks]: + for j in species_list: + row2.append([j]*i) + row2 = [y for x in row2 for y in x] + row3 = [node_list for i in species_list] + [link_list for i in species_list] + row3 = [y for x in row3 for y in x] + + tuples = list(zip(row1, row2, row3)) + index = pd.MultiIndex.from_tuples(tuples, names = ['type','species','name']) + + try: + data = np.fromfile(fin, dtype = np.dtype(ftype), count = tr*(len(species_list*(nnodes + nlinks)))) + data = np.reshape(data, (tr, len(species_list*(nnodes + nlinks)))) + except Exception as e: + print(e) + print ("oops") + + postlog = np.fromfile(fin, dtype = np.int32, count=4) + offset = postlog[0] + numreport = postlog[1] + errorcode = postlog[2] + magicnew = postlog[3] + if errorcode !=0: + print(f'ERROR CODE: {errorcode}') + print(offset, numreport) + + df_fin = pd.DataFrame(index=index, columns=timerange).transpose() + if magic1 == magicnew: + # print("Magic# Match") + df_fin = pd.DataFrame(data.transpose(), index=index, columns=timerange) + df_fin = df_fin.transpose() + + else: + print("Magic#s do not match!") + return df_fin -class MsxBinFile(object): - def __init__(self): - pass - def read(self, filename): - pass diff --git a/wntr/reaction/__init__.py b/wntr/quality/__init__.py similarity index 100% rename from wntr/reaction/__init__.py rename to wntr/quality/__init__.py diff --git a/wntr/reaction/base.py b/wntr/quality/base.py similarity index 99% rename from wntr/reaction/base.py rename to wntr/quality/base.py index e795d8256..9d63da4fd 100644 --- a/wntr/reaction/base.py +++ b/wntr/quality/base.py @@ -52,7 +52,7 @@ from wntr.network.model import WaterNetworkModel from wntr.utils.enumtools import add_get -from wntr.reaction.options import MultispeciesOptions +from wntr.quality.options import MultispeciesOptions logger = logging.getLogger(__name__) diff --git a/wntr/reaction/dynamics.py b/wntr/quality/dynamics.py similarity index 99% rename from wntr/reaction/dynamics.py rename to wntr/quality/dynamics.py index 3f64d50fc..1de155200 100644 --- a/wntr/reaction/dynamics.py +++ b/wntr/quality/dynamics.py @@ -61,7 +61,7 @@ has_sympy = False from wntr.network.model import WaterNetworkModel -from wntr.reaction.base import EXPR_TRANSFORMS, MsxObjectMixin, VariableType +from wntr.quality.base import EXPR_TRANSFORMS, MsxObjectMixin, VariableType from .base import ( ExpressionMixin, diff --git a/wntr/reaction/io.py b/wntr/quality/io.py similarity index 100% rename from wntr/reaction/io.py rename to wntr/quality/io.py diff --git a/wntr/reaction/library.py b/wntr/quality/library.py similarity index 99% rename from wntr/reaction/library.py rename to wntr/quality/library.py index 553be9993..57abef32c 100644 --- a/wntr/reaction/library.py +++ b/wntr/quality/library.py @@ -20,7 +20,7 @@ import logging from wntr.utils.citations import Citation -from wntr.reaction.model import MultispeciesReactionModel +from wntr.quality.model import MultispeciesReactionModel logger = logging.getLogger(__name__) diff --git a/wntr/reaction/model.py b/wntr/quality/model.py similarity index 99% rename from wntr/reaction/model.py rename to wntr/quality/model.py index f1984b225..2a361a479 100644 --- a/wntr/reaction/model.py +++ b/wntr/quality/model.py @@ -46,7 +46,7 @@ convert_xor = None has_sympy = False -import wntr.reaction.io +import wntr.quality.io from wntr.network.model import WaterNetworkModel from wntr.utils.citations import Citation @@ -776,11 +776,11 @@ def add_pattern(self, name, pat): def to_dict(self) -> dict: """Convert this water quality model to a dictionary""" - wntr.reaction.io.to_dict() + wntr.quality.io.to_dict() def from_dict(self, d) -> dict: """Append to this water quality model from a dictionary""" - wntr.reaction.io.from_dict(d, append=self) + wntr.quality.io.from_dict(d, append=self) def __repr__(self): if self._msxfile or self.name: diff --git a/wntr/reaction/options.py b/wntr/quality/options.py similarity index 100% rename from wntr/reaction/options.py rename to wntr/quality/options.py diff --git a/wntr/reaction/variables.py b/wntr/quality/variables.py similarity index 99% rename from wntr/reaction/variables.py rename to wntr/quality/variables.py index aabbbe725..c70017dc8 100644 --- a/wntr/reaction/variables.py +++ b/wntr/quality/variables.py @@ -56,7 +56,7 @@ has_sympy = False from wntr.network.model import WaterNetworkModel -from wntr.reaction.base import EXPR_TRANSFORMS +from wntr.quality.base import EXPR_TRANSFORMS from .base import ( RESERVED_NAMES, diff --git a/wntr/tests/test_reaction_variables.py b/wntr/tests/test_quality_variables.py similarity index 56% rename from wntr/tests/test_reaction_variables.py rename to wntr/tests/test_quality_variables.py index 480cb9a1d..a0bf23043 100644 --- a/wntr/tests/test_reaction_variables.py +++ b/wntr/tests/test_quality_variables.py @@ -5,7 +5,7 @@ import numpy as np import pandas as pd import wntr -import wntr.reaction +import wntr.quality import sympy testdir = dirname(abspath(str(__file__))) @@ -24,35 +24,35 @@ def tearDownClass(self): pass def test_ReactionVariable_reserved_name_exception(self): - self.assertRaises(ValueError, wntr.reaction.BulkSpecies, "D", "mg") - self.assertRaises(ValueError, wntr.reaction.WallSpecies, "Q", "mg") - self.assertRaises(ValueError, wntr.reaction.Constant, "Re", 0.52) - self.assertRaises(ValueError, wntr.reaction.Parameter, "Re", 0.52) - self.assertRaises(ValueError, wntr.reaction.OtherTerm, "Re", 0.52) + self.assertRaises(ValueError, wntr.quality.BulkSpecies, "D", "mg") + self.assertRaises(ValueError, wntr.quality.WallSpecies, "Q", "mg") + self.assertRaises(ValueError, wntr.quality.Constant, "Re", 0.52) + self.assertRaises(ValueError, wntr.quality.Parameter, "Re", 0.52) + self.assertRaises(ValueError, wntr.quality.OtherTerm, "Re", 0.52) def test_RxnVariable_symbols_and_sympy(self): - species1 = wntr.reaction.BulkSpecies("Cl", "mg") + species1 = wntr.quality.BulkSpecies("Cl", "mg") symbol1 = sympy.symbols("Cl") self.assertEqual(species1.symbol, symbol1) - const1 = wntr.reaction.Constant("Kb", 0.482) + const1 = wntr.quality.Constant("Kb", 0.482) symbol2 = sympy.symbols("Kb") self.assertEqual(const1.symbol, symbol2) - param1 = wntr.reaction.Constant("Ka", 0.482) + param1 = wntr.quality.Constant("Ka", 0.482) symbol3 = sympy.symbols("Ka") self.assertEqual(param1.symbol, symbol3) - term1 = wntr.reaction.OtherTerm("T0", "-3.2 * Kb * Cl^2", note="bar") + term1 = wntr.quality.OtherTerm("T0", "-3.2 * Kb * Cl^2", note="bar") symbol4 = sympy.symbols("T0") self.assertEqual(term1.symbol, symbol4) def test_RxnVariable_values(self): - const1 = wntr.reaction.Constant("Kb", 0.482, note="test") + const1 = wntr.quality.Constant("Kb", 0.482, note="test") self.assertEqual(const1.get_value(), const1.global_value) test_pipe_dict = {"PIPE": 0.38} test_tank_dict = {"TANK": 222.23} - param2 = wntr.reaction.Parameter("Kb", 0.482, note="test", _pipe_values=test_pipe_dict, _tank_values=test_tank_dict) + param2 = wntr.quality.Parameter("Kb", 0.482, note="test", _pipe_values=test_pipe_dict, _tank_values=test_tank_dict) self.assertEqual(param2.get_value(), param2.global_value) self.assertEqual(param2.get_value(pipe="PIPE"), test_pipe_dict["PIPE"]) self.assertEqual(param2.get_value(pipe="FOO"), param2.global_value) @@ -60,11 +60,11 @@ def test_RxnVariable_values(self): self.assertRaises(TypeError, param2.get_value, pipe="PIPE", tank="TANK") def test_RxnVariable_string_functions(self): - species1 = wntr.reaction.BulkSpecies("Cl", "mg") - species2 = wntr.reaction.WallSpecies("Cl", "mg", 0.01, 0.0001, note="Testing stuff") - const1 = wntr.reaction.Constant("Kb", 0.482) - param1 = wntr.reaction.Parameter("Ka", 0.482, note="foo") - term1 = wntr.reaction.OtherTerm("T0", "-3.2 * Kb * Cl^2", note="bar") + species1 = wntr.quality.BulkSpecies("Cl", "mg") + species2 = wntr.quality.WallSpecies("Cl", "mg", 0.01, 0.0001, note="Testing stuff") + const1 = wntr.quality.Constant("Kb", 0.482) + param1 = wntr.quality.Parameter("Ka", 0.482, note="foo") + term1 = wntr.quality.OtherTerm("T0", "-3.2 * Kb * Cl^2", note="bar") self.assertEqual(str(species1), "Cl") self.assertEqual(species1.to_msx_string(), "BULK Cl mg ;") @@ -78,8 +78,8 @@ def test_RxnVariable_string_functions(self): def test_Species_tolerances(self): # """RxnSpecies(*s) tolerance settings""" - species1 = wntr.reaction.BulkSpecies("Cl", "mg") - species2 = wntr.reaction.WallSpecies("Cl", "mg", 0.01, 0.0001, note="Testing stuff") + species1 = wntr.quality.BulkSpecies("Cl", "mg") + species2 = wntr.quality.WallSpecies("Cl", "mg", 0.01, 0.0001, note="Testing stuff") self.assertIsNone(species1.get_tolerances()) self.assertIsNotNone(species2.get_tolerances()) self.assertTupleEqual(species2.get_tolerances(), (0.01, 0.0001)) @@ -99,19 +99,19 @@ def test_Species_tolerances(self): def test_BulkSpecies_creation(self): # """BlukSpecies object creation (direct instantiation)""" - self.assertRaises(TypeError, wntr.reaction.BulkSpecies, "Re") - self.assertRaises(ValueError, wntr.reaction.BulkSpecies, "Re", "mg") - self.assertRaises(TypeError, wntr.reaction.BulkSpecies, "Cl", "mg", 0.01) - self.assertRaises(TypeError, wntr.reaction.BulkSpecies, "Cl", "mg", None, 0.01) - species = wntr.reaction.BulkSpecies("Cl", "mg") + self.assertRaises(TypeError, wntr.quality.BulkSpecies, "Re") + self.assertRaises(ValueError, wntr.quality.BulkSpecies, "Re", "mg") + self.assertRaises(TypeError, wntr.quality.BulkSpecies, "Cl", "mg", 0.01) + self.assertRaises(TypeError, wntr.quality.BulkSpecies, "Cl", "mg", None, 0.01) + species = wntr.quality.BulkSpecies("Cl", "mg") self.assertEqual(species.name, "Cl") self.assertEqual(species.units, "mg") - self.assertEqual(species.var_type, wntr.reaction.VariableType.BULK) + self.assertEqual(species.var_type, wntr.quality.VariableType.BULK) self.assertIsNone(species.atol) self.assertIsNone(species.rtol) self.assertIsNone(species.note) - species = wntr.reaction.BulkSpecies("Cl", "mg", 0.01, 0.0001, note="Testing stuff") - self.assertEqual(species.var_type, wntr.reaction.VariableType.BULK) + species = wntr.quality.BulkSpecies("Cl", "mg", 0.01, 0.0001, note="Testing stuff") + self.assertEqual(species.var_type, wntr.quality.VariableType.BULK) self.assertEqual(species.name, "Cl") self.assertEqual(species.units, "mg") self.assertEqual(species.atol, 0.01) @@ -120,19 +120,19 @@ def test_BulkSpecies_creation(self): def test_WallSpecies_creation(self): # """WallSpecies object creation (direct instantiation)""" - self.assertRaises(TypeError, wntr.reaction.WallSpecies, "Re") - self.assertRaises(ValueError, wntr.reaction.WallSpecies, "Re", "mg") - self.assertRaises(TypeError, wntr.reaction.WallSpecies, "Cl", "mg", 0.01) - self.assertRaises(TypeError, wntr.reaction.WallSpecies, "Cl", "mg", None, 0.01) - species = wntr.reaction.WallSpecies("Cl", "mg") + self.assertRaises(TypeError, wntr.quality.WallSpecies, "Re") + self.assertRaises(ValueError, wntr.quality.WallSpecies, "Re", "mg") + self.assertRaises(TypeError, wntr.quality.WallSpecies, "Cl", "mg", 0.01) + self.assertRaises(TypeError, wntr.quality.WallSpecies, "Cl", "mg", None, 0.01) + species = wntr.quality.WallSpecies("Cl", "mg") self.assertEqual(species.name, "Cl") self.assertEqual(species.units, "mg") - self.assertEqual(species.var_type, wntr.reaction.VariableType.WALL) + self.assertEqual(species.var_type, wntr.quality.VariableType.WALL) self.assertIsNone(species.atol) self.assertIsNone(species.rtol) self.assertIsNone(species.note) - species = wntr.reaction.WallSpecies("Cl", "mg", 0.01, 0.0001, note="Testing stuff") - self.assertEqual(species.var_type, wntr.reaction.VariableType.WALL) + species = wntr.quality.WallSpecies("Cl", "mg", 0.01, 0.0001, note="Testing stuff") + self.assertEqual(species.var_type, wntr.quality.VariableType.WALL) self.assertEqual(species.name, "Cl") self.assertEqual(species.units, "mg") self.assertEqual(species.atol, 0.01) @@ -140,78 +140,78 @@ def test_WallSpecies_creation(self): self.assertEqual(species.note, "Testing stuff") def test_Constant_creation(self): - self.assertRaises(TypeError, wntr.reaction.Constant, "Re") - self.assertRaises(ValueError, wntr.reaction.Constant, "Re", 2.48) - const1 = wntr.reaction.Constant("Kb", 0.482, note="test") + self.assertRaises(TypeError, wntr.quality.Constant, "Re") + self.assertRaises(ValueError, wntr.quality.Constant, "Re", 2.48) + const1 = wntr.quality.Constant("Kb", 0.482, note="test") # FIXME: Find a way to suppress warning printing # self.assertWarns(RuntimeWarning, wntr.reaction.Constant, 'Kb1', 0.83, pipe_values={'a',1}) self.assertEqual(const1.name, "Kb") self.assertEqual(const1.global_value, 0.482) self.assertEqual(const1.get_value(), const1.global_value) - self.assertEqual(const1.var_type, wntr.reaction.VariableType.CONST) + self.assertEqual(const1.var_type, wntr.quality.VariableType.CONST) self.assertEqual(const1.note, "test") def test_Parameter_creation(self): - self.assertRaises(TypeError, wntr.reaction.Parameter, "Re") - self.assertRaises(ValueError, wntr.reaction.Parameter, "Re", 2.48) - param1 = wntr.reaction.Parameter("Kb", 0.482, note="test") + self.assertRaises(TypeError, wntr.quality.Parameter, "Re") + self.assertRaises(ValueError, wntr.quality.Parameter, "Re", 2.48) + param1 = wntr.quality.Parameter("Kb", 0.482, note="test") self.assertEqual(param1.name, "Kb") self.assertEqual(param1.global_value, 0.482) self.assertEqual(param1.get_value(), param1.global_value) - self.assertEqual(param1.var_type, wntr.reaction.VariableType.PARAM) + self.assertEqual(param1.var_type, wntr.quality.VariableType.PARAM) self.assertEqual(param1.note, "test") test_pipe_dict = {"PIPE": 0.38} test_tank_dict = {"TANK": 222.23} - param2 = wntr.reaction.Parameter("Kb", 0.482, note="test", _pipe_values=test_pipe_dict, _tank_values=test_tank_dict) + param2 = wntr.quality.Parameter("Kb", 0.482, note="test", _pipe_values=test_pipe_dict, _tank_values=test_tank_dict) self.assertDictEqual(param2.pipe_values, test_pipe_dict) self.assertDictEqual(param2.tank_values, test_tank_dict) def test_RxnTerm_creation(self): - self.assertRaises(TypeError, wntr.reaction.OtherTerm, "Re") - self.assertRaises(ValueError, wntr.reaction.OtherTerm, "Re", "1.0*Re") - term1 = wntr.reaction.OtherTerm("T0", "-3.2 * Kb * Cl^2", note="bar") + self.assertRaises(TypeError, wntr.quality.OtherTerm, "Re") + self.assertRaises(ValueError, wntr.quality.OtherTerm, "Re", "1.0*Re") + term1 = wntr.quality.OtherTerm("T0", "-3.2 * Kb * Cl^2", note="bar") self.assertEqual(term1.name, "T0") self.assertEqual(term1.expression, "-3.2 * Kb * Cl^2") - self.assertEqual(term1.var_type, wntr.reaction.VariableType.TERM) + self.assertEqual(term1.var_type, wntr.quality.VariableType.TERM) self.assertEqual(term1.note, "bar") def test_RxnExpression_strings(self): - equil1 = wntr.reaction.EquilibriumDynamics("Cl", wntr.reaction.LocationType.PIPE, "-Ka + Kb * Cl + T0") - rate1 = wntr.reaction.RateDynamics("Cl", wntr.reaction.LocationType.TANK, "-Ka + Kb * Cl + T0", note="Foo Bar") - formula1 = wntr.reaction.FormulaDynamics("Cl", wntr.reaction.LocationType.PIPE, "-Ka + Kb * Cl + T0") + equil1 = wntr.quality.EquilibriumDynamics("Cl", wntr.quality.LocationType.PIPE, "-Ka + Kb * Cl + T0") + rate1 = wntr.quality.RateDynamics("Cl", wntr.quality.LocationType.TANK, "-Ka + Kb * Cl + T0", note="Foo Bar") + formula1 = wntr.quality.FormulaDynamics("Cl", wntr.quality.LocationType.PIPE, "-Ka + Kb * Cl + T0") self.assertEqual(equil1.to_msx_string(), "EQUIL Cl -Ka + Kb * Cl + T0 ;") self.assertEqual(rate1.to_msx_string(), "RATE Cl -Ka + Kb * Cl + T0 ;Foo Bar") self.assertEqual(formula1.to_msx_string(), "FORMULA Cl -Ka + Kb * Cl + T0 ;") def test_Equilibrium_creation(self): - equil1 = wntr.reaction.EquilibriumDynamics("Cl", wntr.reaction.LocationType.PIPE, "-Ka + Kb * Cl + T0") + equil1 = wntr.quality.EquilibriumDynamics("Cl", wntr.quality.LocationType.PIPE, "-Ka + Kb * Cl + T0") self.assertEqual(equil1.species, "Cl") self.assertEqual(equil1.expression, "-Ka + Kb * Cl + T0") - self.assertEqual(equil1.expr_type, wntr.reaction.DynamicsType.EQUIL) + self.assertEqual(equil1.expr_type, wntr.quality.DynamicsType.EQUIL) def test_Rate_creation(self): - rate1 = wntr.reaction.RateDynamics("Cl", wntr.reaction.LocationType.TANK, "-Ka + Kb * Cl + T0", note="Foo Bar") + rate1 = wntr.quality.RateDynamics("Cl", wntr.quality.LocationType.TANK, "-Ka + Kb * Cl + T0", note="Foo Bar") self.assertEqual(rate1.species, "Cl") self.assertEqual(rate1.expression, "-Ka + Kb * Cl + T0") - self.assertEqual(rate1.expr_type, wntr.reaction.DynamicsType.RATE) + self.assertEqual(rate1.expr_type, wntr.quality.DynamicsType.RATE) self.assertEqual(rate1.note, "Foo Bar") def test_Formula_creation(self): - formula1 = wntr.reaction.FormulaDynamics("Cl", wntr.reaction.LocationType.PIPE, "-Ka + Kb * Cl + T0") + formula1 = wntr.quality.FormulaDynamics("Cl", wntr.quality.LocationType.PIPE, "-Ka + Kb * Cl + T0") self.assertEqual(formula1.species, "Cl") self.assertEqual(formula1.expression, "-Ka + Kb * Cl + T0") - self.assertEqual(formula1.expr_type, wntr.reaction.DynamicsType.FORMULA) + self.assertEqual(formula1.expr_type, wntr.quality.DynamicsType.FORMULA) def test_WaterQualityReactionsModel_creation_specific_everything(self): - rxn_model1 = wntr.reaction.MultispeciesReactionModel() - bulk1 = wntr.reaction.BulkSpecies("Cl", "mg") - wall1 = wntr.reaction.WallSpecies("ClOH", "mg", 0.01, 0.0001, note="Testing stuff") - const1 = wntr.reaction.Constant("Kb", 0.482) - param1 = wntr.reaction.Parameter("Ka", 0.482, note="foo") - term1 = wntr.reaction.OtherTerm("T0", "-3.2 * Kb * Cl^2", note="bar") - equil1 = wntr.reaction.EquilibriumDynamics(bulk1, wntr.reaction.LocationType.PIPE, "-Ka + Kb * Cl + T0") - rate1 = wntr.reaction.RateDynamics(bulk1, wntr.reaction.LocationType.TANK, "-Ka + Kb * Cl + T0", note="Foo Bar") - formula1 = wntr.reaction.FormulaDynamics(wall1, wntr.reaction.LocationType.PIPE, "-Ka + Kb * Cl + T0") + rxn_model1 = wntr.quality.MultispeciesReactionModel() + bulk1 = wntr.quality.BulkSpecies("Cl", "mg") + wall1 = wntr.quality.WallSpecies("ClOH", "mg", 0.01, 0.0001, note="Testing stuff") + const1 = wntr.quality.Constant("Kb", 0.482) + param1 = wntr.quality.Parameter("Ka", 0.482, note="foo") + term1 = wntr.quality.OtherTerm("T0", "-3.2 * Kb * Cl^2", note="bar") + equil1 = wntr.quality.EquilibriumDynamics(bulk1, wntr.quality.LocationType.PIPE, "-Ka + Kb * Cl + T0") + rate1 = wntr.quality.RateDynamics(bulk1, wntr.quality.LocationType.TANK, "-Ka + Kb * Cl + T0", note="Foo Bar") + formula1 = wntr.quality.FormulaDynamics(wall1, wntr.quality.LocationType.PIPE, "-Ka + Kb * Cl + T0") bulk2 = rxn_model1.add_bulk_species("Cl", "mg") wall2 = rxn_model1.add_wall_species("ClOH", "mg", 0.01, 0.0001, note="Testing stuff") @@ -219,7 +219,7 @@ def test_WaterQualityReactionsModel_creation_specific_everything(self): param2 = rxn_model1.add_parameterized_coeff("Ka", 0.482, note="foo") term2 = rxn_model1.add_other_term("T0", "-3.2 * Kb * Cl^2", note="bar") equil2 = rxn_model1.add_pipe_reaction("Cl", "equil", "-Ka + Kb * Cl + T0") - rate2 = rxn_model1.add_tank_reaction("Cl", wntr.reaction.DynamicsType.R, "-Ka + Kb * Cl + T0", note="Foo Bar") + rate2 = rxn_model1.add_tank_reaction("Cl", wntr.quality.DynamicsType.R, "-Ka + Kb * Cl + T0", note="Foo Bar") formula2 = rxn_model1.add_reaction("PIPE", "ClOH", "formula", "-Ka + Kb * Cl + T0") self.assertEqual(bulk1, bulk2) self.assertEqual(wall1, wall2) @@ -231,22 +231,22 @@ def test_WaterQualityReactionsModel_creation_specific_everything(self): # self.assertEqual(formula1, formula2) def test_WaterQualityReactionsModel_creation_generic_species_coeffs(self): - bulk1 = wntr.reaction.BulkSpecies("Cl", "mg") - wall1 = wntr.reaction.WallSpecies("ClOH", "mg", 0.01, 0.0001, note="Testing stuff") - const1 = wntr.reaction.Constant("Kb", 0.482) - param1 = wntr.reaction.Parameter("Ka", 0.482, note="foo") - term1 = wntr.reaction.OtherTerm("T0", "-3.2 * Kb * Cl^2", note="bar") + bulk1 = wntr.quality.BulkSpecies("Cl", "mg") + wall1 = wntr.quality.WallSpecies("ClOH", "mg", 0.01, 0.0001, note="Testing stuff") + const1 = wntr.quality.Constant("Kb", 0.482) + param1 = wntr.quality.Parameter("Ka", 0.482, note="foo") + term1 = wntr.quality.OtherTerm("T0", "-3.2 * Kb * Cl^2", note="bar") - rxn_model2 = wntr.reaction.MultispeciesReactionModel() + rxn_model2 = wntr.quality.MultispeciesReactionModel() - self.assertRaises(ValueError, rxn_model2.add_species, wntr.reaction.VariableType.CONST, "Cl", "mg") + self.assertRaises(ValueError, rxn_model2.add_species, wntr.quality.VariableType.CONST, "Cl", "mg") self.assertRaises(TypeError, rxn_model2.add_coefficient, None, "Kb", 0.482) self.assertRaises(ValueError, rxn_model2.add_coefficient, "Wall", "Kb", 0.482) bulk3 = rxn_model2.add_species("BULK", "Cl", "mg") - wall3 = rxn_model2.add_species(wntr.reaction.VariableType.WALL, "ClOH", "mg", 0.01, 0.0001, note="Testing stuff") + wall3 = rxn_model2.add_species(wntr.quality.VariableType.WALL, "ClOH", "mg", 0.01, 0.0001, note="Testing stuff") const3 = rxn_model2.add_coefficient("Consolation", "Kb", 0.482) - param3 = rxn_model2.add_coefficient(wntr.reaction.VariableType.P, "Ka", 0.482, note="foo") + param3 = rxn_model2.add_coefficient(wntr.quality.VariableType.P, "Ka", 0.482, note="foo") self.assertEqual(bulk3, bulk1) self.assertEqual(wall3, wall1) diff --git a/wntr/utils/enumtools.py b/wntr/utils/enumtools.py index 8dc847265..e44235c33 100644 --- a/wntr/utils/enumtools.py +++ b/wntr/utils/enumtools.py @@ -9,22 +9,6 @@ def add_get(cls=None, *, prefix=None, abbrev=False): """Decorator that will add a ``get()`` classmethod to an enum class. - The get method behaves as follows. - For an integer, the integer value will be used to select the proper member. - For an :class:`Enum` object, the object's ``name`` will be used, and it will - be processed as a string. For a string, the method will: - - * capitalize the string - * remove leading or trailing spaces - * convert interior spaces or dashes to underscores - * optionally, remove a specified prefix from a string (using ``prefix``) - * optionally, try removing all letters except the first (if ``abbrev``) - - It will then try to get the member with the name corresponding to the converted - string. If ``abbrev`` is True, then the string will be truncated after trying - to use the full string as passed in. - - Parameters ---------- prefix : str, optional @@ -47,29 +31,40 @@ def add_get(cls=None, *, prefix=None, abbrev=False): @functools.wraps(cls) def wrap(cls, prefix, abbrev): + """Perform the decorator action""" def get(cls, value: Union[str, int, Enum], prefix='', abbrev=False): """Get the proper enum based on the name or value of the argument. + The get method behaves as follows. For an integer, the integer value will be used to select the proper member. - If the value is the same class as this class, it will be returned unchanged. For an :class:`Enum` object, the object's ``name`` will be used, and it will be processed as a string. For a string, the method will: - * capitalize the string - * remove leading or trailing spaces - * convert interior spaces or dashes to underscores - * optionally, remove a specified prefix from a string (using ``prefix``) - * optionally, try removing all letters except the first (if ``abbrev``) + 1. capitalize the string + 2. remove leading or trailing spaces + 3. convert interior spaces or dashes to underscores + 4. optionally, remove a specified prefix from a string (using ``prefix``, which + should have a default assigned by the :func:`wntr.utils.enumtools.add_get` + function.) It will then try to get the member with the name corresponding to the converted - string. If ``abbrev`` is True, then the string will be truncated after trying - to use the full string as passed in. + string. + + 5. optionally, if ``abbrev`` is True, then the string will be truncated to the first + letter, only, after trying to use the full string as passed in. The ``abbrev`` + parameter will have a default value based on how the :func:`~wntr.utils.enumtools.add_get` + decorator was called on this class. + Parameters ---------- value : Union[str, int, Enum] the value to be checked, if it is an Enum, then the name will be used + prefix : str, optional + a prefix to strip from the beginning of ``value``, default set by the decorator + abbrev : bool, optional + whether to try a single-letter version of ``value``, default set by the decorator Returns ------- From ffcc1a5989425718e46862287c9f9f9846746a14 Mon Sep 17 00:00:00 2001 From: dbhart Date: Wed, 20 Sep 2023 09:48:53 -0600 Subject: [PATCH 26/75] Typo --- documentation/apidoc/wntr.quality.dynamics.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/documentation/apidoc/wntr.quality.dynamics.rst b/documentation/apidoc/wntr.quality.dynamics.rst index ef3204fe1..da8cecbb1 100644 --- a/documentation/apidoc/wntr.quality.dynamics.rst +++ b/documentation/apidoc/wntr.quality.dynamics.rst @@ -1,7 +1,7 @@ wntr.quality.dynamics module ============================ -.. automodule:: wntr.reaction.quality +.. automodule:: wntr.quality.dynamics :members: :undoc-members: :show-inheritance: From eb6e7afa7e3bf4a1e8b7d8a8c8eed634719ce5ce Mon Sep 17 00:00:00 2001 From: dbhart Date: Wed, 20 Sep 2023 17:15:28 -0600 Subject: [PATCH 27/75] Updates to tests and organization --- .../apidoc/wntr.quality.dynamics.rst | 7 - documentation/apidoc/wntr.quality.model.rst | 7 - .../apidoc/wntr.quality.multispecies.rst | 7 + documentation/apidoc/wntr.quality.rst | 4 +- .../apidoc/wntr.quality.variables.rst | 7 - documentation/index.rst | 1 - wntr/epanet/__init__.py | 3 - wntr/epanet/exceptions.py | 159 ++-- wntr/epanet/io.py | 8 - wntr/epanet/msx/__init__.py | 1 - wntr/epanet/msx/enums.py | 95 +- wntr/epanet/msx/exceptions.py | 292 +++--- wntr/epanet/msx/io.py | 170 ++-- wntr/epanet/msx/toolkit.py | 2 - wntr/epanet/toolkit.py | 10 - wntr/epanet/util.py | 41 +- wntr/quality/MSXPY_toolkit.py | 876 ++++++++++++++++++ wntr/quality/__init__.py | 27 +- wntr/quality/base.py | 200 ++-- wntr/quality/dynamics.py | 234 ----- wntr/quality/io.py | 11 +- wntr/quality/library.py | 65 +- wntr/quality/{model.py => multispecies.py} | 674 +++++++++++++- wntr/quality/options.py | 201 ++-- wntr/quality/variables.py | 362 -------- wntr/tests/test_quality_variables.py | 44 +- 26 files changed, 2157 insertions(+), 1351 deletions(-) delete mode 100644 documentation/apidoc/wntr.quality.dynamics.rst delete mode 100644 documentation/apidoc/wntr.quality.model.rst create mode 100644 documentation/apidoc/wntr.quality.multispecies.rst delete mode 100644 documentation/apidoc/wntr.quality.variables.rst create mode 100644 wntr/quality/MSXPY_toolkit.py delete mode 100644 wntr/quality/dynamics.py rename wntr/quality/{model.py => multispecies.py} (56%) delete mode 100644 wntr/quality/variables.py diff --git a/documentation/apidoc/wntr.quality.dynamics.rst b/documentation/apidoc/wntr.quality.dynamics.rst deleted file mode 100644 index da8cecbb1..000000000 --- a/documentation/apidoc/wntr.quality.dynamics.rst +++ /dev/null @@ -1,7 +0,0 @@ -wntr.quality.dynamics module -============================ - -.. automodule:: wntr.quality.dynamics - :members: - :undoc-members: - :show-inheritance: diff --git a/documentation/apidoc/wntr.quality.model.rst b/documentation/apidoc/wntr.quality.model.rst deleted file mode 100644 index 907115f17..000000000 --- a/documentation/apidoc/wntr.quality.model.rst +++ /dev/null @@ -1,7 +0,0 @@ -wntr.quality.model module -========================= - -.. automodule:: wntr.quality.model - :members: - :undoc-members: - :show-inheritance: diff --git a/documentation/apidoc/wntr.quality.multispecies.rst b/documentation/apidoc/wntr.quality.multispecies.rst new file mode 100644 index 000000000..192296011 --- /dev/null +++ b/documentation/apidoc/wntr.quality.multispecies.rst @@ -0,0 +1,7 @@ +wntr.quality.multispecies module +================================ + +.. automodule:: wntr.quality.multispecies + :members: + :undoc-members: + :show-inheritance: diff --git a/documentation/apidoc/wntr.quality.rst b/documentation/apidoc/wntr.quality.rst index 0078e1b6e..db0dbbb19 100644 --- a/documentation/apidoc/wntr.quality.rst +++ b/documentation/apidoc/wntr.quality.rst @@ -14,9 +14,7 @@ Submodules :maxdepth: 1 wntr.quality.base - wntr.quality.dynamics wntr.quality.io wntr.quality.library - wntr.quality.model + wntr.quality.multispecies wntr.quality.options - wntr.quality.variables diff --git a/documentation/apidoc/wntr.quality.variables.rst b/documentation/apidoc/wntr.quality.variables.rst deleted file mode 100644 index a7efc4617..000000000 --- a/documentation/apidoc/wntr.quality.variables.rst +++ /dev/null @@ -1,7 +0,0 @@ -wntr.quality.variables module -============================= - -.. automodule:: wntr.quality.variables - :members: - :undoc-members: - :show-inheritance: diff --git a/documentation/index.rst b/documentation/index.rst index f7d9e1c42..5ef2fdd51 100644 --- a/documentation/index.rst +++ b/documentation/index.rst @@ -30,7 +30,6 @@ designed to simulate and analyze resilience of water distribution networks. graphics gis advancedsim - advancedqual license whatsnew developers diff --git a/wntr/epanet/__init__.py b/wntr/epanet/__init__.py index 9d33d715a..bcab06872 100644 --- a/wntr/epanet/__init__.py +++ b/wntr/epanet/__init__.py @@ -3,6 +3,3 @@ """ from .io import InpFile #, BinFile, HydFile, RptFile from .util import FlowUnits, MassUnits, HydParam, QualParam, EN -import wntr.epanet.toolkit -import wntr.epanet.exceptions -import wntr.epanet.msx diff --git a/wntr/epanet/exceptions.py b/wntr/epanet/exceptions.py index 0cc6dbc01..68a2c3e6d 100644 --- a/wntr/epanet/exceptions.py +++ b/wntr/epanet/exceptions.py @@ -4,6 +4,8 @@ from enum import IntEnum from typing import List +from wntr.utils.enumtools import add_get + EN_ERROR_CODES = { # Runtime errors 1: "At %s, system hydraulically unbalanced - convergence to a hydraulic solution was not achieved in the allowed number of trials", @@ -83,154 +85,155 @@ 309: "cannot save results to report file %s", } """A dictionary of the error codes and their meanings from the EPANET toolkit. -See :class:`EpanetErrors` for the documentation of each code number. +See :class:`EpanetErrorEnum` for the documentation of each code number. :meta hide-value: """ +@add_get(prefix='ERR_') class EpanetErrorEnum(IntEnum): """A list of short phrases that can be used in place of the error code numbers.""" - warn_unbalanced = 1 + WARN_UNBALANCED = 1 """system hydraulically unbalanced - convergence to a hydraulic solution was not achieved in the allowed number of trials""" - warn_unstable = 2 + WARN_UNSTABLE = 2 """system may be hydraulically unstable - hydraulic convergence was only achieved after the status of all links was held fixed""" - warn_disconnected = 3 + WARN_DISCONNECTED = 3 """system disconnected - one or more nodes with positive demands were disconnected for all supply sources""" - warn_pumps = 4 + WARN_PUMPS = 4 """pumps cannot deliver enough flow or head - one or more pumps were forced to either shut down (due to insufficient head) or operate beyond the maximum rated flow""" - warn_valves = 5 + WARN_VALVES = 5 """vavles cannot deliver enough flow - one or more flow control valves could not deliver the required flow even when fully open""" - warn_pressures = 6 + WARN_PRESSURES = 6 """system has negative pressures - negative pressures occurred at one or more junctions with positive demand""" - insufficient_memory = 101 + INSUFFICIENT_MEMORY = 101 """insufficient memory available""" - no_network = 102 + NO_NETWORK = 102 """no network data available""" - no_init_hyd = 103 + INIT_HYD = 103 """hydraulics not initialized""" - no_hydraulics = 104 + NO_HYD = 104 """no hydraulics for water quality analysis""" - no_init_qual = 105 + NO_INITQ = 105 """water quality not initialized""" - no_results = 106 + NO_RESULTS = 106 """no results saved to report on""" - hyd_file = 107 + HYD_FILE = 107 """hydraulics supplied from external file""" - hyd_init_and_hyd_file = 108 + HYD_INIT_FILE = 108 """cannot use external file while hydraulics solver is active""" - modify_time_during_solve = 109 + MODIFY_TIME = 109 """cannot change time parameter when solver is active""" - solve_hyd_fail = 110 + SOLVE_HYD = 110 """cannot solve network hydraulic equations""" - solve_qual_fail = 120 + SOLVE_QUAL = 120 """cannot solve water quality transport equations""" - input_file_error = 200 + INPUT_FILE = 200 """one or more errors in input file""" - syntax_error = 201 + SYNTAX_ERROR = 201 """syntax error""" - illegal_numeric_value = 202 + ILLEGAL_NUMBER = 202 """illegal numeric value""" - undefined_node = 203 + UNDEFINED_NODE = 203 """undefined node""" - undefined_link = 204 + UNDEFINED_LINK = 204 """undefined link""" - undefined_pattern = 205 + UNDEFINED_PATTERN = 205 """undefined time pattern""" - undefined_curve = 206 + UNDEFINED_CURVE = 206 """undefined curve""" - control_on_cv_gpv = 207 + CV_GPV_CONTROL = 207 """attempt to control a CV/GPV link""" - illegal_pda_limits = 208 + ILLEGAL_PDA_LIMITS = 208 """illegal PDA pressure limits""" - illegal_node_property = 209 + ILLEGAL_NODE_PROPERTY = 209 """illegal node property value""" - illegal_link_property = 211 + ILLEGAL_LINK_PROPERTY = 211 """illegal link property value""" - undefined_trace_node = 212 + UNDEFINED_TRACE = 212 """undefined trace node""" - invalid_option_value = 213 + INVALID_OPTION_VALUE = 213 """invalid option value""" - too_many_chars_inp = 214 + TOO_MANY_CHARS = 214 """too many characters in input line""" - duplicate_id = 215 + DUPLICATE_ID = 215 """duplicate ID label""" - undefined_pump = 216 + UNDEFINED_PUMP = 216 """reference to undefined pump""" - invalid_energy_value = 217 + INVALID_ENERGY = 217 """pump has no head curve or power defined""" - illegal_valve_tank = 219 + ILLEGAL_VALVE_TANK = 219 """illegal valve connection to tank node""" - illegal_tank_valve = 219 + ILLEGAL_TANK_VALVE = 219 """illegal valve connection to tank node""" - illegal_valve_valve = 220 + ILLEGAL_VALVE_VALVE = 220 """illegal valve connection to another valve""" - misplaced_rule = 221 + MISPLACED_RULE = 221 """misplaced rule clause in rule-based control""" - link_to_self = 222 + SAME_START_END = 222 """link assigned same start and end nodes""" - not_enough_nodes = 223 + NUM_NODES = 223 """not enough nodes in network""" - no_tanks_or_res = 224 + NO_TANKS = 224 """no tanks or reservoirs in network""" - invalid_tank_levels = 225 + INVALID_TANK_LEVELS = 225 """invalid lower/upper levels for tank""" - missing_pump_data = 226 + MISSING_PUMP_OPTION = 226 """no head curve or power rating for pump""" - invalid_head_curve = 227 + INVALID_HEAD_CURVE = 227 """invalid head curve for pump""" - nonincreasing_x_curve = 230 + CURVE_X_NONINCREASING = 230 """nonincreasing x-values for curve""" - unconnected_node = 233 + UNCONNECTED_NODE = 233 """network has unconnected node""" - unconnected_node_id = 234 + UNCONNECTED_NODE_ID = 234 """network has an unconnected node with ID""" - no_such_source_node = 240 + NONEXISTENT_SOURCE = 240 """nonexistent water quality source""" - no_such_control = 241 + NONEXISTENT_CONTROL = 241 """nonexistent control""" - invalid_name_format = 250 + INVLAID_NAME_FORMAT = 250 """invalid format (e.g. too long an ID name)""" - invalid_parameter_code = 251 + INVALID_PARAMETER = 251 """invalid parameter code""" - invalid_id_name = 252 + INVALID_ID = 252 """invalid ID name""" - no_such_demand_category = 253 + NONEXISTENT_CATEGORY = 253 """nonexistent demand category""" - missing_coords = 254 + MISSING_COORDS = 254 """node with no coordinates""" - invalid_vertex = 255 + INVALID_VERTEX = 255 """invalid link vertex""" - no_such_rule = 257 + NONEXISTENT_RULE = 257 """nonexistent rule""" - no_such_rule_clause = 258 + NONEXISTENT_RULE_CLAUSE = 258 """nonexistent rule clause""" - delete_node_still_linked = 259 + NODE_STILL_LINKED = 259 """attempt to delete a node that still has links connected to it""" - delete_node_is_trace = 260 + NODE_IS_TRACE = 260 """attempt to delete node assigned as a Trace Node""" - delete_node_in_control = 261 + NODE_IN_CONTROL = 261 """attempt to delete a node or link contained in a control""" - modify_network_during_solve = 262 + MODIFY_NETWORK = 262 """attempt to modify network structure while a solver is open""" - node_not_a_tank = 263 + NOT_A_TANK = 263 """node is not a tank""" - same_file_names = 301 + SAME_FILENAMES = 301 """identical file names used for different types of files""" - open_inp_fail = 302 + OPEN_INP_FILE = 302 """cannot open input file""" - open_rpt_fail = 303 + OPEN_RPT_FILE = 303 """cannot open report file""" - open_bin_fail = 304 + OPEN_BIN_FILE = 304 """cannot open binary output file""" - open_hyd_fail = 305 + OPEN_HYD_FILE = 305 """cannot open hydraulics file""" - hyd_file_different_network = 306 + WRONG_HYD_FILE = 306 """hydraulics file does not match network data""" - read_hyd_fail = 307 + READ_HYDRAULICS = 307 """cannot read hydraulics file""" - save_bin_fail = 308 + SAVE_HYDRAULICS = 308 """cannot save results to binary file""" - save_rpt_fail = 309 + SAVE_REPORT = 309 """cannot save results to report file""" @@ -251,15 +254,9 @@ def __init__(self, code: int, *args: List[object], line_num=None, line=None) -> line : str, optional The contents of the line, by default None """ - if isinstance(code, EpanetErrorEnum): - code = int(code) - elif isinstance(code, str): - try: - code = code.strip().replace('-','_').replace(' ','_') - code = int(EpanetErrorEnum[code]) - except KeyError: - return super().__init__('unknown error code: {}'.format(repr(code)), *args) - elif not isinstance(code, int): + try: + code = int(EpanetErrorEnum.get(code)) + except KeyError: return super().__init__('unknown error code: {}'.format(repr(code)), *args) msg = EN_ERROR_CODES.get(code, 'unknown error') if args is not None: diff --git a/wntr/epanet/io.py b/wntr/epanet/io.py index 8372faf76..49132efda 100644 --- a/wntr/epanet/io.py +++ b/wntr/epanet/io.py @@ -1,13 +1,5 @@ """ The wntr.epanet.io module contains methods for reading/writing EPANET input and output files. - -.. rubric:: Contents - -.. autosummary:: - - InpFile - BinFile - """ from __future__ import absolute_import diff --git a/wntr/epanet/msx/__init__.py b/wntr/epanet/msx/__init__.py index d4bf03075..37d0a4a2d 100644 --- a/wntr/epanet/msx/__init__.py +++ b/wntr/epanet/msx/__init__.py @@ -1,4 +1,3 @@ """The wntr.epanet.msx package provides EPANET-MSX compatibility functions for WNTR. """ from .io import MsxFile -import wntr.epanet.msx.toolkit diff --git a/wntr/epanet/msx/enums.py b/wntr/epanet/msx/enums.py index 38c15cd0e..97d31af6e 100644 --- a/wntr/epanet/msx/enums.py +++ b/wntr/epanet/msx/enums.py @@ -10,14 +10,23 @@ class ObjectType(IntEnum): .. warning:: These enum values start with 0. """ NODE = 0 + """EPANET node""" LINK = 1 + """EPANET link""" PIPE = 1 + """EPANET pipe""" TANK = 2 + """EPANET tank""" SPECIES = 3 + """MSX species""" TERM = 4 + """MSX term""" PARAMETER = 5 + """MSX parameter""" CONSTANT = 6 + """MSX constant""" PATTERN = 7 + """**MSX** pattern""" MAX_OBJECTS = 8 @@ -28,10 +37,15 @@ class SourceType(IntEnum): .. warning:: These enum values start with -1. """ NOSOURCE = -1 + """No source""" CONCEN = 0 + """Concentration based source""" MASS = 1 + """Constant mass source""" SETPOINT = 2 + """Setpoint source""" FLOWPACED = 3 + """Flow-paced source""" @add_get(prefix='MSX_') @@ -41,25 +55,37 @@ class UnitSystemType(IntEnum): .. warning:: These enum values start with 0. """ US = 0 + """US units (ft, ft2, gal)""" SI = 1 + """SI units (m, m2, m3)""" @add_get(prefix='MSX_') class FlowUnitsType(IntEnum): - """The enumeration for the flow units used in EPANET-MSX. + """The enumeration for the flow units used in EPANET-MSX (determined from EPANET INP file read in with the toolkit). .. warning:: These enum values start with 0. """ CFS = 0 + """cubic feet per second""" GPM = 1 + """gallons (US) per minute""" MGD = 2 + """million gallons (US) per day""" IMGD = 3 + """million Imperial gallons per day""" AFD = 4 + """acre-feet (US) per day""" LPS = 5 + """liters per second""" LPM = 6 + """liters per minute""" MLD = 7 + """million liters per day""" CMH = 8 + """cubic meters per hour""" CMD = 9 + """cubic meters per day""" @add_get(prefix='MSX_') @@ -69,9 +95,13 @@ class MixType(IntEnum): .. warning:: These enum values start with 0. """ MIX1 = 0 + """full mixing, 1 compartment""" MIX2 = 1 + """full mixing, 2 comparments""" FIFO = 2 + """first in, first out""" LIFO = 3 + """last in, first out""" @add_get(prefix='MSX_') @@ -81,7 +111,9 @@ class SpeciesType(IntEnum): .. warning:: These enum values start with 0. """ BULK = 0 + """bulk species""" WALL = 1 + """wall species""" @add_get(prefix='MSX_') @@ -91,9 +123,13 @@ class ExpressionType(IntEnum): .. warning:: These enum values start with 0. """ NO_EXPR = 0 + """no expression defined""" RATE = 1 + """expression is a rate expression""" FORMULA = 2 + """expression is a formula expression""" EQUIL = 3 + """expression is an equilibrium expression""" @add_get(prefix='MSX_') @@ -103,8 +139,11 @@ class SolverType(IntEnum): .. warning:: These enum values start with 0. """ EUL = 0 + """Euler solver""" RK5 = 1 + """Runga-Kutta 5th order solver""" ROS2 = 2 + """Ros 2nd order solver""" @add_get(prefix='MSX_') @@ -114,7 +153,9 @@ class CouplingType(IntEnum): .. warning:: These enum values start with 0. """ NO_COUPLING = 0 + """no coupling""" FULL_COUPLING = 1 + """full coupling""" @add_get(prefix='MSX_') @@ -124,9 +165,13 @@ class MassUnitsType(IntEnum): .. warning:: These enum values start with 0. """ MG = 0 + """milligrams""" UG = 1 + """micrograms""" MOLE = 2 + """mole""" MMOLE = 3 + """millimole""" @add_get(prefix='MSX_') @@ -136,8 +181,11 @@ class AreaUnitsType(IntEnum): .. warning:: These enum values start with 0. """ FT2 = 0 + """square feet""" M2 = 1 + """square meters""" CM2 = 2 + """square centimeters""" @add_get(prefix='MSX_') @@ -147,24 +195,35 @@ class RateUnitsType(IntEnum): .. warning:: These enum values start with 0. """ SECONDS = 0 + """per second""" MINUTES = 1 + """per minute""" HOURS = 2 + """per hour""" DAYS = 3 + """per day""" @add_get(prefix='MSX_') class UnitsType(IntEnum): - """The enumerations for units used in EPANET-MSX. + """The position for units used in EPANET-MSX. .. warning:: These enum values start with 0. """ LENGTH_UNITS = 0 + """the length unit index""" DIAM_UNITS = 1 + """the diameter unit index""" AREA_UNITS = 2 + """the area unit index""" VOL_UNITS = 3 + """the volume unit index""" FLOW_UNITS = 4 + """the flow unit index""" CONC_UNITS = 5 + """the concentration unit index""" RATE_UNITS = 6 + """the rate unit index""" MAX_UNIT_TYPES = 7 @@ -175,14 +234,23 @@ class HydVarType(IntEnum): .. warning:: These enum values start with 0. """ DIAMETER = 1 + """pipe diameter""" FLOW = 2 + """pipe flow rate""" VELOCITY = 3 + """segment velocity""" REYNOLDS = 4 + """Reynolds number""" SHEAR = 5 + """shear velocity""" FRICTION = 6 + """friction factor""" AREAVOL = 7 + """area / volume ratio""" ROUGHNESS = 8 + """roughness number""" LENGTH = 9 + """pipe or segment length""" MAX_HYD_VARS = 10 @@ -193,28 +261,43 @@ class TstatType(IntEnum): .. warning:: These enum values start with 0. """ SERIES = 0 + """output a time series""" AVERAGE = 1 + """output the average""" MINIMUM = 2 + """output the minimum""" MAXIMUM = 3 + """output the maximum""" RANGE = 4 + """output the range (max - min)""" @add_get(prefix='MSX_') class OptionType(IntEnum): - """The enumeration used for option in EPANET-MSX. + """The enumeration used for choosing an option in EPANET-MSX toolkit. .. warning:: These enum values start with 0. """ AREA_UNITS_OPTION = 0 + """area units""" RATE_UNITS_OPTION = 1 + """rate units""" SOLVER_OPTION = 2 + """solver""" COUPLING_OPTION = 3 + """coupling""" TIMESTEP_OPTION = 4 + """timestep size""" RTOL_OPTION = 5 + """relative tolerance (global)""" ATOL_OPTION = 6 + """absolute tolerance (global)""" COMPILER_OPTION =7 + """compiler option""" MAXSEGMENT_OPTION = 8 + """max segments""" PECLETNUMBER_OPTION = 9 + """peclet number""" @add_get(prefix='MSX_') @@ -224,8 +307,11 @@ class CompilerType(IntEnum): .. warning:: These enum values start with 0. """ NO_COMPILER = 0 + """do not compile reaction dynamics""" VC = 1 + """use Visual C to compile reaction dynamics""" GC = 2 + """use Gnu C to compile reaction dynamics""" @add_get(prefix='MSX_') @@ -235,5 +321,8 @@ class FileModeType(IntEnum): .. warning:: These enum values start with 0. """ SCRATCH_FILE = 0 + """use a scratch file""" SAVED_FILE = 1 + """save the file""" USED_FILE = 2 + """use a saved file""" diff --git a/wntr/epanet/msx/exceptions.py b/wntr/epanet/msx/exceptions.py index 9afaa3f0a..1df9aabee 100644 --- a/wntr/epanet/msx/exceptions.py +++ b/wntr/epanet/msx/exceptions.py @@ -3,152 +3,128 @@ from enum import IntEnum from typing import List -from ..exceptions import EpanetException, EN_ERROR_CODES, EpanetErrorEnum - - -MSX_ERROR_CODES = EN_ERROR_CODES.copy() -MSX_ERROR_CODES.update( - { - # MSX syntax errors - 401: "too many characters", - 402: "too few input items", - 403: "invalid keyword: '%s'", - 404: "invalid numeric value: '%s'", - 405: "reference to undefined object: '%s'", - 406: "illegal use of reserved name: '%s'", - 407: "name already used by another object: '%s'", - 408: "species already assigned an expression: '%s'", - 409: "illegal math expression", - 410: "option no longer supported", - 411: "term '%s' contains a cyclic reference", - # MSX runtime errors - 501: "insufficient memory available", - 502: "no EPANET data file supplied", - 503: "could not open MSX input file %s", - 504: "could not open hydraulic results file", - 505: "could not read hydraulic results file", - 506: "could not read MSX input file %s", - 507: "too few pipe reaction expressions", - 508: "too few tank reaction expressions", - 509: "could not open differential equation solver", - 510: "could not open algebraic equation solver", - 511: "could not open binary results file", - 512: "read/write error on binary results file", - 513: "could not integrate reaction rate expressions", - 514: "could not solve reaction equilibrium expressions", - 515: "reference made to an unknown type of object %s", - 516: "reference made to an illegal object index %s", - 517: "reference made to an undefined object ID %s", - 518: "invalid property values were specified", - 519: "an MSX project was not opened", - 520: "an MSX project is already opened", - 522: "could not compile chemistry functions", - 523: "could not load functions from compiled chemistry file", - 524: "illegal math operation", - } -) - - -class MSXErrors(IntEnum): - too_many_chars_msx = 401 - too_few_items = 402 - invalid_keyword = 403 - invalid_numeric_value_msx = 404 - undefined_msx_object = 405 - illegal_reserved_name = 406 - name_in_use = 407 - species_already_assigned = 408 - illegal_math_expression = 409 - option_deprecated = 410 - cyclic_reference = 411 - insufficient_memory_msx = 501 - no_epanet_datafile = 502 - open_msx_fail = 503 - open_hyd_fail_msx = 504 - read_hyd_fail_msx = 505 - read_msx_fail = 506 - not_enough_pipe_reactions = 507 - not_enough_tank_reactions = 508 - open_de_solver_fail = 509 - open_ae_solver_fail = 510 - open_bin_fail_msx = 511 - io_error_msx_bin = 512 - solve_rate_failed = 513 - solve_equil_failed = 514 - unknown_object_type = 515 - illegal_object_index = 516 - undefined_object_id = 517 - invalid_property_value = 518 - msx_project_not_open = 519 - msx_project_open = 520 - compile_chem_failed = 522 - load_compiled_chem_failed = 523 - illegal_math_operation = 524 - insufficient_memory = 101 - no_network = 102 - no_init_hyd = 103 - no_hydraulics = 104 - no_init_qual = 105 - no_results = 106 - hyd_file = 107 - hyd_init_and_hyd_file = 108 - modify_time_during_solve = 109 - solve_hyd_fail = 110 - solve_qual_fail = 120 - input_file_error = 200 - syntax_error = 201 - illegal_numeric_value = 202 - undefined_node = 203 - undefined_link = 204 - undefined_pattern = 205 - undefined_curve = 206 - control_on_cv_gpv = 207 - illegal_pda_limits = 208 - illegal_node_property = 209 - illegal_link_property = 211 - undefined_trace_node = 212 - invalid_option_value = 213 - too_many_chars_inp = 214 - duplicate_id = 215 - undefined_pump = 216 - invalid_energy_value = 217 - illegal_valve_tank = 219 - illegal_tank_valve = 219 - illegal_valve_valve = 220 - misplaced_rule = 221 - link_to_self = 222 - not_enough_nodes = 223 - no_tanks_or_res = 224 - invalid_tank_levels = 225 - missing_pump_data = 226 - invalid_head_curve = 227 - nonincreasing_x_curve = 230 - unconnected_node = 233 - unconnected_node_id = 234 - no_such_source_node = 240 - no_such_control = 241 - invalid_name_format = 250 - invalid_parameter_code = 251 - invalid_id_name = 252 - no_such_demand_category = 253 - missing_coords = 254 - invalid_vertex = 255 - no_such_rule = 257 - no_such_rule_clause = 258 - delete_node_still_linked = 259 - delete_node_is_trace = 260 - delete_node_in_control = 261 - modify_network_during_solve = 262 - node_not_a_tank = 263 - same_file_names = 301 - open_inp_fail = 302 - open_rpt_fail = 303 - open_bin_fail = 304 - open_hyd_fail = 305 - hyd_file_different_network = 306 - read_hyd_fail = 307 - save_bin_fail = 308 - save_rpt_fail = 309 + +from wntr.utils.enumtools import add_get + +from ..exceptions import EN_ERROR_CODES, EpanetException + +MSX_ERROR_CODES = { + # MSX syntax errors + 401: "too many characters", + 402: "too few input items", + 403: "invalid keyword: '%s'", + 404: "invalid numeric value: '%s'", + 405: "reference to undefined object: '%s'", + 406: "illegal use of reserved name: '%s'", + 407: "name already used by another object: '%s'", + 408: "species already assigned an expression: '%s'", + 409: "illegal math expression", + 410: "option no longer supported", + 411: "term '%s' contains a cyclic reference", + # MSX runtime errors + 501: "insufficient memory available", + 502: "no EPANET data file supplied", + 503: "could not open MSX input file %s", + 504: "could not open hydraulic results file", + 505: "could not read hydraulic results file", + 506: "could not read MSX input file %s", + 507: "too few pipe reaction expressions", + 508: "too few tank reaction expressions", + 509: "could not open differential equation solver", + 510: "could not open algebraic equation solver", + 511: "could not open binary results file", + 512: "read/write error on binary results file", + 513: "could not integrate reaction rate expressions", + 514: "could not solve reaction equilibrium expressions", + 515: "reference made to an unknown type of object %s", + 516: "reference made to an illegal object index %s", + 517: "reference made to an undefined object ID %s", + 518: "invalid property values were specified", + 519: "an MSX project was not opened", + 520: "an MSX project is already opened", + 522: "could not compile chemistry functions", + 523: "could not load functions from compiled chemistry file", + 524: "illegal math operation", +} +"""Dictionary of MSX error codes and meanings. +See :class:`MsxErrorEnum` for the list of error codes and their meanings. + +:meta hide-value: +""" + + +@add_get(prefix="ERR_") +class MsxErrorEnum(IntEnum): + """The EPANET-MSX input and toolkit error numbers, keys, and descriptions""" + + MAX_CHARS = 401 + "too many characters" + NUM_ITEMS = 402 + "too few input items" + INVALID_KEYWORD = 403 + "invalid keyword" + INVALID_NUMBER = 404 + "invalid numeric value" + UNDEFINED_OBJECT_TYPE = 405 + "reference to undefined object" + RESERVED_NAME = 406 + "illegal use of reserved name" + NAME = 407 + "name already used by another object" + SPECIES_EXPR = 408 + "species already assigned an expression" + ILLEGAL_MATH_EXPR = 409 + "illegal math expression" + DEPRECATED = 410 + "option no longer supported" + CYCLIC_REFERENCE = 411 + "term contains a cyclic reference" + MEMORY = 501 + "insufficient memory available" + NO_EPANET_FILE = 502 + "no EPANET data file supplied" + OPEN_MSX_FILE = 503 + "could not open MSX input file" + OPEN_HYD_FILE = 504 + "could not open hydraulic results file" + READ_HYD_FILE = 505 + "could not read hydraulic results file" + MSX_INPUT = 506 + "could not read MSX input file" + NUM_PIPE_EXPR = 507 + "too few pipe reaction expressions" + NUM_TANK_EXPR = 508 + "too few tank reaction expressions" + INTEGRATOR_OPEN = 509 + """could not open differential equation solver""" + NEWTON_OPEN = 510 + "could not open algebraic equation solver" + OPEN_OUT_FILE = 511 + """could not open binary results file""" + IO_OUT_FILE = 512 + """read/write error on binary results file""" + INTEGRATION = 513 + """could not integrate reaction rate expressions""" + NEWTON = 514 + """could not solve reaction equilibrium expressions""" + INVALID_OBJECT_TYPE = 515 + """reference made to an unknown type of object""" + INVALID_OBJECT_INDEX = 516 + """reference made to an illegal object index""" + UNDEFINED_OBJECT_ID = 517 + """reference made to an undefined object ID""" + INVALID_OBJECT_PARAMS = 518 + """invalid property values were specified""" + MSX_NOT_OPENED = 519 + """an MSX project was not opened""" + MSX_OPENED = 520 + """an MSX project is already opened""" + COMPILE_FAILED = 522 + """could not compile chemistry functions""" + COMPLED_LOAD = 523 + """could not load functions from compiled chemistry file""" + ILLEGAL_MATH = 524 + """illegal math operation""" class EpanetMsxException(EpanetException): @@ -160,23 +136,19 @@ def __init__(self, code: int, *args: List[object], line_num=None, line=None) -> code : int or str or MSXErrors The EPANET-MSX error code (int) or a string mapping to the MSXErrors enum members args : additional non-keyword arguments, optional - If there is a string-format within the error code's text, these will be used to + If there is a string-format within the error code's text, these will be used to replace the format, otherwise they will be output at the end of the Exception message. line_num : int, optional The line number, if reading an INP file, by default None line : str, optional The contents of the line, by default None """ - if isinstance(code, (EpanetErrorEnum, MSXErrors)): - code = int(code) - elif isinstance(code, str): - try: - code = code.strip().replace("-", "_").replace(" ", "_") - code = int(MSXErrors[code]) - except KeyError: - return super(Exception, self).__init__("unknown error code: {}".format(repr(code)), *args) - elif not isinstance(code, int): - return super(Exception, self).__init__("unknown error code: {}".format(repr(code)), *args) + try: + code = MsxErrorEnum.get(code) + except: + return super().__init__(code, *args, line_num=line_num, line=line) + if int(code) < 400: + return super().__init__(code, *args, line_num=line_num, line=line) msg = MSX_ERROR_CODES.get(code, "unknown error") if args is not None: args = [*args] @@ -201,7 +173,7 @@ def __init__(self, code, *args, line_num=None, line=None) -> None: code : int or str or MSXErrors The EPANET-MSX error code (int) or a string mapping to the MSXErrors enum members args : additional non-keyword arguments, optional - If there is a string-format within the error code's text, these will be used to + If there is a string-format within the error code's text, these will be used to replace the format, otherwise they will be output at the end of the Exception message. line_num : int, optional The line number, if reading an INP file, by default None @@ -222,7 +194,7 @@ def __init__(self, code, name, *args, line_num=None, line=None) -> None: name : str The key/name/id that is missing args : additional non-keyword arguments, optional - If there is a string-format within the error code's text, these will be used to + If there is a string-format within the error code's text, these will be used to replace the format, otherwise they will be output at the end of the Exception message. line_num : int, optional The line number, if reading an INP file, by default None @@ -243,7 +215,7 @@ def __init__(self, code, value, *args, line_num=None, line=None) -> None: value : Any The value that is invalid args : additional non-keyword arguments, optional - If there is a string-format within the error code's text, these will be used to + If there is a string-format within the error code's text, these will be used to replace the format, otherwise they will be output at the end of the Exception message. line_num : int, optional The line number, if reading an INP file, by default None diff --git a/wntr/epanet/msx/io.py b/wntr/epanet/msx/io.py index 9ef37a66a..82a63ffa5 100644 --- a/wntr/epanet/msx/io.py +++ b/wntr/epanet/msx/io.py @@ -1,16 +1,16 @@ # coding: utf-8 +"""I/O functions for EPANET-MSX toolkit compatibility""" import datetime -from io import FileIO, TextIOWrapper import logging import sys +from io import FileIO, TextIOWrapper +from wntr.epanet.msx.exceptions import EpanetMsxException +from wntr.epanet.util import ENcomment from wntr.network.elements import Source from wntr.quality.base import LocationType, VariableType -from wntr.quality.base import MSXComment -from wntr.quality.model import MultispeciesReactionModel -from wntr.epanet.msx.exceptions import EpanetMsxException -from wntr.quality.variables import Parameter, Species +from wntr.quality.multispecies import MultispeciesQualityModel, Parameter, Species from wntr.utils.citations import Citation sys_default_enc = sys.getdefaultencoding() @@ -54,6 +54,8 @@ def _split_line(line): class MsxFile(object): def __init__(self): + """An MSX input file, usually ".msx" extension. + """ self.sections = dict() for sec in _INP_SECTIONS: self.sections[sec] = [] @@ -78,7 +80,7 @@ def read(self, msx_file, rxn_model=None): the model with the new species, reactions and other options added """ if rxn_model is None: - rxn_model = MultispeciesReactionModel() + rxn_model = MultispeciesQualityModel() self.rxn = rxn_model # if not isinstance(msx_file, list): # msx_file = [msx_file] @@ -173,7 +175,7 @@ def _read_title(self): def _read_options(self): lines = [] - note = MSXComment() + note = ENcomment() for lnum, line in self.sections["[OPTIONS]"]: vals, comment = _split_line(line) try: @@ -211,7 +213,7 @@ def _read_options(self): def _read_species(self): lines = [] - note = MSXComment() + note = ENcomment() for lnum, line in self.sections["[SPECIES]"]: vals, comment = _split_line(line) if vals is None: @@ -234,11 +236,11 @@ def _read_species(self): except Exception as e: raise EpanetMsxException(201, note='at line {} of [SPECIES] section:\n{}'.format(lnum, line)) from e else: - note = MSXComment() + note = ENcomment() def _read_coefficients(self): lines = [] - note = MSXComment() + note = ENcomment() for lnum, line in self.sections["[COEFFICIENTS]"]: vals, comment = _split_line(line) if vals is None: @@ -256,11 +258,11 @@ def _read_coefficients(self): except Exception as e: raise EpanetMsxException(201, note='at line {} of [COEFFICIENTS] section:\n{}'.format(lnum, line)) from e else: - note = MSXComment() + note = ENcomment() def _read_terms(self): lines = [] - note = MSXComment() + note = ENcomment() for lnum, line in self.sections["[TERMS]"]: vals, comment = _split_line(line) if vals is None: @@ -278,11 +280,11 @@ def _read_terms(self): except Exception as e: raise EpanetMsxException(201, note='at line {} of [TERMS] section:\n{}'.format(lnum, line)) from e else: - note = MSXComment() + note = ENcomment() def _read_pipes(self): lines = [] - note = MSXComment() + note = ENcomment() for lnum, line in self.sections["[PIPES]"]: vals, comment = _split_line(line) if vals is None: @@ -300,11 +302,11 @@ def _read_pipes(self): except Exception as e: raise EpanetMsxException(201, note='at line {} of [PIPES] section:\n{}'.format(lnum, line)) from e else: - note = MSXComment() + note = ENcomment() def _read_tanks(self): lines = [] - note = MSXComment() + note = ENcomment() for lnum, line in self.sections["[TANKS]"]: vals, comment = _split_line(line) if vals is None: @@ -322,11 +324,11 @@ def _read_tanks(self): except Exception as e: raise EpanetMsxException(201, note='at line {} of [TANKS] section:\n{}'.format(lnum, line)) from e else: - note = MSXComment() + note = ENcomment() def _read_sources(self): lines = [] - note = MSXComment() + note = ENcomment() for lnum, line in self.sections["[SOURCES]"]: vals, comment = _split_line(line) if vals is None: @@ -352,11 +354,11 @@ def _read_sources(self): except Exception as e: raise EpanetMsxException(201, note='at line {} of [SOURCES] section:\n{}'.format(lnum, line)) from e else: - note = MSXComment() + note = ENcomment() def _read_quality(self): lines = [] - note = MSXComment() + note = ENcomment() for lnum, line in self.sections["[QUALITY]"]: vals, comment = _split_line(line) if vals is None: @@ -387,11 +389,11 @@ def _read_quality(self): except Exception as e: raise EpanetMsxException(201, note='at line {} of [QUALITY] section:\n{}'.format(lnum, line)) from e else: - note = MSXComment() + note = ENcomment() def _read_parameters(self): lines = [] - note = MSXComment() + note = ENcomment() for lnum, line in self.sections["[PARAMETERS]"]: vals, comment = _split_line(line) if vals is None: @@ -417,11 +419,11 @@ def _read_parameters(self): except Exception as e: raise EpanetMsxException(201, note='at line {} of [PARAMETERS] section:\n{}'.format(lnum, line)) from e else: - note = MSXComment() + note = ENcomment() def _read_diffusivity(self): lines = [] - note = MSXComment() + note = ENcomment() for lnum, line in self.sections["[DIFFUSIVITY]"]: vals, comment = _split_line(line) if vals is None: @@ -442,7 +444,7 @@ def _read_diffusivity(self): except Exception as e: raise EpanetMsxException(201, note='at line {} of [DIFFUSIVITIES] section:\n{}'.format(lnum, line)) from e else: - note = MSXComment() + note = ENcomment() def _read_patterns(self): _patterns = dict() @@ -466,7 +468,7 @@ def _read_patterns(self): def _read_report(self): lines = [] - note = MSXComment() + note = ENcomment() for lnum, line in self.sections["[REPORT]"]: vals, comment = _split_line(line) if vals is None: @@ -522,10 +524,19 @@ def _read_report(self): except Exception as e: raise EpanetMsxException(201, note='at line {} of [REPORT] section:\n{}'.format(lnum, line)) from e else: - note = MSXComment() + note = ENcomment() + + def write(self, filename: str, msx: MultispeciesQualityModel): + """Write an MSX input file. - def write(self, filename: str, rxn: MultispeciesReactionModel): - self.rxn = rxn + Parameters + ---------- + filename : str + the filename to write + rxn : MultispeciesQualityModel + the multispecies reaction model + """ + self.rxn = msx with open(filename, "w") as fout: fout.write("; WNTR-reactions MSX file generated {}\n".format(datetime.datetime.now())) @@ -549,20 +560,6 @@ def _write_title(self, fout): fout.write("[TITLE]\n") fout.write(" {}\n".format(self.rxn.title)) fout.write("\n") - # if self.rxn.desc is not None: - # desc = self.rxn.desc.splitlines() - # desc = " ".join(desc) - # fout.write("; @desc={}\n".format(desc)) - # fout.write("\n") - # if self.rxn.citations is not None: - # if isinstance(self.rxn.citations, list): - # for citation in self.rxn.citations: - # fout.write("; @cite={}\n".format(citation.to_dict() if isinstance(citation, Citation) else str(citation))) - # fout.write("\n") - # else: - # citation = self.rxn.citations - # fout.write("; @cite={}\n".format(citation.to_dict() if isinstance(citation, Citation) else str(citation))) - # fout.write("\n") def _write_options(self, fout): opts = self.rxn._options @@ -581,78 +578,103 @@ def _write_options(self, fout): def _write_species(self, fout): fout.write("[SPECIES]\n") + def to_msx_string(self) -> str: + tols = self.get_tolerances() + if tols is None: + tolstr = "" + else: + tolstr = " {:12.6g} {:12.6g}".format(*tols) + return "{:<12s} {:<8s} {:<8s}{:s}".format( + self.var_type.name.upper(), + self.name, + self.units, + tolstr, + ) for var in self.rxn.variables(var_type=VariableType.BULK): - if isinstance(var.note, MSXComment): - fout.write("{}\n".format(var.note.wrap_msx_string(var.to_msx_string()))) + if isinstance(var.note, ENcomment): + fout.write("{}\n".format(var.note.wrap_msx_string(to_msx_string(var)))) elif isinstance(var.note, str): - fout.write(" {} ; {}\n".format(var.to_msx_string(), var.note)) + fout.write(" {} ; {}\n".format(to_msx_string(var), var.note)) else: - fout.write(" {}\n".format(var.to_msx_string())) + fout.write(" {}\n".format(to_msx_string(var))) for var in self.rxn.variables(var_type=VariableType.WALL): - if isinstance(var.note, MSXComment): - fout.write("{}\n".format(var.note.wrap_msx_string(var.to_msx_string()))) + if isinstance(var.note, ENcomment): + fout.write("{}\n".format(var.note.wrap_msx_string(to_msx_string(var)))) elif isinstance(var.note, str): - fout.write(" {} ; {}\n".format(var.to_msx_string(), var.note)) + fout.write(" {} ; {}\n".format(to_msx_string(var), var.note)) else: - fout.write(" {}\n".format(var.to_msx_string())) + fout.write(" {}\n".format(to_msx_string(var))) fout.write("\n") def _write_coefficients(self, fout): fout.write("[COEFFICIENTS]\n") + def to_msx_string(self) -> str: + # if self.units is not None: + # post = r' ; {"units"="' + str(self.units) + r'"}' + # else: + post = '' + return "{:<12s} {:<8s} {:<16s}{}".format( + self.var_type.name.upper(), + self.name, + str(self.global_value), + post + ) for var in self.rxn.variables(var_type=VariableType.CONST): - if isinstance(var.note, MSXComment): - fout.write("{}\n".format(var.note.wrap_msx_string(var.to_msx_string()))) + if isinstance(var.note, ENcomment): + fout.write("{}\n".format(var.note.wrap_msx_string(to_msx_string(var)))) elif isinstance(var.note, str): - fout.write(" {} ; {}\n".format(var.to_msx_string(), var.note)) + fout.write(" {} ; {}\n".format(to_msx_string(var), var.note)) else: - fout.write(" {}\n".format(var.to_msx_string())) + fout.write(" {}\n".format(to_msx_string(var))) for var in self.rxn.variables(var_type=VariableType.PARAM): - if isinstance(var.note, MSXComment): - fout.write("{}\n".format(var.note.wrap_msx_string(var.to_msx_string()))) + if isinstance(var.note, ENcomment): + fout.write("{}\n".format(var.note.wrap_msx_string(to_msx_string(var)))) elif isinstance(var.note, str): - fout.write(" {} ; {}\n".format(var.to_msx_string(), var.note)) + fout.write(" {} ; {}\n".format(to_msx_string(var), var.note)) else: - fout.write(" {}\n".format(var.to_msx_string())) + fout.write(" {}\n".format(to_msx_string(var))) fout.write("\n") def _write_terms(self, fout): fout.write("[TERMS]\n") + def to_msx_string(self) -> str: + return "{:<8s} {:<64s}".format(self.name, self.expression) for var in self.rxn.variables(var_type=VariableType.TERM): - if isinstance(var.note, MSXComment): - fout.write("{}\n".format(var.note.wrap_msx_string(var.to_msx_string()))) + if isinstance(var.note, ENcomment): + fout.write("{}\n".format(var.note.wrap_msx_string(to_msx_string(var)))) elif isinstance(var.note, str): - fout.write(" {} ; {}\n".format(var.to_msx_string(), var.note)) + fout.write(" {} ; {}\n".format(to_msx_string(var), var.note)) else: - fout.write(" {}\n".format(var.to_msx_string())) + fout.write(" {}\n".format(to_msx_string(var))) fout.write("\n") def _write_pipes(self, fout): fout.write("[PIPES]\n") for var in self.rxn.reactions(location=LocationType.PIPE): - if isinstance(var.note, MSXComment): - fout.write("{}\n".format(var.note.wrap_msx_string(var.to_msx_string()))) + if isinstance(var.note, ENcomment): + fout.write("{}\n".format(var.note.wrap_msx_string("{:<12s} {:<8s} {:<32s}".format(var.expr_type.name.upper(), str(var.species), var.expression)))) elif isinstance(var.note, str): - fout.write(" {} ; {}\n".format(var.to_msx_string(), var.note)) + fout.write(" {} ; {}\n".format("{:<12s} {:<8s} {:<32s}".format(var.expr_type.name.upper(), str(var.species), var.expression), var.note)) else: - fout.write(" {}\n".format(var.to_msx_string())) + fout.write(" {}\n".format("{:<12s} {:<8s} {:<32s}".format(var.expr_type.name.upper(), str(var.species), var.expression))) fout.write("\n") def _write_tanks(self, fout): fout.write("[TANKS]\n") for var in self.rxn.reactions(location=LocationType.TANK): - if isinstance(var.note, MSXComment): - fout.write("{}\n".format(var.note.wrap_msx_string(var.to_msx_string()))) + if isinstance(var.note, ENcomment): + fout.write("{}\n".format(var.note.wrap_msx_string("{:<12s} {:<8s} {:<32s}".format(var.expr_type.name.upper(), str(var.species), var.expression)))) elif isinstance(var.note, str): - fout.write(" {} ; {}\n".format(var.to_msx_string(), var.note)) + fout.write(" {} ; {}\n".format("{:<12s} {:<8s} {:<32s}".format(var.expr_type.name.upper(), str(var.species), var.expression), var.note)) else: - fout.write(" {}\n".format(var.to_msx_string())) + fout.write(" {}\n".format("{:<12s} {:<8s} {:<32s}".format(var.expr_type.name.upper(), str(var.species), var.expression))) fout.write("\n") def _write_sources(self, fout): fout.write("[SOURCES]\n") for species in self.rxn._sources.keys(): for node, src in self.rxn._sources[species].items(): - if isinstance(src["note"], MSXComment): + if isinstance(src["note"], ENcomment): fout.write( src["note"].wrap_msx_string( "{:<10s} {:<8s} {:<8s} {:12s} {:<12s}".format(src["source_type"], node, species, src["strength"], src["pattern"] if src["pattern"] is not None else "") @@ -748,10 +770,12 @@ def _write_report(self, fout): fout.write(" PAGESIZE {}\n".format(self.rxn._options.report.pagesize)) fout.write("\n") -import wntr.network import numpy as np import pandas as pd +import wntr.network + + def MsxBinFile(filename, wn: wntr.network.WaterNetworkModel): duration = int(wn.options.time.duration) diff --git a/wntr/epanet/msx/toolkit.py b/wntr/epanet/msx/toolkit.py index 9cc971d80..599131aa3 100644 --- a/wntr/epanet/msx/toolkit.py +++ b/wntr/epanet/msx/toolkit.py @@ -7,8 +7,6 @@ Code in this section taken from code originally written by Junli Hao 07/29/2018, "EPANET-MSX-Python-wrapper" on GitHub, licensed under the BSD license. See LICENSE.txt for more details. - - """ import ctypes from enum import IntEnum diff --git a/wntr/epanet/toolkit.py b/wntr/epanet/toolkit.py index 21ffb67a5..38b1fd14d 100644 --- a/wntr/epanet/toolkit.py +++ b/wntr/epanet/toolkit.py @@ -1,16 +1,6 @@ """ The wntr.epanet.toolkit module is a Python extension for the EPANET Programmers Toolkit DLLs. - -.. rubric:: Contents - -.. autosummary:: - - runepanet - ENepanet - EpanetException - ENgetwarning - """ import ctypes import os diff --git a/wntr/epanet/util.py b/wntr/epanet/util.py index 24673b2d5..9c8fb41e5 100644 --- a/wntr/epanet/util.py +++ b/wntr/epanet/util.py @@ -1,30 +1,10 @@ """ The wntr.epanet.util module contains unit conversion utilities based on EPANET units. - -.. rubric:: Contents - -.. autosummary:: - - FlowUnits - MassUnits - QualParam - HydParam - to_si - from_si - StatisticsType - QualType - SourceType - PressureUnits - FormulaType - ControlType - LinkTankStatus - MixType - ResultType - EN - """ +from dataclasses import dataclass, field import enum import logging +from typing import List import numpy as np import pandas as pd @@ -1403,3 +1383,20 @@ def from_si( return param._from_si(to_units, data, mass_units, reaction_order) else: raise RuntimeError("Invalid parameter: %s" % param) + + +@dataclass +class ENcomment: + pre: List[str] = field(default_factory=list) + post: str = None + + def wrap_msx_string(self, string) -> str: + if self.pre is None or len(self.pre) == 0: + if self.post is None: + return ' ' + string + else: + return ' ' + string + ' ; ' + self.post + elif self.post is None: + return '\n; ' + '\n\n; '.join(self.pre) + '\n\n ' + string + else: + return '\n; ' + '\n\n; '.join(self.pre) + '\n\n ' + string + ' ; ' + self.post diff --git a/wntr/quality/MSXPY_toolkit.py b/wntr/quality/MSXPY_toolkit.py new file mode 100644 index 000000000..d7a9c374b --- /dev/null +++ b/wntr/quality/MSXPY_toolkit.py @@ -0,0 +1,876 @@ +# # -*- coding: utf-8 -*- +# """ +# Created on Fri Jun 18 10:52:45 2021 + +# @author: Matthew +# """ + +# import numpy as np +# import epanet_toolkit as epa +# import msx_toolkit as msx +# import pandas as pd +# import os +# from sklearn.cluster import KMeans +# from sklearn.metrics import silhouette_score +# import wntr +# from scipy.linalg import cholesky +# from SALib.analyze import morris as morris_a + +# def MSXRunQual(species='all', nodes='all', links='all',by_species='yes',bin_read='no',t_start=-1): +# #Function to run a MSX model and extract timeseries of specified species, links, and nodes +# #Inputs are a list of the desired species, nodes, links, and whether the results +# #should be organized by species, or by model element (links and nodes) +# #if no nodes or links are desired, then an empty list [] should be used +# #The t_start option is a number in days which says when the results from the +# #simulation should start to be recorded. This is helpful if a model needs to run +# #to reach hydraulic equilbriums and the first X number of days of the simulation +# #are not needed for the results + +# #The bin_read option allows for the model to be run all at once and +# #then the binary file is read. The reporting timesteps are based on the +# #reporting timestep from the inp file. If not, the results +# #are read at each timestep from the msx model run. + +# if bin_read=='no': + +# #Extract the indicies and names for the species of interest +# if (species=='all'): +# species_names=[] +# #Get the number of species 3 for species +# species_num=msx.MSXgetcount(3) +# #Get a list for the species id's +# for i in range(species_num): +# species_names.append(msx.MSXgetID(3,i+1)) +# #get an array for the species indicies +# species_ind=np.linspace(1,species_num,species_num) + +# #If there is a user supplied list of species to be extracted +# else: +# #Make the user-input list the variable species_names +# species_names=species +# #Extract the indicies for the species being specified +# species_ind=[] +# for i in range(len(species_names)): +# species_ind.append(msx.MSXgetindex(3,species_names[i])) + +# #Extract the node indicies for the specified nodes +# if (nodes=='all'): +# node_names=[] +# #Get the number of nodes- 0 for nodes +# node_num=epa.ENgetcount(0) +# #Get a list for the node id's +# for i in range(node_num): +# node_names.append(epa.ENgetnodeid(i+1)) +# #Get an array for the node indicies +# node_ind=np.linspace(1,node_num,node_num) + +# #If there are actual nodes specified to be extracted +# else: +# #Make the user-input list the variable node_names +# node_names=nodes +# #Extract the indicies for the nodes being specified +# node_ind=[] +# for i in range(len(node_names)): +# node_ind.append(epa.ENgetnodeindex(node_names[i])) + +# #Do the same but for links + +# #Extract the link indicies for the specified nodes +# if (links=='all'): +# link_names=[] +# #Get the number of links- 2 for links +# link_num=epa.ENgetcount(2) +# #Get a list for the link id's +# for i in range(link_num): +# link_names.append(epa.ENgetlinkid(i+1)) +# #Get an array for the node indicies +# link_ind=np.linspace(1,link_num,link_num) + +# #If there are actual nodes specified to be extracted +# else: +# #Make the user-input list the variable node_names +# link_names=links +# #Extract the indicies for the nodes being specified +# link_ind=[] +# for i in range(len(link_names)): +# link_ind.append(epa.ENgetlinkindex(link_names[i])) + + + +# #Create array to extract the time of the simulation steps +# T=[] + +# #Initialize MSX for first timestep +# msx.MSXinit(0) + +# #Initialize time left +# t_left=1 + +# #Create overall results dictionary +# results={} + +# #If organized by species +# if (by_species=='yes'): +# #Create a new dictionary for each species and then within each species +# #make a node and link list +# for i in range(len(species_names)): +# results[species_names[i]]={} +# results[species_names[i]]['node']=[] +# results[species_names[i]]['link']=[] + +# #If organized by element +# if (by_species=='no'): +# #Create node key and another dictionary +# results['node']={} +# #Create link key and another dictionary +# results['link']={} + +# #Within each dictionary make a list to be populated later during model run +# #nodes +# for i in range(len(node_names)): +# results['node'][node_names[i]]=[] +# #links +# for i in range(len(link_names)): +# results['link'][link_names[i]]=[] + + +# #Change the input of t_start from days to seconds +# t_start=t_start*24*60*60 + + +# #Create loop to run model +# while (t_left>0): +# #Solve the quality for that timestep +# [t,t_left]=msx.MSXstep() + +# #If the results should be extracted based on t_start aka the simulation +# #time has passed the time when we care about the results +# if t>t_start: + +# #Append time for that step to the overall time list +# T.append(t) + +# #If the results are to be extracted by model element +# if (by_species=='no'): +# #Extract the results from each node into a different list +# for j in range(len(node_names)): +# #Create a row for the overall results list +# Q_row=[] +# #Extract the results for each desired species at that node +# for i in range(len(species_names)): +# #0 for node #node_ind and the species_ind +# Q_row.append(msx.MSXgetqual(0,int(node_ind[j]),int(species_ind[i]))) +# results['node'][node_names[j]].append(Q_row) + +# #Extract the results from each link into a different list +# for j in range(len(link_names)): +# #Create a row for the overall results list +# Q_row=[] +# #Extract the results for each desired species at that node +# for i in range(len(species_names)): +# #0 for link #node_ind and the species_ind +# Q_row.append(msx.MSXgetqual(1,int(link_ind[j]),int(species_ind[i]))) +# results['link'][link_names[j]].append(Q_row) + +# #If the results are to be extracted by species +# if (by_species=='yes'): +# for i in range(len(species_names)): +# #First extract the nodes and then the links +# #Create empty lists for each row to be added +# Q_row_node=[] +# Q_row_link=[] + +# #Extract results by node +# for j in range(len(node_names)): +# Q_row_node.append(msx.MSXgetqual(0,int(node_ind[j]),int(species_ind[i]))) +# results[species_names[i]]['node'].append(Q_row_node) + +# #Extract results by link +# for j in range(len(link_names)): +# Q_row_link.append(msx.MSXgetqual(1,int(link_ind[j]),int(species_ind[i]))) +# results[species_names[i]]['link'].append(Q_row_link) + + + +# #After the simulation is complete go through the results one more time and +# #convert the lists into dataframes +# if (by_species=='no'): +# #Nodes +# for i in range(len(node_names)): +# results['node'][node_names[i]]=pd.DataFrame(results['node'][node_names[i]],index=T,columns=species_names) + +# #Links +# for i in range(len(link_names)): +# results['link'][link_names[i]]=pd.DataFrame(results['link'][link_names[i]],index=T,columns=species_names) + +# if (by_species=='yes'): +# #Nodes +# for i in range(len(species_names)): +# results[species_names[i]]['node']=pd.DataFrame(results[species_names[i]]['node'],index=T,columns=node_names) + +# #links +# for i in range(len(species_names)): +# results[species_names[i]]['link']=pd.DataFrame(results[species_names[i]]['link'],index=T,columns=link_names) + +# if bin_read=='yes': + +# #Solve the quality of the model +# msx.MSXsolveQ() + +# #Save quality results to binary file +# #Add the process id to the binary file name so that multiple processes are +# #not trying to read from the same file if it is run in parallel +# filename='results_temp'+str(os.getpid())+'.bin' +# msx.MSXsaveoutfile(filename) + +# #def MSXBinReader(filename, epanetinpfile): + +# #This code is from Jon Buckhardt that I lightly edited +# duration=epa.ENgettimeparam(0) +# with open(filename, 'rb') as fin: +# ftype = '=f4' +# idlen = 32 +# prolog = np.fromfile(fin, dtype = np.int32, count = 6) +# magic1 = prolog[0] +# version = prolog[1] +# nnodes = prolog[2] +# nlinks = prolog[3] +# nspecies = prolog[4] +# reportstep = prolog[5] +# species_list = [] +# node_list = GetNodeNameList() +# link_list = GetLinkNameList() + +# for i in range(nspecies): +# species_len = int(np.fromfile(fin, dtype = np.int32, count = 1)) +# species_name = ''.join(chr(f) for f in np.fromfile(fin, dtype = np.uint8, count = species_len) if f!=0) +# species_list.append(species_name) + + +# species_mass = [] +# for i in range(nspecies): +# species_mass.append(''.join(chr(f) for f in np.fromfile(fin, dtype = np.uint8, count = 16) if f != 0)) +# timerange = range(0, duration+1, reportstep) + +# tr = len(timerange) + +# row1 = ['node']*nnodes*len(species_list)+['link']*nlinks*len(species_list) +# row2 = [] +# for i in [nnodes,nlinks]: +# for j in species_list: +# row2.append([j]*i) +# row2 = [y for x in row2 for y in x] +# row3 = [node_list for i in species_list] + [link_list for i in species_list] +# row3 = [y for x in row3 for y in x] + +# tuples = list(zip(row1, row2, row3)) +# index = pd.MultiIndex.from_tuples(tuples, names = ['type','species','name']) + +# try: +# data = np.fromfile(fin, dtype = np.dtype(ftype), count = tr*(len(species_list*(nnodes + nlinks)))) +# data = np.reshape(data, (tr, len(species_list*(nnodes + nlinks)))) +# except Exception as e: +# print(e) +# print ("oops") +# postlog = np.fromfile(fin, dtype = np.int32, count = 4) +# offset = postlog[0] +# numreport = postlog[1] +# errorcode = postlog[2] +# magicnew = postlog[3] +# if magic1 == magicnew: +# #print("Magic# Match") +# df_fin = pd.DataFrame(data.transpose(), index = index, columns = timerange) +# df_fin = df_fin.transpose() +# else: +# print("Magic#s do not match!") +# #return df_fin + +# #df is a multilevel index dataframe of all of the results + +# #Now I am going to repackage the results so that it fits with my struct structure +# #Of how I was doing the results before. This may take a bit of time but I want +# #things how I want them:) + +# #Create the dictionary +# results={} + +# #Go through all the nodes and put data from the dataframe into the correct place +# #in the results dictionary + +# if nodes=='all': +# nodes=GetNodeNameList() + +# if links=='all': +# links=GetLinkNameList() + +# if species=='all': +# species=GetSpeciesNameList() + + + +# if by_species=='no': + +# #Create a dictionary within the dictionary for nodes and links +# results['node']={} + +# results['link']={} + +# for i in range(len(nodes)): +# #Put the dataframe in the dictionary at the correct location +# results['node'][nodes[i]]=df_fin.loc[:,('node',species,nodes[i])] +# #Fix the index so it is no longer a multiindex +# results['node'][nodes[i]].columns=results['node'][nodes[i]].columns.droplevel(['type','name']) + +# for i in range(len(links)): +# #Put the dataframe in the dictionary at the correct location +# results['link'][links[i]]=df_fin.loc[:,('link',species,links[i])] +# #Fix the index so it is no longer a multiindex +# results['link'][links[i]].columns=results['link'][links[i]].columns.droplevel(['type','name']) + +# if by_species=='yes': + +# for i in range(len(species)): +# #Create a dictionary for that species +# results[species[i]]={} + +# #Put the concentrations of the nodes of that species in the right place +# results[species[i]]['node']=df_fin.loc[:,('node',species[i],nodes)] +# #Fix the index so it is no longer a multiindex +# results[species[i]]['node'].columns=results[species[i]]['node'].columns.droplevel(['type','species']) + +# #Put the concentrations of the links of that species in the right place +# results[species[i]]['link']=df_fin.loc[:,('link',species[i],links)] +# #Fix the index so it is no longer a multiindex +# results[species[i]]['link'].columns=results[species[i]]['link'].columns.droplevel(['type','species']) + +# #Remove the +# try: +# os.remove(filename) +# except: +# print('Error removing ' + filename) + +# return results + +# #Get a list of all the node names +# def GetNodeNameList(): +# node_names=[] +# #Get the number of nodes- 0 for nodes +# node_num=epa.ENgetcount(0) +# #Get a list for the node id's +# for i in range(node_num): +# node_names.append(epa.ENgetnodeid(i+1)) +# #Get an array for the node indicies +# #node_ind=np.linspace(1,node_num,node_num) +# return node_names + +# #Get a list of all link names +# def GetLinkNameList(): +# link_names=[] +# #Get the number of nodes- 2 for links +# link_num=epa.ENgetcount(2) +# #Get a list for the node id's +# for i in range(link_num): +# link_names.append(epa.ENgetlinkid(i+1)) +# #Get an array for the node indicies +# #node_ind=np.linspace(1,node_num,node_num) +# return link_names + + + +# #Get a list of all the species names +# def GetSpeciesNameList(): +# species_names=[] +# #Get the number of species 3 for species +# species_num=msx.MSXgetcount(3) +# #Get a list for the species id's +# for i in range(species_num): +# species_names.append(msx.MSXgetID(3,i+1)) +# return species_names + +# def GetConstantNameList(): +# #Get the name for each constant +# constant_names=[] +# #Get the number of constants +# constants_num=msx.MSXgetcount(6) +# for i in range(constants_num): +# #Get the name of each specific constant, 6 for constant +# constant_names.append(msx.MSXgetID(6,i+1)) +# return constant_names + +# def TimeToCriticalValue(results,element_type='node',element='1',species='cNH2CL',crit_val=1.46): +# #As currently written, assumes results are NOT by species and that the +# #critical value is decreasing, finding the value on the way down + +# element_results=results[element_type][element] +# chlor=element_results.loc[:,species] +# chlor=chlor[chlor>crit_val] +# t_crit=np.max(chlor.index) +# return t_crit + +# def TimeToCriticalValueSeries(chlor,crit_val=1.46): +# #Same as function above but takes a series as an input instead of the overall results dictionary + +# #As currently written, assumes results are NOT by species and that the +# #critical value is decreasing, finding the value on the way down + +# chlor=chlor[chlor>crit_val] +# t_crit=np.max(chlor.index) +# return t_crit + +# def GetConstants(con_get): +# #Returns a numpy array with the constants of a model + +# #Get the indicies of the constants of interest +# inds=[] +# for i in range(len(con_get)): +# inds.append(msx.MSXgetindex(6,con_get[i])) + +# #Make an array holding the initial value for each constant +# constants=np.zeros((len(inds),1)) +# #Populate that array with the initial value of each constant +# #IMPORTANT: Requires that the input vector is the indicies starting from 1 +# #not starting from 0 which is done in the previous for loop +# for i in range(len(inds)): +# constants[i] = msx.MSXgetconstant(inds[i]) + +# return constants + +# def GetInitialConcentration(node,species): +# #Inputs: Nodes of interest and species of interest +# #The node input is the ID of the node not the index number +# #Returns a numpy array with the initial concentration of the specified +# #Species at the specified node + + +# #Get the index of the specified node +# node_ind=epa.ENgetnodeindex(node) + + +# #Get the indicies of the species of interest +# inds=[] +# #Get the indicies of the species of interest +# for i in range(len(species)): +# inds.append(msx.MSXgetindex(3,species[i])) + +# #Make an array holding the initial value for each species +# initial_con=np.zeros((len(inds),1)) + +# #Populate that array with the initial value of each initial species at the +# #specified node, input to the function +# for i in range(len(inds)): +# initial_con[i] = msx.MSXgetinitqual(0,node_ind,inds[i]) + +# return initial_con + + +# def SetConstants(con_get,given_constants): +# #Set constants to specific values +# #con_get is a list with the IDs of the constants to be varied +# #given_constants is a numpy array of the values of the constants to be changed +# #the order of IDs in con_get must be the same as the order of the values in +# #given_constants + +# #Get the indicies of the constants of interest +# inds=[] +# for i in range(len(con_get)): +# inds.append(msx.MSXgetindex(6,con_get[i])) + +# #Populate that array with the initial value of each constant +# for i in range(len(inds)): +# msx.MSXsetconstant(inds[i],given_constants[i]) + +# def SetInitialConcentration(node,species,init_val): +# #Inputs: Nodes of interest and species of interest, and vector of species values +# #The node input is the ID of the node not the index number + +# if (len(species)!=len(init_val)): +# raise Exception('The length of species IDs list and species value array are not equal') + +# #Get the index of the specified node +# node_ind=epa.ENgetnodeindex(node) + +# #Get the indicies of the species of interest +# inds=[] +# for i in range(len(species)): +# inds.append(msx.MSXgetindex(3,species[i])) + +# #Set the species of interest to the specified values +# for i in range(len(inds)): +# msx.MSXsetinitqual(0,node_ind,inds[i],init_val[i]) + +# def SetGlobalInitialConcentration(species,init_val): + + +# #Get the number of nodes in the model +# node_num=epa.ENgetcount(0) + +# #Get the number of links- 2 for links +# link_num=epa.ENgetcount(2) + +# #Get the indicies of the species of interest +# inds=[] +# for i in range(len(species)): +# inds.append(msx.MSXgetindex(3,species[i])) + +# #Loop through each node +# #Set the species of interest to the specified values +# #For each species +# for i in range(len(inds)): +# #For each node +# for j in range(node_num): +# #j+1 because epanet indicies start from 1 not 0 like python +# msx.MSXsetinitqual(0,j+1,inds[i],init_val[i]) + +# #Loop through each species +# #Set the species of interest to the specified values +# #For each species +# for i in range(len(inds)): +# #For each link +# for j in range(link_num): +# #j+1 because epanet indicies start from 1 not 0 like python +# msx.MSXsetinitqual(1,j+1,inds[i],init_val[i]) + + + +# def GetAllNodeDemands(): +# #Get the base demands for each node +# #Get the number of nodes +# node_num=epa.ENgetcount(0) +# #Create a list to put the values +# node_demands=[] +# #Extract the demands from the model +# for i in range(node_num): +# node_demands.append(epa.ENgetnodevalue(i+1, 1)) +# #Turn the list into an array +# node_demands=np.array(node_demands) +# return node_demands + +# def SetAllNodeDemands(given_demands): +# #Get the number of nodes +# node_num=epa.ENgetcount(0) +# #Raise an error if the number of demands supplied does not match the +# #number of nodes in the model +# if (node_num!=len(given_demands)): +# raise Exception('The number of demands provided dose not match the total number of nodes in the model') +# #Set the demands in the model +# for i in range(len(given_demands)): +# epa.ENsetnodevalue(i+1, 1, given_demands[i]) + +# def SetNodeDemands(nodes,given_demands): +# #Set baseline demands in specific nodes +# for i in range(len(nodes)): +# epa.ENsetnodevalue(epa.ENgetnodeindex(nodes[i]), 1, given_demands[i]) + +# def MonochloramineSetTemp(Temp,unit,temp_cons): +# #This function changes the temperature-dependant model constants in the +# #Monochloramine Decay model (found in Wahman 2018, developed by others) + +# if unit=='F': +# #Convert to Kelvin +# Temp_k=(Temp-32)*(5/9)+273.15 +# if unit=='C': +# #Convert to Kelvin +# Temp_k=Temp+273.15 +# if unit=='K': +# #It already is in Kelvin but change the variable name +# Temp_k=Temp + +# #Set constants based on the temperature + +# #Create a list of the acceptable constants to be varied +# temp_cons_acceptable=['k1','k2','k3','AC1','AC2','AC3','KNH4','KHOCL','KH2CO3','KHCO3','KW'] + +# #Check to make sure the constants supplied are in that list +# for k in range(len(temp_cons)): +# if temp_cons[k] not in temp_cons_acceptable: +# raise Exception('One of the supplied constant names does not exist in the model') + +# #Create a list which is the same length as temp_cons +# temp_con_val_list=[None]*len(temp_cons) + +# #Loop through each value of temp_cons and populate temp_con_val_list +# for i in range(len(temp_cons)): + +# #Formule for each temperature-dependant constant are found in Wahman 2018 + +# if temp_cons[i]=='k1': +# temp_con_val_list[i]=6.6*10**8*np.exp(-1510/Temp_k) +# if temp_cons[i]=='k2': +# temp_con_val_list[i]=1.38*10**8*np.exp(-8800/Temp_k) +# if temp_cons[i]=='k3': +# temp_con_val_list[i]=3.0*10**5*np.exp(-2010/Temp_k) +# if temp_cons[i]=='AC1': +# temp_con_val_list[i]=1.05*10**7*np.exp(-2169/Temp_k) +# if temp_cons[i]=='AC2': +# temp_con_val_list[i]=8.19*10**6*np.exp(-4026/Temp_k) +# if temp_cons[i]=='AC3': +# temp_con_val_list[i]=4.2*10**31*np.exp(-22144/Temp_k) +# if temp_cons[i]=='KNH4': +# temp_con_val_list[i]=10**-(1.03*10**-4*Temp_k**2-9.21*10**-2*Temp_k+27.6) +# if temp_cons[i]=='KHOCL': +# temp_con_val_list[i]=10**-(1.18*10**-4*Temp_k**2-7.86*10**-2*Temp_k+20.5) +# if temp_cons[i]=='KH2CO3': +# temp_con_val_list[i]=10**-(1.48*10**-4*Temp_k**2-9.39*10**-2*Temp_k+21.2) +# if temp_cons[i]=='KHCO3': +# temp_con_val_list[i]=10**-(1.19*10**-4*Temp_k**2-7.99*10**-2*Temp_k+23.6) +# if temp_cons[i]=='KW': +# temp_con_val_list[i]=10**-(1.5*10**-4*Temp_k**2-1.23*10**-1*Temp_k+37.3) + +# #Take the individual values and put them in an array +# temp_con_vals=np.array(temp_con_val_list) + +# #Set the constants in the model +# SetConstants(temp_cons,temp_con_vals) + +# def MonochloramineGetTempCon(Temp,unit,con): +# #This function changes the temperature-dependant model constants in the +# #Monochloramine Decay model (found in Wahman 2018, developed by others) + +# #Input a vector of temperatures and get a vector of the desired constant + +# if unit=='F': +# #Convert to Kelvin +# Temp_k=(Temp-32)*(5/9)+273.15 +# if unit=='C': +# #Convert to Kelvin +# Temp_k=Temp+273.15 +# if unit=='K': +# #It already is in Kelvin but change the variable name +# Temp_k=Temp + +# #Set constants based on the temperature + +# #Formule for each temperature-dependant constant are found in Wahman 2018 +# if con=='k1': +# out=6.6*10**8*np.exp(-1510/Temp_k) +# if con=='k2': +# out=1.38*10**8*np.exp(-8800/Temp_k) +# if con=='k3': +# out=3.0*10**5*np.exp(-2010/Temp_k) +# if con=='AC1': +# out=1.05*10**7*np.exp(-2169/Temp_k) +# if con=='AC2': +# out=8.19*10**6*np.exp(-4026/Temp_k) +# if con=='AC3': +# out=4.2*10**31*np.exp(-22144/Temp_k) +# if con=='KNH4': +# out=10**-(1.03*10**-4*Temp_k**2-9.21*10**-2*Temp_k+27.6) +# if con=='KHOCL': +# out=10**-(1.18*10**-4*Temp_k**2-7.86*10**-2*Temp_k+20.5) +# if con=='KH2CO3': +# out=10**-(1.48*10**-4*Temp_k**2-9.39*10**-2*Temp_k+21.2) +# if con=='KHCO3': +# out=10**-(1.19*10**-4*Temp_k**2-7.99*10**-2*Temp_k+23.6) +# if con=='KW': +# out=10**-(1.5*10**-4*Temp_k**2-1.23*10**-1*Temp_k+37.3) + +# return out + +# def GenerateNormal(problem,n_sims): +# #Takes a problem (defined by the SALib package) and generates parameters for +# #model runs based on normal distributions of each parameter where the +# #mean is the mean/median of the upper/lower bounds specified and the standard +# #deviation is set so that 2 standard deviations from the mean is the upper/lower bound +# #of the value for the specified parameter + + +# #Create an empty array of the size needed +# norm_input=np.zeros((n_sims,problem['num_vars'])) +# rng=np.random.default_rng() + +# for i in range(problem['num_vars']): + +# #Mean is the middle of the upper and lower bounds specified by the problem +# mean=problem['bounds'][i].mean() +# #The standard deviation is set so that 2 standard deviations away from the +# #mean is the upper and lower bounds of the range specified by the problem +# sigma=(problem['bounds'][i].mean()-problem['bounds'][i][0])/2 +# norm_input[:,i]=rng.normal(mean,sigma,n_sims) + +# return norm_input + +# def ScaleMatrixAll(X): +# #Scales a matrix using the min/max over all of the columns instead of by each column individually +# return (X - X.min()) / (X.max() - X.min()) + +# def KMeansBestNum(scaled_2d,clust_num_test=10): +# #Find best number of kmeans clusters +# sil=[None]*(clust_num_test-1) +# random_state=170 +# for i in range(1,clust_num_test): +# n=i+1 +# #do kmeans clustering +# y_pred = KMeans(n_clusters=n, random_state=random_state).fit_predict(scaled_2d) +# #Calculate the silhouette scores +# sil[i-1]=silhouette_score(scaled_2d,y_pred) +# #Find the index where the sil score is the highest +# z=np.where(sil==np.max(sil))[0] +# num_clust_best=z[0]+2 +# #Do the clustering one more time with that number of clusters +# y_pred = KMeans(n_clusters=num_clust_best, random_state=random_state).fit_predict(scaled_2d) +# return y_pred + +# def Network2DPlot(network,color_var,size_var,title,nodes,min_scale=30,max_scale=80,show_inds='all'): + +# #Scale Information +# mult=max_scale-min_scale +# #doing the plotting +# if show_inds=='all': +# show_inds=list(np.arange(0,len(nodes))) +# node_sizes=(ScaleMatrixAll(size_var[show_inds])*mult)+min_scale +# node_sizes=node_sizes.astype(float) +# wntr.graphics.plot_network(network, pd.Series(color_var,index=nodes)[show_inds], node_size=node_sizes,title=title) + + +# def GenerateCorrDemands(group,n,n_samples,mean_group,corr_m): + +# #Assuming the same standard deviation for all nodes +# std_all=np.ones((n_samples,1))*.1 + +# #The correlation among nodes becomes: +# corr_node=np.ones((n_samples,n_samples)) + +# #Create correlation matrix for each node +# for i in range(n_samples): +# for j in range(n_samples): +# if i!=j: +# corr_node[i,j]=corr_m[group[i],group[j]] + +# #Create array for the means to add to the results +# group_arr=np.array(group) +# mean_all=np.ones((n_samples,1)) +# for i in range(np.max(np.unique(group))+1): +# mean_all[np.where(group_arr==i)[0]]=mean_group[i] + + +# signal=[] +# for i in range(len(std_all)): +# signal.append(np.random.default_rng().normal(0,1,n)) + +# # signal=np.random.default_rng().normal(0,1,(n,2)) +# # signal01=np.random.default_rng().normal(0,1,n) +# # signal02=np.random.default_rng().normal(0,1,n) + + +# std_m = np.identity(len(std_all))*std_all + +# # calc desired covariance (vc matrix) +# cov_m = np.dot(std_m, np.dot(corr_node, std_m)) +# cky = cholesky(cov_m, lower=True) + +# corr_data = np.dot(cky,signal) +# corr_data=corr_data+mean_all + +# #Transpose output so each row is each simulation and each column is a node +# corr_data=corr_data.T +# return corr_data + +# def MorrisWallEvaluate(model_pickle,species): + +# results_model=model_pickle['results'] +# nodes=model_pickle['nodes'] +# links=model_pickle['links'] +# problem=model_pickle['problem'] +# param_values_model=model_pickle['param_values'] +# inp_file=model_pickle['inp_file'] + + + +# #Extract the number of timesteps for which the model was computed +# timesteps=len(results_model[0]['node'][nodes[0]].index) +# timesteps_index=results_model[0]['node'][nodes[0]].index + +# #Create a dictionary to store the mu_star and sigma results for the model +# morris_results={} +# morris_results['mu_star']={} +# morris_results['sigma']={} + +# morris_results['mu_star']['node']={} +# morris_results['mu_star']['link']={} + +# morris_results['sigma']['node']={} +# morris_results['sigma']['link']={} + + + +# age_results={} +# age_mean={} +# age_mean['node']=pd.DataFrame() +# age_mean['link']=pd.DataFrame() + +# for l in range(len(nodes)): +# print('Evaluating Node ' + str(l+1) + ' of ' +str(len(nodes))) +# #Compute the morris values for each parameter for each timestep of the model +# #Create an array to store the mu_star values at each timestep +# mu_star_timestep=np.zeros((timesteps,problem['num_vars'])) +# sigma_timestep=np.zeros((timesteps,problem['num_vars'])) + +# #Extract the model output results for that specific timestep +# con_out=np.zeros((len(results_model),1)) +# for j in range(timesteps): +# for i in range(len(results_model)): +# con_out[i]=results_model[i]['node'][nodes[l]].loc[timesteps_index[j],species] + +# #Compute morris results +# a=morris_a.analyze(problem,param_values_model,con_out) + +# mu_star_timestep[j,:]=a['mu_star'] +# sigma_timestep[j,:]=a['sigma'] + +# #Convert mu_star_timestep into a dataframe +# mu_star_df=pd.DataFrame(mu_star_timestep,index=timesteps_index,columns=problem['names']) +# sigma_df=pd.DataFrame(sigma_timestep,index=timesteps_index,columns=problem['names']) + +# morris_results['mu_star']['node'][nodes[l]]=mu_star_df +# morris_results['sigma']['node'][nodes[l]]=sigma_df + +# #Loop through all of the simulation results and get the average +# #water age for each timestep and each node + +# #Create a dataframe to put the results into +# age_results[nodes[l]]=pd.DataFrame() +# for i in range(len(results_model)): +# age_results[nodes[l]]['S'+str(i+1)]=results_model[i]['node'][nodes[l]]['AGE'] + +# age_mean['node'][nodes[l]]=age_results[nodes[l]].mean(axis=1) + +# for l in range(len(links)): +# print('Evaluating Link ' + str(l+1) + ' of ' + str(len(links))) +# #Compute the morris values for each parameter for each timestep of the model +# #Create an array to store the mu_star values at each timestep +# mu_star_timestep=np.zeros((timesteps,problem['num_vars'])) +# sigma_timestep=np.zeros((timesteps,problem['num_vars'])) + +# #Extract the model output results for that specific timestep +# con_out=np.zeros((len(results_model),1)) +# for j in range(timesteps): +# for i in range(len(results_model)): +# con_out[i]=results_model[i]['link'][links[l]].loc[timesteps_index[j],species] + +# #Compute morris results +# a=morris_a.analyze(problem,param_values_model,con_out) + +# mu_star_timestep[j,:]=a['mu_star'] +# sigma_timestep[j,:]=a['sigma'] + +# #Convert mu_star_timestep into a dataframe +# mu_star_df=pd.DataFrame(mu_star_timestep,index=timesteps_index,columns=problem['names']) +# sigma_df=pd.DataFrame(sigma_timestep,index=timesteps_index,columns=problem['names']) + +# morris_results['mu_star']['link'][links[l]]=mu_star_df +# morris_results['sigma']['link'][links[l]]=sigma_df + +# #Loop through all of the simulation results and get the average +# #water age for each timestep and each node + +# #Create a dataframe to put the results into +# age_results[links[l]]=pd.DataFrame() +# for i in range(len(results_model)): +# age_results[links[l]]['S'+str(i+1)]=results_model[i]['link'][links[l]]['AGE'] + +# age_mean['link'][links[l]]=age_results[links[l]].mean(axis=1) + +# return morris_results,age_mean + + + \ No newline at end of file diff --git a/wntr/quality/__init__.py b/wntr/quality/__init__.py index 7c166da59..5f7c85291 100644 --- a/wntr/quality/__init__.py +++ b/wntr/quality/__init__.py @@ -5,9 +5,26 @@ # pyomo.dae # sympy -from .base import VariableType, LocationType, DynamicsType, ReactionDynamics, ReactionVariable -from .options import MultispeciesOptions -from .variables import Species, OtherTerm, InternalVariable, BulkSpecies, WallSpecies, Parameter, Coefficient, Constant -from .dynamics import RateDynamics, FormulaDynamics, EquilibriumDynamics from ..epanet.msx.exceptions import EpanetMsxException -from .model import MultispeciesReactionModel \ No newline at end of file +from .base import ( + DynamicsType, + LocationType, + ReactionDynamics, + ReactionVariable, + VariableType, +) +from .multispecies import FormulaDynamics +from .multispecies import ( + BulkSpecies, + Coefficient, + Constant, + EquilibriumDynamics, + InternalVariable, + MultispeciesQualityModel, + OtherTerm, + Parameter, + RateDynamics, + Species, + WallSpecies, +) +from .options import MultispeciesOptions diff --git a/wntr/quality/base.py b/wntr/quality/base.py index 9d63da4fd..6dc404512 100644 --- a/wntr/quality/base.py +++ b/wntr/quality/base.py @@ -4,37 +4,19 @@ The base classes for the the wntr.reaction module. Other than the enum classes, the classes in this module are all abstract and/or mixin classes, and should not be instantiated directly. - -.. rubric:: Contents - -.. autosummary:: - - VariableType - LocationType - DynamicsType - ReactionVariable - ReactionDynamics - AbstractReactionModel - LinkedVariablesMixin - ExpressionMixin - MsxObjectMixin - MSXComment - """ import abc import enum import logging from abc import ABC, abstractmethod, abstractproperty -from dataclasses import InitVar, dataclass, field +from dataclasses import InitVar, dataclass from enum import Enum, IntFlag -from typing import ( - ClassVar, - Generator, - List, - Union, -) +from typing import ClassVar, Generator, List, Union +from wntr.network.model import WaterNetworkModel +from wntr.quality.options import MultispeciesOptions +from wntr.utils.enumtools import add_get has_sympy = False try: @@ -50,10 +32,6 @@ convert_xor = None has_sympy = False -from wntr.network.model import WaterNetworkModel -from wntr.utils.enumtools import add_get -from wntr.quality.options import MultispeciesOptions - logger = logging.getLogger(__name__) HYDRAULIC_VARIABLES = [ @@ -209,14 +187,8 @@ class DynamicsType(Enum): """Alias for :attr:`FORMULA`""" -@dataclass class ReactionVariable(ABC): """The base for a reaction variable. - - Parameters - ---------- - name : str - the name/symbol of the variable """ name: str @@ -230,6 +202,29 @@ def __hash__(self) -> int: """Makes the variable hashable by hashing the `str` representation""" return hash(str(self)) + __variable_registry = None + + @property + def _variable_registry(self) -> "AbstractQualityModel": + return self.__variable_registry + + @_variable_registry.setter + def _variable_registry(self, value): + if value is not None and not isinstance(value, AbstractQualityModel): + raise TypeError("Linked model must be a RxnModelRegistry, got {}".format(type(value))) + self.__variable_registry = value + + def validate(self): + """Validate that this object is a member of the RxnModelRegistry + + Raises + ------ + TypeError + if the model registry isn't linked + """ + if not isinstance(self._variable_registry, AbstractQualityModel): + raise TypeError("This object is not connected to any RxnModelRegistry") + @abstractproperty def var_type(self) -> VariableType: """The variable type.""" @@ -244,7 +239,7 @@ def is_species(self) -> bool: True if this is a species object, False otherwise """ return self.var_type == VariableType.BULK or self.var_type == VariableType.WALL - + def is_coeff(self) -> bool: """Check to see if this variable represents a coefficient (constant or parameter). @@ -254,7 +249,7 @@ def is_coeff(self) -> bool: True if this is a coefficient object, False otherwise """ return self.var_type == VariableType.CONST or self.var_type == VariableType.PARAM - + def is_other_term(self) -> bool: """Check to see if this variable represents a function (MSX term). @@ -270,8 +265,22 @@ def symbol(self): """Representation of the variable's name as a sympy.Symbol""" return Symbol(self.name) + def to_symbolic(self, transformations=EXPR_TRANSFORMS): + """Convert to a symbolic expression. + + Parameters + ---------- + transformations : tuple of sympy transformations + transformations to apply to the expression, by default EXPR_TRANSFORMS + + Returns + ------- + sympy.Expr + the expression parsed by sympy + """ + return self.symbol + -@dataclass class ReactionDynamics(ABC): """The base for a reaction. @@ -300,6 +309,29 @@ def __hash__(self) -> int: """Makes the reaction hashable by hashing the `str` representation""" return hash(str(self)) + __variable_registry = None + + @property + def _variable_registry(self) -> "AbstractQualityModel": + return self.__variable_registry + + @_variable_registry.setter + def _variable_registry(self, value): + if value is not None and not isinstance(value, AbstractQualityModel): + raise TypeError("Linked model must be a RxnModelRegistry, got {}".format(type(value))) + self.__variable_registry = value + + def validate(self): + """Validate that this object is a member of the RxnModelRegistry + + Raises + ------ + TypeError + if the model registry isn't linked + """ + if not isinstance(self._variable_registry, AbstractQualityModel): + raise TypeError("This object is not connected to any RxnModelRegistry") + @abstractproperty def expr_type(self) -> DynamicsType: """The type of reaction dynamics being described (or, the left-hand-side of the equation)""" @@ -325,8 +357,24 @@ def to_key(cls, species, location): location = LocationType.get(location) return str(species) + "." + location.name.lower() + @abstractmethod + def to_symbolic(self, transformations=EXPR_TRANSFORMS): + """Convert to a symbolic expression. + + Parameters + ---------- + transformations : tuple of sympy transformations + transformations to apply to the expression, by default EXPR_TRANSFORMS + + Returns + ------- + sympy.Expr + the expression parsed by sympy + """ + return parse_expr(self.expression, transformations=transformations) + -class AbstractReactionModel(ABC): +class AbstractQualityModel(ABC): @abstractmethod def variables(self, var_type=None): """Generator over all defined variables, optionally limited by variable type""" @@ -366,81 +414,3 @@ def get_reaction(self, species, location=None) -> List[ReactionDynamics]: def remove_reaction(self, species, location=None): """Remove reaction(s) for a species, optionally only for one location""" raise NotImplementedError - - -class LinkedVariablesMixin: - - __variable_registry = None - - @property - def _variable_registry(self) -> AbstractReactionModel: - return self.__variable_registry - - @_variable_registry.setter - def _variable_registry(self, value): - if value is not None and not isinstance(value, AbstractReactionModel): - raise TypeError("Linked model must be a RxnModelRegistry, got {}".format(type(value))) - self.__variable_registry = value - - def validate(self): - """Validate that this object is a member of the RxnModelRegistry - - Raises - ------ - TypeError - if the model registry isn't linked - """ - if not isinstance(self._variable_registry, AbstractReactionModel): - raise TypeError("This object is not connected to any RxnModelRegistry") - - -@dataclass -class ExpressionMixin(ABC): - """A mixin class for converting an expression to a sympy Expr""" - - @abstractmethod - def to_symbolic(self, transformations=EXPR_TRANSFORMS): - """Convert to a symbolic expression. - - Parameters - ---------- - transformations : tuple of sympy transformations - transformations to apply to the expression, by default EXPR_TRANSFORMS - - Returns - ------- - sympy.Expr - the expression parsed by sympy - """ - return parse_expr(self.expression, transformations=transformations) - - -class MsxObjectMixin: - def to_msx_string(self) -> str: - """Get the expression as an EPANET-MSX input-file style string. - - Returns - ------- - str - the expression for use in an EPANET-MSX input file - """ - raise NotImplementedError - - -@dataclass -class MSXComment: - pre: List[str] = field(default_factory=list) - post: str = None - - def wrap_msx_string(self, string) -> str: - if self.pre is None or len(self.pre) == 0: - if self.post is None: - return ' ' + string - else: - return ' ' + string + ' ; ' + self.post - elif self.post is None: - return '\n; ' + '\n\n; '.join(self.pre) + '\n\n ' + string - else: - return '\n; ' + '\n\n; '.join(self.pre) + '\n\n ' + string + ' ; ' + self.post - - diff --git a/wntr/quality/dynamics.py b/wntr/quality/dynamics.py deleted file mode 100644 index 1de155200..000000000 --- a/wntr/quality/dynamics.py +++ /dev/null @@ -1,234 +0,0 @@ -# -*- coding: utf-8 -*- - -r""" -Classes for the species reactions used in reaction models. -Defines a reaction based on the type of reaction dynamics, e.g., equilibrium -or rate-of-change. The dynamics, or ``expr_type`` determine the left-hand-side of a reaction -equation, while the ``expression`` provides the right-hand-side. - -In other words, the ``expr_type``, ``species`` and ``expression`` attributes of all -reaction class objects can be read as: - -.. math:: - - expr\_type(species) = expression(vars,...). - - -For a ``RATE`` reaction, this equates to: - -.. math:: - - \frac{d}{dt}C(species) = f(vars,...) - -The classes in this module can be created directly. However, they are more -powerful when either, a) created using API calls on a :class:`~wntr.reaction.model.WaterNetworkModel`, -or, b) linked to a :class:`~wntr.reaction.model.WaterNetworkModel` model object after creation. -This allows for expressions to be validated against the variables defined in the model. - -If :class:`sympy` is installed, then there are functions available -that will convert object instances of these classes into sympy expressions -and symbols. If the instances are linked to a model, then expressions can -be expanded, validated, and even evaluated or simplified symbolically. - -.. rubric:: Contents - -.. autosummary:: - - RateDynamics - EquilibriumDynamics - FormulaDynamics - -""" -import enum -import logging -from dataclasses import InitVar, asdict, dataclass, field -from enum import Enum, IntFlag -from typing import Any, ClassVar, Dict, List, Set, Tuple, Union -from .base import MSXComment - -has_sympy = False -try: - from sympy import Float, Symbol, init_printing, symbols - from sympy.parsing import parse_expr - from sympy.parsing.sympy_parser import convert_xor, standard_transformations - - has_sympy = True -except ImportError: - sympy = None - logging.critical("This python installation does not have SymPy installed. Certain functionality will be disabled.") - standard_transformations = (None,) - convert_xor = None - has_sympy = False - -from wntr.network.model import WaterNetworkModel -from wntr.quality.base import EXPR_TRANSFORMS, MsxObjectMixin, VariableType - -from .base import ( - ExpressionMixin, - LinkedVariablesMixin, - DynamicsType, - LocationType, - AbstractReactionModel, - ReactionDynamics, - VariableType, -) -from .variables import Coefficient, Species, OtherTerm - -logger = logging.getLogger(__name__) - - -@dataclass(repr=False) -class RateDynamics(MsxObjectMixin, LinkedVariablesMixin, ExpressionMixin, ReactionDynamics): - r"""Used to supply the equation that expresses the rate of change of the given species - with respect to time as a function of the other species in the model. - - .. math:: - - \frac{d}{dt} C(species) = expression - - - Parameters - ---------- - species : str - the name of the species whose reaction dynamics is being described - location : RxnLocationType or str - the location the reaction occurs (pipes or tanks) - expression : str - the expression for the reaction dynamics, which is the rate-of-change of the species concentration - note : str, optional - a note about this reaction - variable_registry : RxnModelRegistry, optional - a link to the remainder of the larger model - """ - note: Union[str, Dict[str, str]] = None - """A note or comment about this species reaction dynamics""" - variable_registry: InitVar[AbstractReactionModel] = field(default=None, compare=False) - """A link to the reaction model with variables""" - - def __post_init__(self, variable_registry): - self._variable_registry = variable_registry - - @property - def expr_type(self) -> DynamicsType: - return DynamicsType.RATE - - def to_symbolic(self, transformations=...): - return super().to_symbolic(transformations) - - def to_msx_string(self) -> str: - return "{:<12s} {:<8s} {:<32s}".format(self.expr_type.name.upper(), str(self.species), self.expression) - - def to_dict(self) -> dict: - rep = dict(species=self.species, expr_type=self.expr_type.name.lower(), expression=self.expression) - if isinstance(self.note, str): - rep['note'] = self.note - elif isinstance(self.note, MSXComment): - rep['note'] = asdict(self.note) if self.note.pre else self.note.post - else: - rep['note'] = None - return rep - - - -@dataclass(repr=False) -class EquilibriumDynamics(MsxObjectMixin, LinkedVariablesMixin, ExpressionMixin, ReactionDynamics): - """Used for equilibrium expressions where it is assumed that the expression supplied is being equated to zero. - - .. math:: - - 0 = expression - - - Parameters - ---------- - species : str - the name of the species whose reaction dynamics is being described - location : RxnLocationType or str - the location the reaction occurs (pipes or tanks) - expression : str - the expression for the reaction dynamics, which should equal to zero - note : str, optional - a note about this reaction - variable_registry : RxnModelRegistry, optional - a link to the remainder of the larger model - """ - - note: Union[str, Dict[str, str]] = None - """A note or comment about this species reaction dynamics""" - variable_registry: InitVar[AbstractReactionModel] = field(default=None, compare=False) - """A link to the reaction model with variables""" - - def __post_init__(self, variable_registry): - self._variable_registry = variable_registry - - @property - def expr_type(self) -> DynamicsType: - return DynamicsType.EQUIL - - def to_symbolic(self, transformations=...): - return super().to_symbolic(transformations) - - def to_msx_string(self) -> str: - return "{:<12s} {:<8s} {:<32s}".format(self.expr_type.name.upper(), str(self.species), self.expression) - - def to_dict(self) -> dict: - rep = dict(species=self.species, expr_type=self.expr_type.name.lower(), expression=self.expression) - if isinstance(self.note, str): - rep['note'] = self.note - elif isinstance(self.note, MSXComment): - rep['note'] = asdict(self.note) if self.note.pre else self.note.post - else: - rep['note'] = None - return rep - - -@dataclass(repr=False) -class FormulaDynamics(MsxObjectMixin, LinkedVariablesMixin, ExpressionMixin, ReactionDynamics): - """Used when the concentration of the named species is a simple function of the remaining species. - - .. math:: - - C(species) = expression - - - Parameters - ---------- - species : str - the name of the species whose reaction dynamics is being described - location : RxnLocationType or str - the location the reaction occurs (pipes or tanks) - expression : str - the expression for the reaction formula, which is used to calculate the concentration of the species - note : str, optional - a note about this reaction - variable_registry : RxnModelRegistry, optional - a link to the remainder of the larger model - """ - - note: Union[str, Dict[str, str]] = None - """A note or comment about this species reaction dynamics""" - variable_registry: InitVar[AbstractReactionModel] = field(default=None, compare=False) - """A link to the reaction model with variables""" - - def __post_init__(self, variable_registry): - self._variable_registry = variable_registry - - @property - def expr_type(self) -> DynamicsType: - return DynamicsType.FORMULA - - def to_symbolic(self, transformations=...): - return super().to_symbolic(transformations) - - def to_msx_string(self) -> str: - return "{:<12s} {:<8s} {:<32s}".format(self.expr_type.name.upper(), str(self.species), self.expression) - - def to_dict(self) -> dict: - rep = dict(species=self.species, expr_type=self.expr_type.name.lower(), expression=self.expression) - if isinstance(self.note, str): - rep['note'] = self.note - elif isinstance(self.note, MSXComment): - rep['note'] = asdict(self.note) if self.note.pre else self.note.post - else: - rep['note'] = None - return rep diff --git a/wntr/quality/io.py b/wntr/quality/io.py index 9949293de..a0ad77e76 100644 --- a/wntr/quality/io.py +++ b/wntr/quality/io.py @@ -1,13 +1,6 @@ # coding: utf-8 """Mulispecies reaction model I/O functions. -.. rubric:: Contents - -.. autosummary:: - - to_dict - from_dict - """ import wntr.epanet.msx @@ -17,6 +10,7 @@ def to_dict(msx): + """Convert a multispecies reaction model to a dictionary representation""" from wntr import __version__ rep = dict( version="wntr-{}".format(__version__), @@ -43,3 +37,6 @@ def to_dict(msx): # for node, source in v.items(): # rep["sources"][sp][node] = source.to_dict() return rep + +def from_dict(d): + raise NotImplementedError \ No newline at end of file diff --git a/wntr/quality/library.py b/wntr/quality/library.py index 57abef32c..96bf00d5a 100644 --- a/wntr/quality/library.py +++ b/wntr/quality/library.py @@ -10,30 +10,24 @@ models - that is, sources, pipes, nodes are for a given network, and must be updated for different models. -.. autosummary:: - - nicotine - nicotine_ri - lead_ppm - """ import logging from wntr.utils.citations import Citation -from wntr.quality.model import MultispeciesReactionModel +from wntr.quality.multispecies import MultispeciesQualityModel logger = logging.getLogger(__name__) # ===================== Nicotine-chlorine model # -def nicotine() -> MultispeciesReactionModel: +def nicotine() -> MultispeciesQualityModel: """A nicotine-chlorine reaction model""" - msx = MultispeciesReactionModel() + msx = MultispeciesQualityModel() msx.name = "nicotine" msx.title = ("Nicotine - Chlorine reaction",) - msx.options.quality.area_units = "M2" - msx.options.quality.rate_units = "MIN" - msx.options.quality.timestep = 1 + msx.options.area_units = "M2" + msx.options.rate_units = "MIN" + msx.options.timestep = 1 msx.add_bulk_species("Nx", units="MG", note="Nicotine") msx.add_bulk_species("HOCL", units="MG", note="Free chlorine") msx.add_constant_coeff("kd", global_value=2.33e-3, units="min^(-1)", note="decay rate") @@ -47,19 +41,20 @@ def nicotine() -> MultispeciesReactionModel: msx.add_tank_reaction("HOCL", "rate", "0") return msx + # ===================== Nicotine-chlorine reactive intermediate species # -def nicotine_ri() -> MultispeciesReactionModel: +def nicotine_ri() -> MultispeciesQualityModel: """A nicotine-chlorine reaction with a reactive intermediate""" - msx = MultispeciesReactionModel() - msx.name = 'nicotine_ri' + msx = MultispeciesQualityModel() + msx.name = "nicotine_ri" msx.title = ("Nicotine - Chlorine reaction with reactive intermediate",) # Set the options - msx.options.quality.area_units = "M2" - msx.options.quality.rate_units = "MIN" - msx.options.quality.timestep = 1 - msx.options.quality.atol = 1.0e-10 - msx.options.quality.rtol = 1.0e-10 + msx.options.area_units = "M2" + msx.options.rate_units = "MIN" + msx.options.timestep = 1 + msx.options.atol = 1.0e-10 + msx.options.rtol = 1.0e-10 # Add species msx.add_bulk_species("Nx", units="MG", note="Nicotine") msx.add_bulk_species("HOCL", units="MG", note="Free Chlorine") @@ -84,21 +79,21 @@ def nicotine_ri() -> MultispeciesReactionModel: msx.add_tank_reaction("NX2", "RATE", expression="RXNX2") return msx + # ===================== Lead plumbosolvency model # -def lead_ppm() -> MultispeciesReactionModel: +def lead_ppm() -> MultispeciesQualityModel: """A lead plumbosolvency model [BWMS20]_. .. [BWMS20] - J. B. Burkhardt, et al. (2020) - "Framework for Modeling Lead in Premise Plumbing Systems Using EPANET". - `Journal of water resources planning and management`. - **146** (12). - https://doi.org/10.1061/(asce)wr.1943-5452.0001304 + J. B. Burkhardt, et al. (2020) + "Framework for Modeling Lead in Premise Plumbing Systems Using EPANET". + `Journal of water resources planning and management`. + **146** (12). https://doi.org/10.1061/(asce)wr.1943-5452.0001304 """ - msx = MultispeciesReactionModel() - msx.name = 'lead_ppm' + msx = MultispeciesQualityModel() + msx.name = "lead_ppm" msx.title = "Lead Plumbosolvency Model (from Burkhardt et al 2020)" msx.desc = "Parameters for EPA HPS Simulator Model" msx.citations.append( @@ -138,13 +133,11 @@ def lead_ppm() -> MultispeciesReactionModel: "nodes": "all", "links": "all", }, - "quality": { - "timestep": 1, - "area_units": "M2", - "rate_units": "SEC", - "rtol": 1e-08, - "atol": 1e-08, - }, + "timestep": 1, + "area_units": "M2", + "rate_units": "SEC", + "rtol": 1e-08, + "atol": 1e-08, } msx.add_bulk_species("PB2", "ug", note="dissolved lead (Pb)") msx.add_constant_coeff("M", global_value=0.117, note="Desorption rate (ug/m^2/s)", units="ug * m^(-1) * s^(-1)") @@ -152,4 +145,4 @@ def lead_ppm() -> MultispeciesReactionModel: msx.add_parameterized_coeff("F", global_value=0, note="determines which pipes have reactions") msx.add_pipe_reaction("PB2", "RATE", expression="F*Av*M*(E - PB2)/E") msx.add_tank_reaction("PB2", "RATE", expression="0") - return msx \ No newline at end of file + return msx diff --git a/wntr/quality/model.py b/wntr/quality/multispecies.py similarity index 56% rename from wntr/quality/model.py rename to wntr/quality/multispecies.py index 2a361a479..36d9f106c 100644 --- a/wntr/quality/model.py +++ b/wntr/quality/multispecies.py @@ -1,15 +1,11 @@ # -*- coding: utf-8 -*- """ -Water quality reactions model. - -.. rubric:: Contents - -.. autosummary:: - - MultispeciesReactionModel +Multispecies water quality model and elements. +This module contains concrete instantiations of the abstract classes described in :class:`wntr.quality.base`. """ +import enum import logging import warnings from collections.abc import MutableMapping @@ -29,9 +25,27 @@ Union, ) +import wntr.quality.io +from wntr.epanet.util import ENcomment from wntr.network.elements import Source +from wntr.network.model import WaterNetworkModel +from wntr.utils.citations import Citation from wntr.utils.disjoint_mapping import DisjointMapping, KeyExistsError +from .base import ( + EXPR_TRANSFORMS, + HYDRAULIC_VARIABLES, + RESERVED_NAMES, + SYMPY_RESERVED, + AbstractQualityModel, + DynamicsType, + LocationType, + ReactionDynamics, + ReactionVariable, + VariableType, +) +from .options import MultispeciesOptions + has_sympy = False try: from sympy import Float, Symbol, init_printing, symbols @@ -46,50 +60,610 @@ convert_xor = None has_sympy = False -import wntr.quality.io -from wntr.network.model import WaterNetworkModel -from wntr.utils.citations import Citation - -from .base import ( - HYDRAULIC_VARIABLES, - SYMPY_RESERVED, - DynamicsType, - LinkedVariablesMixin, - LocationType, - ReactionDynamics, - AbstractReactionModel, - ReactionVariable, - VariableType, -) -from .dynamics import EquilibriumDynamics, FormulaDynamics, RateDynamics -from .options import MultispeciesOptions -from .variables import ( - BulkSpecies, - Coefficient, - Constant, - InternalVariable, - OtherTerm, - Parameter, - Species, - WallSpecies, -) logger = logging.getLogger(__name__) -__all__ = ["MultispeciesReactionModel"] + +class Species(ReactionVariable): + def __init__( + self, + name: str, + units: str, + atol: float = None, + rtol: float = None, + note: Union[str, Dict[str, str]] = None, + diffusivity: float = None, + *, + _qm: AbstractQualityModel = None, + ): + """A species in a multispecies water quality model. + + Parameters + ---------- + name : str + The name (symbol) for the variable, must be a valid MSX name + units : str + The units used for this species + atol : float, optional + The absolute tolerance to use when solving for this species, by default None + rtol : float, optional + The relative tolerance to use when solving for this species, by default None + note : str or dict, optional + A note about this species, by default None + diffusivity : float, optional + The diffusivity value for this species, by default None + + Keyword Args + ------------ + _qm : AbstractQualityModel, optional, keyword-only + the model this variable is being added to, by default None + + Raises + ------ + ValueError + if ``name`` is a reserved name + """ + if name in RESERVED_NAMES: + raise ValueError("Name cannot be a reserved name") + self.name = name + """The name (symbol) for the variable, must be a valid MSX name""" + self.units = units + """The units used for this species""" + self.note = note + """A note about this species, by default None""" + self.diffusivity = diffusivity + """The diffusivity value for this species, by default None""" + if atol is not None: + atol = float(atol) + if rtol is not None: + rtol = float(rtol) + if (atol is None) ^ (rtol is None): + raise TypeError("atol and rtol must be the same type, got {} and {}".format(atol, rtol)) + self._atol = atol + self._rtol = rtol + self._variable_registry = _qm + + def __repr__(self): + return "{}(name={}, unit={}, atol={}, rtol={}, note={})".format(self.__class__.__name__, repr(self.name), repr(self.units), self._atol, self._rtol, repr(self.note)) + + def __eq__(self, other): + return ( + isinstance(other, self.__class__) + and self.name == other.name + and self.units == other.units + and self.diffusivity == other.diffusivity + and self._atol == other._atol + and self._rtol == other._rtol + ) + + def get_tolerances(self) -> Tuple[float, float]: + """Get the species-specific solver tolerances. + + Returns + ------- + two-tuple or None + the absolute and relative tolerances, or None if the global values should be used + """ + if self._atol is not None and self._rtol is not None: + return (self._atol, self._rtol) + return None + + def set_tolerances(self, absolute: float, relative: float): + """Set the species-specific solver tolerances. Using ``None`` for both will + clear the tolerances, though using :func:`clear_tolerances` is clearer code. + + Parameters + ---------- + absolute : float + the absolute solver tolerance + relative : float + the relative solver tolerance + + Raises + ------ + TypeError + if both absolute and relative are not the same type + ValueError + if either value is less-than-or-equal-to zero + """ + if absolute is None and relative is None: + self._atol = self._rtol = None + return + try: + if not isinstance(absolute, float): + absolute = float(absolute) + if not isinstance(relative, float): + relative = float(relative) + except Exception as e: + raise TypeError("absolute and relative must be the same type, got {} and {}".format(absolute, relative)) + if absolute <= 0: + raise ValueError("Absolute tolerance must be greater than 0") + if relative <= 0: + raise ValueError("Relative tolerance must be greater than 0") + self._atol = absolute + self._rtol = relative + + def clear_tolerances(self): + """Resets both tolerances to ``None`` to use the global values.""" + self._atol = self._rtol = None + + def to_dict(self): + rep = dict(name=self.name, unist=self.units) + tols = self.get_tolerances() + if tols is not None: + rep["atol"] = tols[0] + rep["rtol"] = tols[1] + rep["diffusivity"] = self.diffusivity + if isinstance(self.note, str): + rep["note"] = self.note + elif isinstance(self.note, ENcomment): + rep["note"] = asdict(self.note) if self.note.pre else self.note.post + else: + rep["note"] = None + return rep -class MultispeciesReactionModel(AbstractReactionModel): - """Water quality reactions model object. +class BulkSpecies(Species): + """A bulk species.""" + + @property + def var_type(self) -> VariableType: + return VariableType.BULK + + +class WallSpecies(Species): + """A wall species""" + + @property + def var_type(self) -> VariableType: + return VariableType.WALL + + +class Coefficient(ReactionVariable): + def __init__(self, name: str, global_value: float, note: Union[str, Dict[str, str]] = None, units: str = None, *, _qm: AbstractQualityModel = None): + """A coefficient, either constant or parameterized by pipe or tank, that is used in reaction expressions. + + Parameters + ---------- + name : str + the name/symbol of the coefficient + global_value : float + the global value for the coefficient + note : Union[str, Dict[str, str]], optional + a note for this variable, by default None + units : str, optional + units for this coefficient, by default None + + Keyword Args + ------------ + _qm : AbstractQualityModel, optional, keyword-only + the model this variable is being added to, by default None + + Raises + ------ + ValueError + if ``name`` is a reserved name + """ + + if name in RESERVED_NAMES: + raise ValueError("Name cannot be a reserved name") + self.name = name + """The name (symbol) for the variable, must be a valid MSX name""" + self.global_value = float(global_value) + """The global value for the coefficient""" + self.note = note + """A note about this species, by default None""" + self.units = units + """The units used for this species""" + self._variable_registry = _qm + + def __repr__(self): + return "{}(name={}, global_value={}, units={}, note={})".format(self.__class__.__name__, repr(self.name), repr(self.global_value), repr(self.units), repr(self.note)) + + def __eq__(self, other): + return isinstance(other, self.__class__) and self.name == other.name and self.global_value == other.global_value and self.units == other.units + + def get_value(self) -> float: + """Get the value of the coefficient + + Returns + ------- + float + the global value + """ + return self.global_value + + def to_dict(self): + rep = dict(name=self.name, global_value=self.global_value, units=self.units) + if isinstance(self.note, str): + rep["note"] = self.note + elif isinstance(self.note, ENcomment): + rep["note"] = asdict(self.note) if self.note.pre else self.note.post + else: + rep["note"] = None + return rep + + +class Constant(Coefficient): + """A constant coefficient for reaction expressions.""" + + @property + def var_type(self) -> VariableType: + return VariableType.CONST + + +class Parameter(Coefficient): + """A variable parameter for reaction expressions.""" + + def __init__( + self, + name: str, + global_value: float, + note: Union[str, Dict[str, str]] = None, + units: str = None, + pipe_values: Dict[str, float] = None, + tank_values: Dict[str, float] = None, + *, + _qm: AbstractQualityModel = None, + ): + """A coefficient, either constant or parameterized by pipe or tank, that is used in reaction expressions. + + Parameters + ---------- + name : str + the name/symbol of the coefficient + global_value : float + the global value for the coefficient + note : Union[str, Dict[str, str]], optional + a note for this variable, by default None + units : str, optional + units for this coefficient, by default None + pipe_values : dict, optional + the values of the parameter at specific pipes, by default None + tank_values : dict, optional + the values of the parameter at specific tanks, by default None + + Keyword Args + ------------ + _qm : AbstractQualityModel, optional, keyword-only + the model this variable is being added to, by default None + + Raises + ------ + ValueError + if ``name`` is a reserved name + """ + super().__init__(name, global_value=global_value, note=note, units=units, _qm=_qm) + self._pipe_values = pipe_values if pipe_values is not None else dict() + """A dictionary of parameter values for various pipes""" + self._tank_values = tank_values if tank_values is not None else dict() + """A dictionary of parameter values for various tanks""" + + def __eq__(self, other): + basic = isinstance(other, self.__class__) and self.name == other.name and self.global_value == other.global_value and self.units == other.units + if not basic: + return False + for k, v in self._pipe_values: + if other._pipe_values[k] != v: + return False + for k, v in self._tank_values: + if other._tank_values[k] != v: + return False + return True + + @property + def var_type(self) -> VariableType: + return VariableType.PARAM + + def get_value(self, pipe: str = None, tank: str = None) -> float: + """Get the value of the parameter, either globally or for a specific pipe or tank. + + Parameters + ---------- + pipe : str, optional + a pipe to get the value for, by default None + tank : str, optional + a tank to get the value for, by default None + + Returns + ------- + float + either a specific parameter value for the specified pipe or tank, or the global value + if nothing is specified OR if the pipe or tank requested does not have a special value. + + Raises + ------ + TypeError + if both pipe and tank are specified + """ + if pipe is not None and tank is not None: + raise TypeError("Cannot get a value for a pipe and tank at the same time - one or both must be None") + if pipe is not None: + return self._pipe_values.get(pipe, self.global_value) + if tank is not None: + return self._tank_values.get(tank, self.global_value) + return self.global_value + + @property + def pipe_values(self) -> Dict[str, float]: + """A dictionary of values, iff different from the global value, for specific pipes""" + return self._pipe_values + + @property + def tank_values(self) -> Dict[str, float]: + """A dictionary of values, iff different from the global value, for specific tanks""" + return self._tank_values + + def to_dict(self): + rep = super().to_dict() + rep["pipe_values"] = self._pipe_values.copy() + rep["tank_values"] = self._tank_values.copy() + return rep + + +@dataclass(repr=False) +class OtherTerm(ReactionVariable): + """A function definition used as a shortcut in reaction expressions (called a 'term' in EPANET-MSX) Parameters ---------- - msx_file_name : str, optional - The name of the MSX input file to read + name : str + the name/symbol of the function (term) + expression : str + the mathematical expression described by this function + note : str, optional + a note for this function, by default None + + Keyword Args + ------------ + _qm : AbstractQualityModel, optional, keyword-only + the model this variable is being added to, by default None + """ + + def __init__( + self, + name: str, + expression: str, + note: Union[str, Dict[str, str]] = None, + *, + _qm: AbstractQualityModel = None, + ): + if name in RESERVED_NAMES: + raise ValueError("Name cannot be a reserved name") + self.name = name + """The name (symbol) for the variable, must be a valid MSX name""" + self.expression = expression + """The expression this named-function is equivalent to""" + self.note = note + """A note about this function/term""" + self._variable_registry = _qm + + def __repr__(self): + return "{}(name={}, expression={}, note={})".format(self.__class__.__name__, repr(self.name), repr(self.expression), repr(self.note)) + + def __eq__(self, other): + return isinstance(other, self.__class__) and self.name == other.name and self.expression == other.expression + + @property + def var_type(self) -> VariableType: + return VariableType.TERM + + def to_symbolic(self, transformations=...): + return super().to_symbolic(transformations) + + def to_dict(self): + rep = dict(name=self.name, expression=self.expression) + if isinstance(self.note, str): + rep["note"] = self.note + elif isinstance(self.note, ENcomment): + rep["note"] = asdict(self.note) if self.note.pre else self.note.post + else: + rep["note"] = None + return rep + + +@dataclass(repr=False) +class InternalVariable(ReactionVariable): + """A hydraulic variable or a placeholder for a built-in reserved word. + + For example, "Len" is the EPANET-MSX name for the length of a pipe, and "I" is a sympy + reserved symbol for the imaginary number.""" + + def __init__( + self, + name: str, + note: Union[str, Dict[str, str]] = "internal variable - not output to MSX", + units: str = None, + ): + self.name = name + """The name (symbol) for the variable, must be a valid MSX name""" + self.note = note + """A note about this function/term""" + self.units = units + """The units used for this species""" + + def __repr__(self): + return "{}(name={}, note={}, units={})".format(self.__class__.__name__, repr(self.name), repr(self.note), repr(self.units)) + + def __eq__(self, other): + return isinstance(other, self.__class__) and self.name == other.name + @property + def var_type(self) -> VariableType: + return VariableType.INTERNAL + + +@dataclass(repr=False) +class RateDynamics(ReactionDynamics): + r"""A rate-of-change reaction dynamics expression. + + Used to supply the equation that expresses the rate of change of the given species + with respect to time as a function of the other species in the model. + + .. math:: + + \frac{d}{dt} C(species) = expression + + Parameters + ---------- + species : str + the name of the species whose reaction dynamics is being described + location : RxnLocationType or str + the location the reaction occurs (pipes or tanks) + expression : str + the expression for the reaction dynamics, which is the rate-of-change of the species concentration + note : str, optional + a note about this reaction + + Keyword Args + ------------ + _qm : AbstractQualityModel, optional, keyword-only + the model this variable is being added to, by default None + """ + + def __init__(self, species: str, location: LocationType, expression: str, note: Union[str, Dict[str, str]] = None, *, _qm: AbstractQualityModel = None): + self.species = species + self.location = location + self.expression = expression + self.note = note + """A note or comment about this species reaction dynamics""" + self._variable_registry = _qm + + @property + def expr_type(self) -> DynamicsType: + return DynamicsType.RATE + + def to_symbolic(self, transformations=...): + return super().to_symbolic(transformations) + + def to_dict(self) -> dict: + rep = dict(species=self.species, expr_type=self.expr_type.name.lower(), expression=self.expression) + if isinstance(self.note, str): + rep["note"] = self.note + elif isinstance(self.note, ENcomment): + rep["note"] = asdict(self.note) if self.note.pre else self.note.post + else: + rep["note"] = None + return rep + + +@dataclass(repr=False) +class EquilibriumDynamics(ReactionDynamics): + """An equilibrium reaction expression. + + Used for equilibrium expressions where it is assumed that the expression supplied is being equated to zero. + + .. math:: + + 0 = expression + + Parameters + ---------- + species : str + the name of the species whose reaction dynamics is being described + location : RxnLocationType or str + the location the reaction occurs (pipes or tanks) + expression : str + the expression for the reaction dynamics, which should equal to zero + note : str, optional + a note about this reaction + + Keyword Args + ------------ + _qm : AbstractQualityModel, optional, keyword-only + the model this variable is being added to, by default None + + """ + + def __init__(self, species: str, location: LocationType, expression: str, note: Union[str, Dict[str, str]] = None, *, _qm: AbstractQualityModel = None): + self.species = species + self.location = location + self.expression = expression + self.note = note + """A note or comment about this species reaction dynamics""" + self._variable_registry = _qm + + @property + def expr_type(self) -> DynamicsType: + return DynamicsType.EQUIL + + def to_symbolic(self, transformations=...): + return super().to_symbolic(transformations) + + def to_dict(self) -> dict: + rep = dict(species=self.species, expr_type=self.expr_type.name.lower(), expression=self.expression) + if isinstance(self.note, str): + rep["note"] = self.note + elif isinstance(self.note, ENcomment): + rep["note"] = asdict(self.note) if self.note.pre else self.note.post + else: + rep["note"] = None + return rep + + +@dataclass(repr=False) +class FormulaDynamics(ReactionDynamics): + """A formula based reaction dynamics. + + Used when the concentration of the named species is a simple function of the remaining species. + + .. math:: + + C(species) = expression + + Parameters + ---------- + species : str + the name of the species whose reaction dynamics is being described + location : RxnLocationType or str + the location the reaction occurs (pipes or tanks) + expression : str + the expression for the reaction formula, which is used to calculate the concentration of the species + note : str, optional + a note about this reaction + + Keyword Args + ------------ + _qm : RxnModelRegistry, optional + a link to the remainder of the larger model """ + def __init__(self, species: str, location: LocationType, expression: str, note: Union[str, Dict[str, str]] = None, *, _qm: AbstractQualityModel = None): + self.species = species + self.location = location + self.expression = expression + self.note = note + """A note or comment about this species reaction dynamics""" + self._variable_registry = _qm + + @property + def expr_type(self) -> DynamicsType: + return DynamicsType.FORMULA + + def to_symbolic(self, transformations=...): + return super().to_symbolic(transformations) + + def to_dict(self) -> dict: + rep = dict(species=self.species, expr_type=self.expr_type.name.lower(), expression=self.expression) + if isinstance(self.note, str): + rep["note"] = self.note + elif isinstance(self.note, ENcomment): + rep["note"] = asdict(self.note) if self.note.pre else self.note.post + else: + rep["note"] = None + return rep + + +class MultispeciesQualityModel(AbstractQualityModel): def __init__(self, msx_file_name=None): + """Water quality reactions model object. + + Parameters + ---------- + msx_file_name : str, optional + The name of the MSX input file to read + + """ self.name: str = None """A one-line title for the model""" @@ -245,7 +819,7 @@ def add_variable(self, var_or_type: Union[ReactionVariable, VariableType], name: raise KeyExistsError("A variable with this name already exists in the model") typ = __variable.var_type name = __variable.name - if isinstance(__variable, LinkedVariablesMixin): + if hasattr(__variable, "_variable_registry"): __variable._variable_registry = self if typ is VariableType.BULK or typ is VariableType.WALL: self._variables.add_item_to_group("species", name, __variable) @@ -307,9 +881,9 @@ def add_species( if (atol is None) ^ (rtol is None): raise TypeError("atol and rtol must be the same type, got {} and {}".format(atol, rtol)) if species_type is VariableType.BULK: - var = BulkSpecies(name=name, units=units, atol=atol, rtol=rtol, note=note, variable_registry=self) + var = BulkSpecies(name=name, units=units, atol=atol, rtol=rtol, note=note, _qm=self) elif species_type is VariableType.WALL: - var = WallSpecies(name=name, units=units, atol=atol, rtol=rtol, note=note, variable_registry=self) + var = WallSpecies(name=name, units=units, atol=atol, rtol=rtol, note=note, _qm=self) self._species[name] = var self._inital_quality[name] = dict([("global", None), ("nodes", dict()), ("links", dict())]) self._sources[name] = dict() @@ -416,9 +990,9 @@ def add_coefficient( if self._is_variable_registered(name): raise KeyExistsError("The variable {} already exists in this model".format(name)) if coeff_type is VariableType.CONST: - var = Constant(name=name, global_value=global_value, note=note, units=units, variable_registry=self) + var = Constant(name=name, global_value=global_value, note=note, units=units, _qm=self) elif coeff_type is VariableType.PARAM: - var = Parameter(name=name, global_value=global_value, note=note, units=units, variable_registry=self, **kwargs) + var = Parameter(name=name, global_value=global_value, note=note, units=units, _qm=self, **kwargs) self._coeffs[name] = var return var @@ -486,7 +1060,7 @@ def add_parameterized_coeff( VariableNameExistsError if a variable with this name already exists in the model """ - return self.add_coefficient(VariableType.PARAM, name=name, global_value=global_value, note=note, units=units, _pipe_values=pipe_values, _tank_values=tank_values) + return self.add_coefficient(VariableType.PARAM, name=name, global_value=global_value, note=note, units=units, pipe_values=pipe_values, tank_values=tank_values) def add_other_term(self, name: str, expression: str, note: str = None) -> OtherTerm: """Add a new user-defined function to the model. @@ -516,7 +1090,7 @@ def add_other_term(self, name: str, expression: str, note: str = None) -> OtherT """ if self._is_variable_registered(name): raise KeyExistsError("The variable {} already exists in this model".format(name)) - var = OtherTerm(name=name, expression=expression, note=note, variable_registry=self) + var = OtherTerm(name=name, expression=expression, note=note, _qm=self) self._terms[name] = var return var @@ -536,7 +1110,7 @@ def remove_variable(self, name: str): def get_variable(self, name: str) -> ReactionVariable: """Get a variable based on its name (symbol). - + Parameters ---------- name : str @@ -616,11 +1190,11 @@ def add_reaction(self, location: LocationType, species: Union[str, Species], dyn dynamics = DynamicsType.get(dynamics) new = None if dynamics is DynamicsType.EQUIL: - new = EquilibriumDynamics(species=species, location=location, expression=expression, note=note, variable_registry=self) + new = EquilibriumDynamics(species=species, location=location, expression=expression, note=note, _qm=self) elif dynamics is DynamicsType.RATE: - new = RateDynamics(species=species, location=location, expression=expression, note=note, variable_registry=self) + new = RateDynamics(species=species, location=location, expression=expression, note=note, _qm=self) elif dynamics is DynamicsType.FORMULA: - new = FormulaDynamics(species=species, location=location, expression=expression, note=note, variable_registry=self) + new = FormulaDynamics(species=species, location=location, expression=expression, note=note, _qm=self) else: raise ValueError("Invalid dynamics type, {}".format(dynamics)) if location is LocationType.PIPE: diff --git a/wntr/quality/options.py b/wntr/quality/options.py index 1f113f52e..00656d325 100644 --- a/wntr/quality/options.py +++ b/wntr/quality/options.py @@ -11,11 +11,68 @@ logger = logging.getLogger(__name__) +class ReportOptions(_OptionsBase): + """ + Options related to EPANET-MSX report outputs. + + Parameters + ---------- + report_filename : str + Provides the filename to use for outputting an EPANET report file, + by default this will be the prefix plus ".rpt". + + species : dict[str, bool] + Output species concentrations + + species_precision : dict[str, float] + Output species concentrations with the specified precision + + nodes : None, "ALL", or list + Output node information in report file. If a list of node names is provided, + EPANET only provides report information for those nodes. + + links : None, "ALL", or list + Output link information in report file. If a list of link names is provided, + EPANET only provides report information for those links. + + pagesize : str + Page size for EPANET report output + + + """ + + def __init__( + self, + pagesize: list = None, + report_filename: str = None, + species: Dict[str, bool] = None, + species_precision: Dict[str, float] = None, + nodes: Union[Literal["ALL"], List[str]] = None, + links: Union[Literal["ALL"], List[str]] = None, + ): + self.pagesize = pagesize + """The pagesize for the report""" + self.report_filename = report_filename + """The prefix of the report filename (will add .rpt)""" + self.species = species if species is not None else dict() + """Turn individual species outputs on and off, by default no species are output""" + self.species_precision = species_precision if species_precision is not None else dict() + """Set the output precision for the concentration of a specific species""" + self.nodes = nodes + """A list of nodes to print output for, or 'ALL' for all nodes, by default None""" + self.links = links + """A list of links to print output for, or 'ALL' for all links, by default None""" -class QualityOptions(_OptionsBase): + def __setattr__(self, name, value): + if name not in ["pagesize", "report_filename", "species", "nodes", "links", "species_precision"]: + raise AttributeError("%s is not a valid attribute of ReportOptions" % name) + self.__dict__[name] = value + + + +class MultispeciesOptions(_OptionsBase): """ - Options related to water quality modeling. These options come from - the "[OPTIONS]" section of an EPANET-MSX input file. + Multispecies quality model options. Parameters ---------- @@ -48,6 +105,10 @@ class QualityOptions(_OptionsBase): peclet : int, optional Peclet threshold for applying dispersion (MSX 2.0 or newer only), by default 1000. + + report : ReportOptions + Contains options for how for format and save report + """ def __init__( @@ -62,7 +123,8 @@ def __init__( compiler: str = "NONE", segments: int = 5000, peclet: int = 1000, - global_initial_quality: Dict[str, float] = None + global_initial_quality: Dict[str, float] = None, + report: ReportOptions = None, ): self.timestep = timestep """The timestep, in seconds, by default 360""" @@ -84,9 +146,14 @@ def __init__( """The number of segments per-pipe to use, by default 5000.""" self.peclet = peclet """The threshold for applying dispersion, by default 1000.""" + self.report = ReportOptions.factory(report) def __setattr__(self, name, value): - if name in {"timestep"}: + if name == "report": + if not isinstance(value, (ReportOptions, dict, tuple, list)): + raise ValueError("report must be a ReportOptions or convertable object") + value = ReportOptions.factory(value) + elif name in {"timestep"}: try: value = max(1, int(value)) except ValueError: @@ -102,129 +169,7 @@ def __setattr__(self, name, value): except ValueError: raise ValueError("%s must be a number", name) elif name not in ["area_units", "rate_units", "solver", "coupling", "compiler"]: - raise AttributeError("%s is not a valid attribute of QualityOptions" % name) - self.__dict__[name] = value - - -class ReportOptions(_OptionsBase): - """ - Options related to EPANET report outputs. - The values in this options class *do not* affect the behavior of the WNTRSimulator. - These only affect what is written to an EPANET INP file and the results that are - in the EPANET-created report file. - - Parameters - ---------- - report_filename : str - Provides the filename to use for outputting an EPANET report file, - by default this will be the prefix plus ".rpt". - - species : dict[str, bool] - Output species concentrations - - species_precision : dict[str, float] - Output species concentrations with the specified precision - - nodes : None, "ALL", or list - Output node information in report file. If a list of node names is provided, - EPANET only provides report information for those nodes. - - links : None, "ALL", or list - Output link information in report file. If a list of link names is provided, - EPANET only provides report information for those links. - - pagesize : str - Page size for EPANET report output - - - """ - - def __init__( - self, - pagesize: list = None, - report_filename: str = None, - species: Dict[str, bool] = None, - species_precision: Dict[str, float] = None, - nodes: Union[Literal['ALL'], List[str]] = None, - links: Union[Literal['ALL'], List[str]] = None, - ): - self.pagesize = pagesize - """The pagesize for the report""" - self.report_filename = report_filename - """The prefix of the report filename (will add .rpt)""" - self.species = species if species is not None else dict() - """Turn individual species outputs on and off, by default no species are output""" - self.species_precision = species_precision if species_precision is not None else dict() - """Set the output precision for the concentration of a specific species""" - self.nodes = nodes - """A list of nodes to print output for, or 'ALL' for all nodes, by default None""" - self.links = links - """A list of links to print output for, or 'ALL' for all links, by default None""" - - def __setattr__(self, name, value): - if name not in ["pagesize", "report_filename", "species", "nodes", "links", "species_precision"]: - raise AttributeError("%s is not a valid attribute of ReportOptions" % name) - self.__dict__[name] = value - - -class UserOptions(_OptionsBase): - """ - Options defined by the user. - - Provides an empty class that accepts getattribute and setattribute methods to - create user-defined options. For example, if using WNTR for uncertainty - quantification, certain options could be added here that would never be - used directly by WNTR, but which would be saved on pickling and could be - used by the user-built analysis scripts. - - """ - - def __init__(self, **kwargs): - for k, v in kwargs.items(): - self.__dict__[k] = v - - -class MultispeciesOptions(_OptionsBase): - """ - Water network model options class. - - These options mimic options in EPANET. - The `user` attribute is a generic python class object that allows for - dynamically created attributes that are user specific. - - Parameters - ---------- - quality : QualityOptions - Contains water quality simulation options and source definitions - - report : ReportOptions - Contains options for how for format and save report - - user : dict - An empty dictionary that allows for user specified options - - - """ - - def __init__(self, report: ReportOptions = None, quality: QualityOptions = None, user: UserOptions = None): - self.report = ReportOptions.factory(report) - self.quality = QualityOptions.factory(quality) - self.user = UserOptions.factory(user) - - def __setattr__(self, name, value): - if name == "report": - if not isinstance(value, (ReportOptions, dict, tuple, list)): - raise ValueError("report must be a ReportOptions or convertable object") - value = ReportOptions.factory(value) - elif name == "quality": - if not isinstance(value, (QualityOptions, dict, tuple, list)): - raise ValueError("quality must be a QualityOptions or convertable object") - value = QualityOptions.factory(value) - elif name == "user": - value = UserOptions.factory(value) - else: - # elif name not in ["title"]: - raise ValueError("%s is not a valid member of WaterNetworkModel") + raise ValueError("%s is not a valid member of MultispeciesOptions") self.__dict__[name] = value def to_dict(self): diff --git a/wntr/quality/variables.py b/wntr/quality/variables.py deleted file mode 100644 index c70017dc8..000000000 --- a/wntr/quality/variables.py +++ /dev/null @@ -1,362 +0,0 @@ -# -*- coding: utf-8 -*- - -""" -Classes for variables used in reaction dynamics definitions. -Defines species (chemical or biological), coefficients for equations, -"term-functions", i.e., named functions that are called "terms" in -EPANET-MSX, and internal variables, such as hydraulic variables. - -The classes in this module can be created directly. However, they are more -powerful when either, a) created using API calls on a :class:`~wntr.reaction.model.WaterNetworkModel`, -or, b) linked to a :class:`~wntr.reaction.model.WaterNetworkModel` model object after creation. -This allows for variables to be validated against other variables in the model, -avoiding naming conflicts and checking that terms used in a term-function have -been defined. - -If :class:`sympy` is installed, then there are functions available -that will convert object instances of these classes into sympy expressions -and symbols. If the instances are linked to a model, then expressions can -be expanded, validated, and even evaluated or simplified symbolically. - -.. rubric:: Contents - -.. autosummary:: - - Species - BulkSpecies - WallSpecies - Coefficient - Constant - Parameter - OtherTerm - InternalVariable - -""" - -import enum -import logging -import warnings -from dataclasses import InitVar, asdict, dataclass, field -from enum import Enum, IntFlag -from typing import Any, ClassVar, Dict, List, Set, Tuple, Union -from .base import MSXComment - -has_sympy = False -try: - from sympy import Float, Symbol, init_printing, symbols - from sympy.parsing import parse_expr - from sympy.parsing.sympy_parser import convert_xor, standard_transformations - - has_sympy = True -except ImportError: - sympy = None - logging.critical("This python installation does not have SymPy installed. Certain functionality will be disabled.") - standard_transformations = (None,) - convert_xor = None - has_sympy = False - -from wntr.network.model import WaterNetworkModel -from wntr.quality.base import EXPR_TRANSFORMS - -from .base import ( - RESERVED_NAMES, - ExpressionMixin, - LinkedVariablesMixin, - MsxObjectMixin, - AbstractReactionModel, - ReactionVariable, - VariableType, -) - -logger = logging.getLogger(__name__) - - -@dataclass(repr=False) -class Species(MsxObjectMixin, LinkedVariablesMixin, ReactionVariable): - - units: str - """The unit used for this species""" - atol: InitVar[float] = None - """The absolute tolerance to use when solving for this species, by default None""" - rtol: InitVar[float] = None - """The relative tolerance to use when solving for this species, by default None""" - note: Union[str, Dict[str, str]] = None - """A note about this species, by default None""" - diffusivity: float = None - """The diffusivity value for this species, by default None""" - variable_registry: InitVar[AbstractReactionModel] = None - - def __post_init__(self, atol=None, rtol=None, reaction_model=None): - if isinstance(atol, property): - atol = None - elif atol is not None: - atol = float(atol) - if isinstance(rtol, property): - rtol = None - elif rtol is not None: - rtol = float(rtol) - if self.name in RESERVED_NAMES: - raise ValueError("Name cannot be a reserved name") - if (atol is None) ^ (rtol is None): - raise TypeError("atol and rtol must be the same type, got {} and {}".format(atol, rtol)) - self._atol = atol - self._rtol = rtol - self._variable_registry = reaction_model - - def __repr__(self): - return "{}(name={}, unit={}, atol={}, rtol={}, note={})".format(self.__class__.__name__, repr(self.name), repr(self.units), self._atol, self._rtol, repr(self.note)) - - def get_tolerances(self) -> Tuple[float, float]: - """Get the species-specific solver tolerances. - - Returns - ------- - two-tuple or None - the absolute and relative tolerances, or None if the global values should be used - """ - if self._atol is not None and self._rtol is not None: - return (self._atol, self._rtol) - return None - - def set_tolerances(self, absolute: float, relative: float): - """Set the species-specific solver tolerances. Using ``None`` for both will - clear the tolerances, though using :func:`clear_tolerances` is clearer code. - - Parameters - ---------- - absolute : float - the absolute solver tolerance - relative : float - the relative solver tolerance - - Raises - ------ - TypeError - if both absolute and relative are not the same type - ValueError - if either value is less-than-or-equal-to zero - """ - if absolute is None and relative is None: - self._atol = self._rtol = None - return - try: - if not isinstance(absolute, float): - absolute = float(absolute) - if not isinstance(relative, float): - relative = float(relative) - except Exception as e: - raise TypeError("absolute and relative must be the same type, got {} and {}".format(absolute, relative)) - if absolute <= 0: - raise ValueError("Absolute tolerance must be greater than 0") - if relative <= 0: - raise ValueError("Relative tolerance must be greater than 0") - self._atol = absolute - self._rtol = relative - - def clear_tolerances(self): - """Resets both tolerances to ``None`` to use the global values.""" - self._atol = self._rtol = None - - def to_msx_string(self) -> str: - tols = self.get_tolerances() - if tols is None: - tolstr = "" - else: - tolstr = " {:12.6g} {:12.6g}".format(*tols) - return "{:<12s} {:<8s} {:<8s}{:s}".format( - self.var_type.name.upper(), - self.name, - self.units, - tolstr, - ) - - def to_dict(self): - rep = dict(name=self.name, unist=self.units) - tols = self.get_tolerances() - if tols is not None: - rep['atol'] = tols[0] - rep['rtol'] = tols[1] - rep['diffusivity'] = self.diffusivity - if isinstance(self.note, str): - rep['note'] = self.note - elif isinstance(self.note, MSXComment): - rep['note'] = asdict(self.note) if self.note.pre else self.note.post - else: - rep['note'] = None - return rep - - -@dataclass(repr=False) -class BulkSpecies(Species): - @property - def var_type(self) -> VariableType: - return VariableType.BULK - - -@dataclass(repr=False) -class WallSpecies(Species): - @property - def var_type(self) -> VariableType: - return VariableType.WALL - - -@dataclass(repr=False) -class Coefficient(MsxObjectMixin, LinkedVariablesMixin, ReactionVariable): - - global_value: float - note: Union[str, Dict[str, str]] = None - units: str = None - variable_registry: InitVar[AbstractReactionModel] = None - - def __post_init__(self, reaction_model): - if self.name in RESERVED_NAMES: - raise ValueError("Name cannot be a reserved name") - self.global_value = float(self.global_value) - self._variable_registry = reaction_model - - def __repr__(self): - return "{}(name={}, global_value={}, units={}, note={})".format(self.__class__.__name__, repr(self.name), repr(self.global_value), repr(self.units), repr(self.note)) - - def get_value(self) -> float: - return self.global_value - - def to_msx_string(self) -> str: - # if self.units is not None: - # post = r' ; {"units"="' + str(self.units) + r'"}' - # else: - post = '' - return "{:<12s} {:<8s} {:<16s}{}".format( - self.var_type.name.upper(), - self.name, - str(self.global_value), - post - ) - - def to_dict(self): - rep = dict(name=self.name, global_value=self.global_value, units=self.units) - if isinstance(self.note, str): - rep['note'] = self.note - elif isinstance(self.note, MSXComment): - rep['note'] = asdict(self.note) if self.note.pre else self.note.post - else: - rep['note'] = None - return rep - - -@dataclass(repr=False) -class Constant(Coefficient): - @property - def var_type(self) -> VariableType: - return VariableType.CONST - - -@dataclass(repr=False) -class Parameter(Coefficient): - - _pipe_values: Dict[str, float] = field(default_factory=dict) - """A dictionary of parameter values for various pipes""" - _tank_values: Dict[str, float] = field(default_factory=dict) - """A dictionary of parameter values for various tanks""" - - def __post_init__(self, reaction_model): - super().__post_init__(reaction_model) - if self._pipe_values is None: - self._pipe_values = dict() - if self._tank_values is None: - self._tank_values = dict() - - @property - def var_type(self) -> VariableType: - return VariableType.PARAM - - def get_value(self, pipe: str = None, tank: str = None) -> float: - if pipe is not None and tank is not None: - raise TypeError("Cannot get a value for a pipe and tank at the same time - one or both must be None") - if pipe is not None: - return self._pipe_values.get(pipe, self.global_value) - if tank is not None: - return self._tank_values.get(tank, self.global_value) - return self.global_value - - @property - def pipe_values(self) -> Dict[str, float]: - return self._pipe_values - - @property - def tank_values(self) -> Dict[str, float]: - return self._tank_values - - def to_dict(self): - rep = super().to_dict() - rep['pipe_values'] = self._pipe_values.copy() - rep['tank_values'] = self._tank_values.copy() - return rep - - -@dataclass(repr=False) -class OtherTerm(MsxObjectMixin, LinkedVariablesMixin, ExpressionMixin, ReactionVariable): - """A function definition used as a shortcut in reaction expressions (called a 'term' in EPANET-MSX) - - Parameters - ---------- - name : str - the name/symbol of the function (term) - expression : str - the mathematical expression described by this function - note : str, optional - a note for this function, by default None - variable_registry : RxnModelRegistry - the reaction model this function is a part of - """ - - expression: str - """The expression this named-function is equivalent to""" - note: Union[str, Dict[str, str]] = None - """A note about this function/term""" - variable_registry: InitVar[AbstractReactionModel] = field(default=None, compare=False) - - def __post_init__(self, reaction_model): - if self.name in RESERVED_NAMES: - raise ValueError("Name cannot be a reserved name") - self._variable_registry = reaction_model - - def __repr__(self): - return "{}(name={}, expression={}, note={})".format(self.__class__.__name__, repr(self.name), repr(self.expression), repr(self.note)) - - @property - def var_type(self) -> VariableType: - return VariableType.TERM - - def to_msx_string(self) -> str: - return "{:<8s} {:<64s}".format(self.name, self.expression) - - def to_symbolic(self, transformations=...): - return super().to_symbolic(transformations) - - def to_dict(self): - rep = dict(name=self.name, expression=self.expression) - if isinstance(self.note, str): - rep['note'] = self.note - elif isinstance(self.note, MSXComment): - rep['note'] = asdict(self.note) if self.note.pre else self.note.post - else: - rep['note'] = None - return rep - - -@dataclass(repr=False) -class InternalVariable(ReactionVariable): - """A hydraulic variable or a placeholder for a built-in reserved word. - - For example, "Len" is the EPANET-MSX name for the length of a pipe, and "I" is a sympy - reserved symbol for the imaginary number.""" - - note: str = "internal variable - not output to MSX" - units: str = None - - def __repr__(self): - return "{}(name={}, note={}, units={})".format(self.__class__.__name__, repr(self.name), repr(self.note), repr(self.units)) - - @property - def var_type(self) -> VariableType: - return VariableType.INTERNAL diff --git a/wntr/tests/test_quality_variables.py b/wntr/tests/test_quality_variables.py index a0bf23043..e14357fbb 100644 --- a/wntr/tests/test_quality_variables.py +++ b/wntr/tests/test_quality_variables.py @@ -52,7 +52,7 @@ def test_RxnVariable_values(self): self.assertEqual(const1.get_value(), const1.global_value) test_pipe_dict = {"PIPE": 0.38} test_tank_dict = {"TANK": 222.23} - param2 = wntr.quality.Parameter("Kb", 0.482, note="test", _pipe_values=test_pipe_dict, _tank_values=test_tank_dict) + param2 = wntr.quality.Parameter("Kb", 0.482, note="test", pipe_values=test_pipe_dict, tank_values=test_tank_dict) self.assertEqual(param2.get_value(), param2.global_value) self.assertEqual(param2.get_value(pipe="PIPE"), test_pipe_dict["PIPE"]) self.assertEqual(param2.get_value(pipe="FOO"), param2.global_value) @@ -67,14 +67,9 @@ def test_RxnVariable_string_functions(self): term1 = wntr.quality.OtherTerm("T0", "-3.2 * Kb * Cl^2", note="bar") self.assertEqual(str(species1), "Cl") - self.assertEqual(species1.to_msx_string(), "BULK Cl mg ;") - self.assertEqual(species2.to_msx_string(), "WALL Cl mg 0.01 0.0001 ;Testing stuff") self.assertEqual(str(const1), "Kb") self.assertEqual(str(param1), "Ka") - self.assertEqual(const1.to_msx_string(), "CONSTANT Kb 0.482 ;") - self.assertEqual(param1.to_msx_string(), "PARAMETER Ka 0.482 ;foo") self.assertEqual(str(term1), "T0") - self.assertEqual(term1.to_msx_string(), "T0 -3.2 * Kb * Cl^2 ;bar") def test_Species_tolerances(self): # """RxnSpecies(*s) tolerance settings""" @@ -87,14 +82,14 @@ def test_Species_tolerances(self): self.assertRaises(ValueError, species1.set_tolerances, -0.51, 0.01) self.assertRaises(ValueError, species1.set_tolerances, 0.0, 0.0) species1.set_tolerances(0.01, 0.0001) - self.assertEqual(species1.atol, 0.01) - self.assertEqual(species1.rtol, 0.0001) + self.assertEqual(species1._atol, 0.01) + self.assertEqual(species1._rtol, 0.0001) species1.set_tolerances(None, None) - self.assertIsNone(species1.atol) - self.assertIsNone(species1.rtol) + self.assertIsNone(species1._atol) + self.assertIsNone(species1._rtol) species2.clear_tolerances() - self.assertIsNone(species1.atol) - self.assertIsNone(species1.rtol) + self.assertIsNone(species1._atol) + self.assertIsNone(species1._rtol) self.assertIsNone(species2.get_tolerances()) def test_BulkSpecies_creation(self): @@ -107,15 +102,15 @@ def test_BulkSpecies_creation(self): self.assertEqual(species.name, "Cl") self.assertEqual(species.units, "mg") self.assertEqual(species.var_type, wntr.quality.VariableType.BULK) - self.assertIsNone(species.atol) - self.assertIsNone(species.rtol) + self.assertIsNone(species._atol) + self.assertIsNone(species._rtol) self.assertIsNone(species.note) species = wntr.quality.BulkSpecies("Cl", "mg", 0.01, 0.0001, note="Testing stuff") self.assertEqual(species.var_type, wntr.quality.VariableType.BULK) self.assertEqual(species.name, "Cl") self.assertEqual(species.units, "mg") - self.assertEqual(species.atol, 0.01) - self.assertEqual(species.rtol, 0.0001) + self.assertEqual(species._atol, 0.01) + self.assertEqual(species._rtol, 0.0001) self.assertEqual(species.note, "Testing stuff") def test_WallSpecies_creation(self): @@ -128,15 +123,15 @@ def test_WallSpecies_creation(self): self.assertEqual(species.name, "Cl") self.assertEqual(species.units, "mg") self.assertEqual(species.var_type, wntr.quality.VariableType.WALL) - self.assertIsNone(species.atol) - self.assertIsNone(species.rtol) + self.assertIsNone(species._atol) + self.assertIsNone(species._rtol) self.assertIsNone(species.note) species = wntr.quality.WallSpecies("Cl", "mg", 0.01, 0.0001, note="Testing stuff") self.assertEqual(species.var_type, wntr.quality.VariableType.WALL) self.assertEqual(species.name, "Cl") self.assertEqual(species.units, "mg") - self.assertEqual(species.atol, 0.01) - self.assertEqual(species.rtol, 0.0001) + self.assertEqual(species._atol, 0.01) + self.assertEqual(species._rtol, 0.0001) self.assertEqual(species.note, "Testing stuff") def test_Constant_creation(self): @@ -162,7 +157,7 @@ def test_Parameter_creation(self): self.assertEqual(param1.note, "test") test_pipe_dict = {"PIPE": 0.38} test_tank_dict = {"TANK": 222.23} - param2 = wntr.quality.Parameter("Kb", 0.482, note="test", _pipe_values=test_pipe_dict, _tank_values=test_tank_dict) + param2 = wntr.quality.Parameter("Kb", 0.482, note="test", pipe_values=test_pipe_dict, tank_values=test_tank_dict) self.assertDictEqual(param2.pipe_values, test_pipe_dict) self.assertDictEqual(param2.tank_values, test_tank_dict) @@ -179,9 +174,6 @@ def test_RxnExpression_strings(self): equil1 = wntr.quality.EquilibriumDynamics("Cl", wntr.quality.LocationType.PIPE, "-Ka + Kb * Cl + T0") rate1 = wntr.quality.RateDynamics("Cl", wntr.quality.LocationType.TANK, "-Ka + Kb * Cl + T0", note="Foo Bar") formula1 = wntr.quality.FormulaDynamics("Cl", wntr.quality.LocationType.PIPE, "-Ka + Kb * Cl + T0") - self.assertEqual(equil1.to_msx_string(), "EQUIL Cl -Ka + Kb * Cl + T0 ;") - self.assertEqual(rate1.to_msx_string(), "RATE Cl -Ka + Kb * Cl + T0 ;Foo Bar") - self.assertEqual(formula1.to_msx_string(), "FORMULA Cl -Ka + Kb * Cl + T0 ;") def test_Equilibrium_creation(self): equil1 = wntr.quality.EquilibriumDynamics("Cl", wntr.quality.LocationType.PIPE, "-Ka + Kb * Cl + T0") @@ -203,7 +195,7 @@ def test_Formula_creation(self): self.assertEqual(formula1.expr_type, wntr.quality.DynamicsType.FORMULA) def test_WaterQualityReactionsModel_creation_specific_everything(self): - rxn_model1 = wntr.quality.MultispeciesReactionModel() + rxn_model1 = wntr.quality.MultispeciesQualityModel() bulk1 = wntr.quality.BulkSpecies("Cl", "mg") wall1 = wntr.quality.WallSpecies("ClOH", "mg", 0.01, 0.0001, note="Testing stuff") const1 = wntr.quality.Constant("Kb", 0.482) @@ -237,7 +229,7 @@ def test_WaterQualityReactionsModel_creation_generic_species_coeffs(self): param1 = wntr.quality.Parameter("Ka", 0.482, note="foo") term1 = wntr.quality.OtherTerm("T0", "-3.2 * Kb * Cl^2", note="bar") - rxn_model2 = wntr.quality.MultispeciesReactionModel() + rxn_model2 = wntr.quality.MultispeciesQualityModel() self.assertRaises(ValueError, rxn_model2.add_species, wntr.quality.VariableType.CONST, "Cl", "mg") self.assertRaises(TypeError, rxn_model2.add_coefficient, None, "Kb", 0.482) From 45d597674b44e0eb9b866b84d7b22eb233bb439a Mon Sep 17 00:00:00 2001 From: dbhart Date: Tue, 26 Sep 2023 10:12:45 -0600 Subject: [PATCH 28/75] Updates for testing and documentation --- wntr/epanet/msx/enums.py | 215 ++++++++ wntr/epanet/msx/exceptions.py | 3 +- wntr/epanet/msx/io.py | 205 ++++---- wntr/epanet/util.py | 10 +- wntr/network/base.py | 21 +- wntr/network/elements.py | 16 +- wntr/quality/base.py | 86 ++-- wntr/quality/library.py | 25 +- wntr/quality/multispecies.py | 487 +++++++++++++----- wntr/quality/options.py | 42 +- .../networks_for_testing/msx_example.inp | 36 ++ .../networks_for_testing/msx_example.msx | 58 +++ wntr/tests/test_epanet_msx_io.py | 42 ++ wntr/tests/test_epanet_msx_tooklit.py | 35 ++ wntr/utils/enumtools.py | 2 + 15 files changed, 969 insertions(+), 314 deletions(-) create mode 100644 wntr/tests/networks_for_testing/msx_example.inp create mode 100644 wntr/tests/networks_for_testing/msx_example.msx create mode 100644 wntr/tests/test_epanet_msx_io.py create mode 100644 wntr/tests/test_epanet_msx_tooklit.py diff --git a/wntr/epanet/msx/enums.py b/wntr/epanet/msx/enums.py index 97d31af6e..6a94ca483 100644 --- a/wntr/epanet/msx/enums.py +++ b/wntr/epanet/msx/enums.py @@ -8,6 +8,22 @@ class ObjectType(IntEnum): """The enumeration for object type used in EPANET-MSX. .. warning:: These enum values start with 0. + + .. rubric:: Enum Members + + The following enum names are defined, and, if using the :meth:`get` method, then + they are case insensitive and can be optionally prefixed with "MSX\_". + + .. autosummary:: + NODE + LINK + PIPE + TANK + SPECIES + TERM + PARAMETER + CONSTANT + PATTERN """ NODE = 0 """EPANET node""" @@ -35,6 +51,18 @@ class SourceType(IntEnum): """The enumeration for source type used in EPANET-MSX. .. warning:: These enum values start with -1. + + .. rubric:: Enum Members + + The following enum names are defined, and, if using the :meth:`get` method, then + they are case insensitive and can be optionally prefixed with "MSX\_". + + .. autosummary:: + NOSOURCE + CONCEN + MASS + SETPOINT + FLOWPACED """ NOSOURCE = -1 """No source""" @@ -53,6 +81,15 @@ class UnitSystemType(IntEnum): """The enumeration for the units system used in EPANET-MSX. .. warning:: These enum values start with 0. + + .. rubric:: Enum Members + + The following enum names are defined, and, if using the :meth:`get` method, then + they are case insensitive and can be optionally prefixed with "MSX\_". + + .. autosummary:: + US + SI """ US = 0 """US units (ft, ft2, gal)""" @@ -65,6 +102,23 @@ class FlowUnitsType(IntEnum): """The enumeration for the flow units used in EPANET-MSX (determined from EPANET INP file read in with the toolkit). .. warning:: These enum values start with 0. + + .. rubric:: Enum Members + + The following enum names are defined, and, if using the :meth:`get` method, then + they are case insensitive and can be optionally prefixed with "MSX\_". + + .. autosummary:: + CFS + GPM + MGD + IMGD + AFD + LPS + LPM + MLD + CMH + CMD """ CFS = 0 """cubic feet per second""" @@ -93,6 +147,17 @@ class MixType(IntEnum): """The enumeration for the mixing model used in EPANET-MSX. .. warning:: These enum values start with 0. + + .. rubric:: Enum Members + + The following enum names are defined, and, if using the :meth:`get` method, then + they are case insensitive and can be optionally prefixed with "MSX\_". + + .. autosummary:: + MIX1 + MIX2 + FIFO + LIFO """ MIX1 = 0 """full mixing, 1 compartment""" @@ -109,6 +174,15 @@ class SpeciesType(IntEnum): """The enumeration for species type used in EPANET-MSX. .. warning:: These enum values start with 0. + + .. rubric:: Enum Members + + The following enum names are defined, and, if using the :meth:`get` method, then + they are case insensitive and can be optionally prefixed with "MSX\_". + + .. autosummary:: + BULK + WALL """ BULK = 0 """bulk species""" @@ -121,6 +195,17 @@ class ExpressionType(IntEnum): """The enumeration for the expression type used in EPANET-MSX. .. warning:: These enum values start with 0. + + .. rubric:: Enum Members + + The following enum names are defined, and, if using the :meth:`get` method, then + they are case insensitive and can be optionally prefixed with "MSX\_". + + .. autosummary:: + NO_EXPR + RATE + FORMULA + EQUIL """ NO_EXPR = 0 """no expression defined""" @@ -137,6 +222,16 @@ class SolverType(IntEnum): """The enumeration for the solver type used in EPANET-MSX. .. warning:: These enum values start with 0. + + .. rubric:: Enum Members + + The following enum names are defined, and, if using the :meth:`get` method, then + they are case insensitive and can be optionally prefixed with "MSX\_". + + .. autosummary:: + EUL + RK5 + ROS2 """ EUL = 0 """Euler solver""" @@ -151,6 +246,15 @@ class CouplingType(IntEnum): """The enumeration for the coupling type option used in EPANET-MSX. .. warning:: These enum values start with 0. + + .. rubric:: Enum Members + + The following enum names are defined, and, if using the :meth:`get` method, then + they are case insensitive and can be optionally prefixed with "MSX\_". + + .. autosummary:: + NO_COUPLING + FULL_COUPLING """ NO_COUPLING = 0 """no coupling""" @@ -163,6 +267,17 @@ class MassUnitsType(IntEnum): """The enumeration for mass units used in EPANET-MSX. .. warning:: These enum values start with 0. + + .. rubric:: Enum Members + + The following enum names are defined, and, if using the :meth:`get` method, then + they are case insensitive and can be optionally prefixed with "MSX\_". + + .. autosummary:: + MG + UG + MOLE + MMOLE """ MG = 0 """milligrams""" @@ -179,6 +294,16 @@ class AreaUnitsType(IntEnum): """The enumeration for area units used in EPANET-MSX. .. warning:: These enum values start with 0. + + .. rubric:: Enum Members + + The following enum names are defined, and, if using the :meth:`get` method, then + they are case insensitive and can be optionally prefixed with "MSX\_". + + .. autosummary:: + FT2 + M2 + CM2 """ FT2 = 0 """square feet""" @@ -193,6 +318,17 @@ class RateUnitsType(IntEnum): """The enumeration for rate units used in EPANET-MSX. .. warning:: These enum values start with 0. + + .. rubric:: Enum Members + + The following enum names are defined, and, if using the :meth:`get` method, then + they are case insensitive and can be optionally prefixed with "MSX\_". + + .. autosummary:: + SECONDS + MINUTES + HOURS + DAYS """ SECONDS = 0 """per second""" @@ -209,6 +345,20 @@ class UnitsType(IntEnum): """The position for units used in EPANET-MSX. .. warning:: These enum values start with 0. + + .. rubric:: Enum Members + + The following enum names are defined, and, if using the :meth:`get` method, then + they are case insensitive and can be optionally prefixed with "MSX\_". + + .. autosummary:: + LENGTH_UNITS + DIAM_UNITS + AREA_UNITS + VOL_UNITS + FLOW_UNITS + CONC_UNITS + RATE_UNITS """ LENGTH_UNITS = 0 """the length unit index""" @@ -232,6 +382,22 @@ class HydVarType(IntEnum): """The enumeration for hydraulic variable used in EPANET-MSX. .. warning:: These enum values start with 0. + + .. rubric:: Enum Members + + The following enum names are defined, and, if using the :meth:`get` method, then + they are case insensitive and can be optionally prefixed with "MSX\_". + + .. autosummary:: + DIAMETER + FLOW + VELOCITY + REYNOLDS + SHEAR + FRICTION + AREAVOL + ROUGHNESS + LENGTH """ DIAMETER = 1 """pipe diameter""" @@ -259,6 +425,18 @@ class TstatType(IntEnum): """The enumeration used for time statistic in EPANET-MSX. .. warning:: These enum values start with 0. + + .. rubric:: Enum Members + + The following enum names are defined, and, if using the :meth:`get` method, then + they are case insensitive and can be optionally prefixed with "MSX\_". + + .. autosummary:: + SERIES + AVERAGE + MINIMUM + MAXIMUM + RANGE """ SERIES = 0 """output a time series""" @@ -277,6 +455,23 @@ class OptionType(IntEnum): """The enumeration used for choosing an option in EPANET-MSX toolkit. .. warning:: These enum values start with 0. + + .. rubric:: Enum Members + + The following enum names are defined, and, if using the :meth:`get` method, then + they are case insensitive and can be optionally prefixed with "MSX\_". + + .. autosummary:: + AREA_UNITS_OPTION + RATE_UNITS_OPTION + SOLVER_OPTION + COUPLING_OPTION + TIMESTEP_OPTION + RTOL_OPTION + ATOL_OPTION + COMPILER_OPTION + MAXSEGMENT_OPTION + PECLETNUMBER_OPTION """ AREA_UNITS_OPTION = 0 """area units""" @@ -305,6 +500,16 @@ class CompilerType(IntEnum): """The enumeration used for specifying compiler options in EPANET-MSX. .. warning:: These enum values start with 0. + + .. rubric:: Enum Members + + The following enum names are defined, and, if using the :meth:`get` method, then + they are case insensitive and can be optionally prefixed with "MSX\_". + + .. autosummary:: + NO_COMPILER + VC + GC """ NO_COMPILER = 0 """do not compile reaction dynamics""" @@ -319,6 +524,16 @@ class FileModeType(IntEnum): """The enumeration for file model used in EPANET-MSX. .. warning:: These enum values start with 0. + + .. rubric:: Enum Members + + The following enum names are defined, and, if using the :meth:`get` method, then + they are case insensitive and can be optionally prefixed with "MSX\_". + + .. autosummary:: + SCRATCH_FILE + SAVED_FILE + USED_FILE """ SCRATCH_FILE = 0 """use a scratch file""" diff --git a/wntr/epanet/msx/exceptions.py b/wntr/epanet/msx/exceptions.py index 1df9aabee..0faeeac71 100644 --- a/wntr/epanet/msx/exceptions.py +++ b/wntr/epanet/msx/exceptions.py @@ -55,7 +55,8 @@ @add_get(prefix="ERR_") class MsxErrorEnum(IntEnum): - """The EPANET-MSX input and toolkit error numbers, keys, and descriptions""" + """The EPANET-MSX input and toolkit error numbers, keys, and descriptions. + """ MAX_CHARS = 401 "too many characters" diff --git a/wntr/epanet/msx/io.py b/wntr/epanet/msx/io.py index 82a63ffa5..2d3329aec 100644 --- a/wntr/epanet/msx/io.py +++ b/wntr/epanet/msx/io.py @@ -53,16 +53,27 @@ def _split_line(line): class MsxFile(object): + """An EPANET-MSX input file reader. + + .. rubric:: Class Methods + .. autosummary:: + :nosignatures: + + read + write + + """ + def __init__(self): - """An MSX input file, usually ".msx" extension. - """ + self.rxn: MultispeciesQualityModel = None self.sections = dict() for sec in _INP_SECTIONS: self.sections[sec] = [] self.top_comments = [] self.patterns = dict() - def read(self, msx_file, rxn_model=None): + @classmethod + def read(cls, msx_filename: str, rxn_model: MultispeciesQualityModel = None): """ Read an EPANET-MSX input file (.msx) and load data into a water quality reactions model. Only MSX 2.0 files are recognized. @@ -81,22 +92,23 @@ def read(self, msx_file, rxn_model=None): """ if rxn_model is None: rxn_model = MultispeciesQualityModel() - self.rxn = rxn_model + obj = cls() + obj.rxn = rxn_model # if not isinstance(msx_file, list): # msx_file = [msx_file] - rxn_model.filename = msx_file + rxn_model.filename = msx_filename - self.patterns = dict() - self.top_comments = [] - self.sections = dict() + obj.patterns = dict() + obj.top_comments = [] + obj.sections = dict() for sec in _INP_SECTIONS: - self.sections[sec] = [] + obj.sections[sec] = [] def _read(): section = None lnum = 0 - edata = {"fname": msx_file} - with open(msx_file, "r", encoding=sys_default_enc) as f: + edata = {"fname": msx_filename} + with open(msx_filename, "r", encoding=sys_default_enc) as f: for line in f: lnum += 1 edata["lnum"] = lnum @@ -130,32 +142,64 @@ def _read(): logger.warning('%(fname)s:%(lnum)d: Invalid section "%(sec)s"' % edata) raise EpanetMsxException(201, note='at line {}:\n{}'.format(lnum, line)) elif section is None and line.startswith(";"): - self.top_comments.append(line[1:]) + obj.top_comments.append(line[1:]) continue elif section is None: logger.debug("Found confusing line: %s", repr(line)) raise EpanetMsxException(201, note='at line {}:\n{}'.format(lnum, line)) # We have text, and we are in a section - self.sections[section].append((lnum, line)) + obj.sections[section].append((lnum, line)) try: _read() - self._read_title() - self._read_options() - self._read_species() - self._read_coefficients() - self._read_terms() - self._read_pipes() - self._read_tanks() - self._read_sources() - self._read_quality() - self._read_parameters() - self._read_diffusivity() - self._read_patterns() - self._read_report() - return self.rxn + obj._read_title() + obj._read_options() + obj._read_species() + obj._read_coefficients() + obj._read_terms() + obj._read_pipes() + obj._read_tanks() + obj._read_source_dict() + obj._read_quality() + obj._read_parameters() + obj._read_diffusivity() + obj._read_patterns() + obj._read_report() + return obj.rxn except Exception as e: raise EpanetMsxException(200) from e + @classmethod + def write(cls, filename: str, msx: MultispeciesQualityModel): + """Write an MSX input file. + + Parameters + ---------- + filename : str + the filename to write + rxn : MultispeciesQualityModel + the multispecies reaction model + """ + obj = cls() + obj.rxn = msx + with open(filename, "w") as fout: + + fout.write("; WNTR-reactions MSX file generated {}\n".format(datetime.datetime.now())) + fout.write("\n") + obj._write_title(fout) + obj._write_options(fout) + obj._write_species(fout) + obj._write_coefficients(fout) + obj._write_terms(fout) + obj._write_pipes(fout) + obj._write_tanks(fout) + obj._write_source_dict(fout) + obj._write_quality(fout) + obj._write_diffusivity(fout) + obj._write_parameters(fout) + obj._write_patterns(fout) + obj._write_report(fout) + fout.write("; END of MSX file generated by WNTR\n") + def _read_title(self): lines = [] title = None @@ -183,25 +227,25 @@ def _read_options(self): raise EpanetMsxException(402, note="at line {} of [OPTIONS] section:\n{}".format(lnum, line)) name, val = vals[0].upper(), vals[1].upper() if name == "AREA_UNITS": - self.rxn._options.quality.area_units = val + self.rxn._options.area_units = val elif name == "RATE_UNITS": - self.rxn._options.quality.rate_units = val + self.rxn._options.rate_units = val elif name == "SOLVER": - self.rxn._options.quality.solver = val + self.rxn._options.solver = val elif name == "COUPLING": - self.rxn._options.quality.coupling = val + self.rxn._options.coupling = val elif name == "TIMESTEP": - self.rxn._options.quality.timestep = int(val) + self.rxn._options.timestep = int(val) elif name == "ATOL": - self.rxn._options.quality.atol = float(val) + self.rxn._options.atol = float(val) elif name == "RTOL": - self.rxn._options.quality.rtol = float(val) + self.rxn._options.rtol = float(val) elif name == "COMPILER": - self.rxn._options.quality.compiler = val + self.rxn._options.compiler = val elif name == "SEGMENTS": - self.rxn._options.quality.segments = int(val) + self.rxn._options.segments = int(val) elif name == "PECLET": - self.rxn._options.quality.peclet = int(val) + self.rxn._options.peclet = int(val) else: raise EpanetMsxException(403, note='at line {} of [OPTIONS] section:\n{}'.format(lnum, line)) except ValueError: @@ -326,7 +370,7 @@ def _read_tanks(self): else: note = ENcomment() - def _read_sources(self): + def _read_source_dict(self): lines = [] note = ENcomment() for lnum, line in self.sections["[SOURCES]"]: @@ -345,10 +389,10 @@ def _read_sources(self): typ, node, spec, strength, pat = vals if not self.rxn.has_variable(spec): raise ValueError("Undefined species in [SOURCES] section: {}".format(spec)) - if spec not in self.rxn._sources.keys(): - self.rxn._sources[spec] = dict() + if spec not in self.rxn._source_dict.keys(): + self.rxn._source_dict[spec] = dict() source = dict(source_type=typ, strength=strength, pattern=pat, note=note) - self.rxn._sources[spec][node] = source + self.rxn._source_dict[spec][node] = source except EpanetMsxException: raise except Exception as e: @@ -376,14 +420,14 @@ def _read_quality(self): raise SyntaxError("Unknown first word in [QUALITY] section") if not self.rxn.has_variable(spec): raise ValueError("Undefined species in [QUALITY] section: {}".format(spec)) - if spec not in self.rxn._inital_quality.keys(): - self.rxn._inital_quality[spec] = dict(global_value=None, nodes=dict(), links=dict()) + if spec not in self.rxn._inital_qual_dict.keys(): + self.rxn._inital_qual_dict[spec] = dict(global_value=None, nodes=dict(), links=dict()) if cmd[0].lower() == "g": - self.rxn._inital_quality[spec]["global_value"] = float(concen) + self.rxn._species[spec].initial_quality = float(concen) elif cmd[0].lower() == "n": - self.rxn._inital_quality[spec]["nodes"][netid] = float(concen) + self.rxn._inital_qual_dict[spec]["nodes"][netid] = float(concen) elif cmd[1].lower() == "l": - self.rxn._inital_quality[spec]["links"][netid] = float(concen) + self.rxn._inital_qual_dict[spec]["links"][netid] = float(concen) except EpanetMsxException: raise except Exception as e: @@ -526,36 +570,6 @@ def _read_report(self): else: note = ENcomment() - def write(self, filename: str, msx: MultispeciesQualityModel): - """Write an MSX input file. - - Parameters - ---------- - filename : str - the filename to write - rxn : MultispeciesQualityModel - the multispecies reaction model - """ - self.rxn = msx - with open(filename, "w") as fout: - - fout.write("; WNTR-reactions MSX file generated {}\n".format(datetime.datetime.now())) - fout.write("\n") - self._write_title(fout) - self._write_options(fout) - self._write_species(fout) - self._write_coefficients(fout) - self._write_terms(fout) - self._write_pipes(fout) - self._write_tanks(fout) - self._write_sources(fout) - self._write_quality(fout) - self._write_diffusivity(fout) - self._write_parameters(fout) - self._write_patterns(fout) - self._write_report(fout) - fout.write("; END of MSX file generated by WNTR\n") - def _write_title(self, fout): fout.write("[TITLE]\n") fout.write(" {}\n".format(self.rxn.title)) @@ -564,16 +578,16 @@ def _write_title(self, fout): def _write_options(self, fout): opts = self.rxn._options fout.write("[OPTIONS]\n") - fout.write(" AREA_UNITS {}\n".format(opts.quality.area_units.upper())) - fout.write(" RATE_UNITS {}\n".format(opts.quality.rate_units.upper())) - fout.write(" SOLVER {}\n".format(opts.quality.solver.upper())) - fout.write(" COUPLING {}\n".format(opts.quality.coupling.upper())) - fout.write(" TIMESTEP {}\n".format(opts.quality.timestep)) - fout.write(" ATOL {}\n".format(opts.quality.atol)) - fout.write(" RTOL {}\n".format(opts.quality.rtol)) - fout.write(" COMPILER {}\n".format(opts.quality.compiler.upper())) - fout.write(" SEGMENTS {}\n".format(opts.quality.segments)) - fout.write(" PECLET {}\n".format(opts.quality.peclet)) + fout.write(" AREA_UNITS {}\n".format(opts.area_units.upper())) + fout.write(" RATE_UNITS {}\n".format(opts.rate_units.upper())) + fout.write(" SOLVER {}\n".format(opts.solver.upper())) + fout.write(" COUPLING {}\n".format(opts.coupling.upper())) + fout.write(" TIMESTEP {}\n".format(opts.timestep)) + fout.write(" ATOL {}\n".format(opts.atol)) + fout.write(" RTOL {}\n".format(opts.rtol)) + fout.write(" COMPILER {}\n".format(opts.compiler.upper())) + fout.write(" SEGMENTS {}\n".format(opts.segments)) + fout.write(" PECLET {}\n".format(opts.peclet)) fout.write("\n") def _write_species(self, fout): @@ -670,10 +684,10 @@ def _write_tanks(self, fout): fout.write(" {}\n".format("{:<12s} {:<8s} {:<32s}".format(var.expr_type.name.upper(), str(var.species), var.expression))) fout.write("\n") - def _write_sources(self, fout): + def _write_source_dict(self, fout): fout.write("[SOURCES]\n") - for species in self.rxn._sources.keys(): - for node, src in self.rxn._sources[species].items(): + for species in self.rxn._source_dict.keys(): + for node, src in self.rxn._source_dict[species].items(): if isinstance(src["note"], ENcomment): fout.write( src["note"].wrap_msx_string( @@ -696,11 +710,12 @@ def _write_sources(self, fout): def _write_quality(self, fout): fout.write("[QUALITY]\n") - for species in self.rxn._inital_quality.keys(): - for typ, val in self.rxn._inital_quality[species].items(): - if typ == "global_value": - fout.write(" {:<8s} {:<8s} {}\n".format("GLOBAL", species, val)) - elif typ in ["nodes", "links"]: + for spec, species in self.rxn._species.items(): + if species.initial_quality is not None: + fout.write(" {:<8s} {:<8s} {}\n".format("GLOBAL", species.name, species.initial_quality)) + for species in self.rxn._inital_qual_dict.keys(): + for typ, val in self.rxn._inital_qual_dict[species].items(): + if typ in ["nodes", "links"]: for node, conc in val.items(): fout.write(" {:<8s} {:<8s} {:<8s} {}\n".format(typ.upper()[0:4], node, species, conc)) fout.write("\n") @@ -724,7 +739,7 @@ def _write_parameters(self, fout): def _write_patterns(self, fout): fout.write("[PATTERNS]\n") - for pattern_name, pattern in self.rxn._patterns.items(): + for pattern_name, pattern in self.rxn._pattern_dict.items(): num_columns = 10 count = 0 for i in pattern: # .multipliers: diff --git a/wntr/epanet/util.py b/wntr/epanet/util.py index 9c8fb41e5..ae97a8f56 100644 --- a/wntr/epanet/util.py +++ b/wntr/epanet/util.py @@ -35,8 +35,8 @@ class SizeLimits(enum.Enum): """ - Limits on the size of character arrays used to store ID names - and text messages. + Limits on the size of character arrays used to store ID names + and text messages. """ # // ! < Max. # characters in ID name EN_MAX_ID = 31 @@ -46,9 +46,9 @@ class SizeLimits(enum.Enum): class InitHydOption(enum.Enum): """ - Hydraulic initialization options. - These options are used to initialize a new hydraulic analysis - when EN_initH is called. + Hydraulic initialization options. + These options are used to initialize a new hydraulic analysis + when EN_initH is called. """ # !< Don't save hydraulics; don't re-initialize flows EN_NOSAVE = 0 diff --git a/wntr/network/base.py b/wntr/network/base.py index a7fc59cbb..1ce26e832 100644 --- a/wntr/network/base.py +++ b/wntr/network/base.py @@ -245,13 +245,13 @@ def tag(self, tag): @property def initial_quality(self): - """float: The initial quality (concentration) at the node""" + """float or dict: The initial quality (concentration) at the node, or a dict of species-->quality for multispecies quality""" if not self._initial_quality: return 0.0 return self._initial_quality @initial_quality.setter def initial_quality(self, value): - if value and not isinstance(value, (list, float, int)): + if value and not isinstance(value, (list, float, int, dict)): raise ValueError('Initial quality must be a float or a list') self._initial_quality = value @@ -372,6 +372,7 @@ def __init__(self, wn, link_name, start_node_name, end_node_name): # Model state variables self._user_status = LinkStatus.Opened self._internal_status = LinkStatus.Active + self._initial_quality = None self._prev_setting = None self._setting = None self._flow = None @@ -499,6 +500,18 @@ def status(self, status): " behavior, use initial_status.") # self._user_status = status + @property + def initial_quality(self): + """float or dict : The initial quality (concentration) at the node, or a dict of species and quality if multispecies""" + if not self._initial_quality: + return 0.0 + return self._initial_quality + @initial_quality.setter + def initial_quality(self, value): + if value and not isinstance(value, (list, float, int, dict)): + raise ValueError('Initial quality must be a float or a list') + self._initial_quality = value + @property def quality(self): """float : (read-only) current simulated average link quality""" @@ -591,8 +604,8 @@ class Registry(MutableMapping): """ def __init__(self, wn): - if not isinstance(wn, AbstractModel): - raise ValueError('Registry must be initialized with a model') + # if not isinstance(wn, AbstractModel): + # raise ValueError('Registry must be initialized with a model') # self._m = model self._data = OrderedDict() self._usage = OrderedDict() diff --git a/wntr/network/elements.py b/wntr/network/elements.py index 63588ae8a..6b3a9b749 100644 --- a/wntr/network/elements.py +++ b/wntr/network/elements.py @@ -2624,7 +2624,7 @@ class Source(object): """ # def __init__(self, name, node_registry, pattern_registry): - def __init__(self, model, name, node_name, source_type, strength, pattern=None): + def __init__(self, model, name, node_name, source_type, strength, pattern=None, species=None): self._strength_timeseries = TimeSeries(model._pattern_reg, strength, pattern, name) self._pattern_reg = model._pattern_reg self._pattern_reg.add_usage(pattern, (name, 'Source')) @@ -2633,6 +2633,7 @@ def __init__(self, model, name, node_name, source_type, strength, pattern=None): self._name = name self._node_name = node_name self._source_type = source_type + self._species = None def __eq__(self, other): if not type(self) == type(other): @@ -2644,8 +2645,8 @@ def __eq__(self, other): return False def __repr__(self): - fmt = "" - return fmt.format(self.name, self.node_name, self.source_type, self._strength_timeseries.base_value, self._strength_timeseries.pattern_name) + fmt = "" + return fmt.format(self.name, self.node_name, self.source_type, self._strength_timeseries.base_value, self._strength_timeseries.pattern_name, repr(self._species)) @property def strength_timeseries(self): @@ -2676,6 +2677,13 @@ def source_type(self): def source_type(self, value): self._source_type = value + @property + def species(self): + """str : species name for multispecies reactions, by default None""" + @species.setter + def species(self, value): + self._species = str(value) + def to_dict(self): ret = dict() ret['name'] = self.name @@ -2683,4 +2691,6 @@ def to_dict(self): ret['source_type'] = self.source_type ret['strength'] = self.strength_timeseries.base_value ret['pattern'] = self.strength_timeseries.pattern_name + if self.species: + ret['species'] = self.species return ret diff --git a/wntr/quality/base.py b/wntr/quality/base.py index 6dc404512..b217dd91d 100644 --- a/wntr/quality/base.py +++ b/wntr/quality/base.py @@ -10,13 +10,19 @@ import enum import logging from abc import ABC, abstractmethod, abstractproperty +from collections.abc import MutableMapping from dataclasses import InitVar, dataclass from enum import Enum, IntFlag from typing import ClassVar, Generator, List, Union +import numpy as np + +from wntr.network.base import AbstractModel from wntr.network.model import WaterNetworkModel +from wntr.network.elements import Pattern from wntr.quality.options import MultispeciesOptions from wntr.utils.enumtools import add_get +from wntr.utils.ordered_set import OrderedSet has_sympy = False try: @@ -48,16 +54,22 @@ {"name": "Av", "note": "Surface area per unit volume (area units/L) "}, {"name": "Len", "note": "Pipe length (feet or meters)"}, ] -"""The hydraulic variables defined in EPANET-MSX""" +"""The hydraulic variables defined in EPANET-MSX. + +:meta hide-value: +""" RESERVED_NAMES = tuple([v["name"] for v in HYDRAULIC_VARIABLES]) -"""The MSX reserved names as a tuple""" +"""The MSX reserved names.""" SYMPY_RESERVED = ("E", "I", "pi") """Some extra names reserved by sympy""" EXPR_TRANSFORMS = standard_transformations + (convert_xor,) -"""The sympy transforms to use in expression parsing""" +"""The sympy transforms to use in expression parsing. + +:meta hide-value: +""" @add_get(abbrev=True) @@ -67,10 +79,8 @@ class VariableType(Enum): The following types are defined, and aliases of just the first character are also defined. - .. rubric:: Valid Values - + .. rubric:: Enum Members .. autosummary:: - BULK WALL CONSTANT @@ -78,9 +88,9 @@ class VariableType(Enum): TERM INTERNAL - .. rubric:: Class methods - + .. rubric:: Class Methods .. autosummary:: + :nosignatures: get @@ -100,22 +110,15 @@ class VariableType(Enum): """An internal variable - see :attr:`~wntr.reaction.base.RESERVED_NAMES`""" B = BULK - """Alias for :attr:`BULK`""" W = WALL - """Alias for :attr:`WALL`""" C = CONSTANT - """Alias for :attr:`CONSTANT`""" P = PARAMETER - """Alias for :attr:`PARAMETER`""" T = TERM - """Alias for :attr:`TERM`""" I = INTERNAL - """Alias for :attr:`INTERNAL`""" + CONST = CONSTANT - """Alias for :attr:`CONSTANT`""" PARAM = PARAMETER - """Alias for :attr:`PARAMETER`""" - + @add_get(abbrev=True) class LocationType(Enum): @@ -124,30 +127,25 @@ class LocationType(Enum): The following types are defined, and aliases of just the first character are also defined. - - .. rubric:: Valid values - + .. rubric:: Enum Members .. autosummary:: - PIPE TANK - .. rubric:: Class methods - + .. rubric:: Class Methods .. autosummary:: - + :nosignatures: + get - """ PIPE = 1 """The expression describes a reaction in pipes""" TANK = 2 """The expression describes a reaction in tanks""" + P = PIPE - """Alias for :attr:`PIPE`""" T = TANK - """Alias for :attr:`TANK`""" @add_get(abbrev=True) @@ -157,18 +155,16 @@ class DynamicsType(Enum): The following types are defined, and aliases of just the first character are also defined. - .. rubric:: Valid values - + .. rubric:: Enum Members .. autosummary:: - EQUIL RATE FORMULA - .. rubric:: Class methods - + .. rubric:: Class Methods .. autosummary:: - + :nosignatures: + get """ @@ -179,27 +175,26 @@ class DynamicsType(Enum): """used to supply the equation that expresses the rate of change of the given species with respect to time as a function of the other species in the model""" FORMULA = 3 """used when the concentration of the named species is a simple function of the remaining species""" + E = EQUIL - """Alias for :attr:`EQUIL`""" R = RATE - """Alias for :attr:`RATE`""" F = FORMULA - """Alias for :attr:`FORMULA`""" class ReactionVariable(ABC): """The base for a reaction variable. - """ - name: str - """The name (symbol) for the variable, must be a valid MSX name""" + Attributes + ---------- + name : str + The name (symbol) for the variable, must be a valid MSX name + """ def __str__(self) -> str: """Returns the name of the variable""" return self.name def __hash__(self) -> int: - """Makes the variable hashable by hashing the `str` representation""" return hash(str(self)) __variable_registry = None @@ -284,7 +279,7 @@ def to_symbolic(self, transformations=EXPR_TRANSFORMS): class ReactionDynamics(ABC): """The base for a reaction. - Parameters + Attributes ---------- species : str the name of the species whose reaction dynamics is being described @@ -294,13 +289,6 @@ class ReactionDynamics(ABC): the expression for the reaction dynamics (right-hand-side) """ - species: str - """The name of the species that this reaction describes""" - location: LocationType - """The location this reaction occurs (pipes vs tanks)""" - expression: str - """The expression for the reaction dynamics (or, the right-hand-side of the equation)""" - def __str__(self) -> str: """Names the reaction with the format `species-dot-location` (for example, ``PB2.pipe``)""" return self.to_key(self.species, self.location) @@ -375,6 +363,8 @@ def to_symbolic(self, transformations=EXPR_TRANSFORMS): class AbstractQualityModel(ABC): + """Abstract methods any water quality model should include.""" + @abstractmethod def variables(self, var_type=None): """Generator over all defined variables, optionally limited by variable type""" diff --git a/wntr/quality/library.py b/wntr/quality/library.py index 96bf00d5a..a233f5fae 100644 --- a/wntr/quality/library.py +++ b/wntr/quality/library.py @@ -21,7 +21,13 @@ # ===================== Nicotine-chlorine model # def nicotine() -> MultispeciesQualityModel: - """A nicotine-chlorine reaction model""" + """A nicotine-chlorine reaction model. + + Returns + ------- + MultispeciesQualityModel + a new model for a nicotine-chlorine reaction + """ msx = MultispeciesQualityModel() msx.name = "nicotine" msx.title = ("Nicotine - Chlorine reaction",) @@ -45,7 +51,13 @@ def nicotine() -> MultispeciesQualityModel: # ===================== Nicotine-chlorine reactive intermediate species # def nicotine_ri() -> MultispeciesQualityModel: - """A nicotine-chlorine reaction with a reactive intermediate""" + """A nicotine-chlorine reaction with a reactive intermediate. + + Returns + ------- + MultispeciesQualityModel + a new model for a nicotine-chlorine reaction with a reactive intermediate + """ msx = MultispeciesQualityModel() msx.name = "nicotine_ri" msx.title = ("Nicotine - Chlorine reaction with reactive intermediate",) @@ -85,12 +97,19 @@ def nicotine_ri() -> MultispeciesQualityModel: def lead_ppm() -> MultispeciesQualityModel: """A lead plumbosolvency model [BWMS20]_. + Returns + ------- + MultispeciesQualityModel + a new lead plumbosolvency model + + Notes + ----- + .. [BWMS20] J. B. Burkhardt, et al. (2020) "Framework for Modeling Lead in Premise Plumbing Systems Using EPANET". `Journal of water resources planning and management`. **146** (12). https://doi.org/10.1061/(asce)wr.1943-5452.0001304 - """ msx = MultispeciesQualityModel() msx.name = "lead_ppm" diff --git a/wntr/quality/multispecies.py b/wntr/quality/multispecies.py index 36d9f106c..4f9182cae 100644 --- a/wntr/quality/multispecies.py +++ b/wntr/quality/multispecies.py @@ -28,7 +28,7 @@ import wntr.quality.io from wntr.epanet.util import ENcomment from wntr.network.elements import Source -from wntr.network.model import WaterNetworkModel +from wntr.network.model import PatternRegistry, SourceRegistry, WaterNetworkModel from wntr.utils.citations import Citation from wntr.utils.disjoint_mapping import DisjointMapping, KeyExistsError @@ -65,6 +65,36 @@ class Species(ReactionVariable): + """A species in a multispecies water quality model. + + This is the abstract model for a water quality species. The preferred way + to create a new species is to use one of the following: + + - :meth:`MultispeciesQualityModel.add_bulk_species()` + - :meth:`MultispeciesQualityModel.add_wall_species()` + - :meth:`MultispeciesQualityModel.add_species()` + - :meth:`MultispeciesQualityModel.add_variable()` + + .. rubric:: Attributes + .. autosummary:: + name + units + note + diffusivity + var_type + """ + + name: str = None + """The name (symbol) for the variable, must be a valid MSX name""" + units: str = None + """The units used for concentration of this species""" + note: Union[str, Dict[str, str]] = None + """A note to go with this species""" + diffusivity: float = None + """A value for diffusivity for this species""" + initial_quality: float = None + """Global initial quality for this species""" + def __init__( self, name: str, @@ -73,11 +103,11 @@ def __init__( rtol: float = None, note: Union[str, Dict[str, str]] = None, diffusivity: float = None, + initial_quality: float = None, *, _qm: AbstractQualityModel = None, ): - """A species in a multispecies water quality model. - + """ Parameters ---------- name : str @@ -92,21 +122,18 @@ def __init__( A note about this species, by default None diffusivity : float, optional The diffusivity value for this species, by default None + initial_quality: float, optional + The global initial quality for this species, by default None - Keyword Args - ------------ - _qm : AbstractQualityModel, optional, keyword-only - the model this variable is being added to, by default None - - Raises - ------ - ValueError - if ``name`` is a reserved name + Other Parameters + ---------------- + _qm : MultispeciesQualityModel + the model to link with, used internally when created via the :meth:`~MultispeciesQualityModel.add_species()` API. """ if name in RESERVED_NAMES: raise ValueError("Name cannot be a reserved name") self.name = name - """The name (symbol) for the variable, must be a valid MSX name""" + """The name of the variable""" self.units = units """The units used for this species""" self.note = note @@ -204,25 +231,83 @@ def to_dict(self): class BulkSpecies(Species): - """A bulk species.""" + """A bulk species. + + The preferred way to create a new bulk species is to use one of the following: + + - :meth:`MultispeciesQualityModel.add_bulk_species()` + - :meth:`MultispeciesQualityModel.add_species()` + - :meth:`MultispeciesQualityModel.add_variable()` + + .. rubric:: Attributes + .. autosummary:: + name + units + note + diffusivity + var_type + """ @property - def var_type(self) -> VariableType: + def var_type(self): return VariableType.BULK class WallSpecies(Species): - """A wall species""" + """A wall species. + + The preferred way to create a new wall species is to use one of the following: + + - :meth:`MultispeciesQualityModel.add_wall_species()` + - :meth:`MultispeciesQualityModel.add_species()` + - :meth:`MultispeciesQualityModel.add_variable()` + + .. rubric:: Attributes + .. autosummary:: + name + units + note + diffusivity + var_type + """ @property - def var_type(self) -> VariableType: + def var_type(self): return VariableType.WALL class Coefficient(ReactionVariable): - def __init__(self, name: str, global_value: float, note: Union[str, Dict[str, str]] = None, units: str = None, *, _qm: AbstractQualityModel = None): - """A coefficient, either constant or parameterized by pipe or tank, that is used in reaction expressions. + """A coefficient, either constant or parameterized by pipe or tank, that is used in reaction expressions. + + This is the abstract model for a reaction expression coefficient. The preferred way + to create a new coefficient is to use one of the following: + + - :meth:`MultispeciesQualityModel.add_constant_coeff()` + - :meth:`MultispeciesQualityModel.add_parameterized_coeff()` + - :meth:`MultispeciesQualityModel.add_coefficient()` + - :meth:`MultispeciesQualityModel.add_variable()` + + .. rubric:: Attributes + .. autosummary:: + name + global_value + units + note + var_type + """ + + name: str = None + """The name (symbol) for the variable, must be a valid MSX name""" + units: str = None + """The units used for this variable""" + note: Union[str, Dict[str, str]] = None + """A note to go with this varibale""" + global_value: float = None + """The global value for the coefficient""" + + def __init__(self, name: str, global_value: float, note: Union[str, Dict[str, str]] = None, units: str = None, *, _qm: AbstractQualityModel = None): + """ Parameters ---------- name : str @@ -234,21 +319,15 @@ def __init__(self, name: str, global_value: float, note: Union[str, Dict[str, st units : str, optional units for this coefficient, by default None - Keyword Args - ------------ - _qm : AbstractQualityModel, optional, keyword-only - the model this variable is being added to, by default None - - Raises - ------ - ValueError - if ``name`` is a reserved name + Other Parameters + ---------------- + _qm : MultispeciesQualityModel + the model to link with, used internally when created via the :meth:`~MultispeciesQualityModel.add_coefficient()` API. """ - if name in RESERVED_NAMES: raise ValueError("Name cannot be a reserved name") self.name = name - """The name (symbol) for the variable, must be a valid MSX name""" + """The name of the variable""" self.global_value = float(global_value) """The global value for the coefficient""" self.note = note @@ -285,15 +364,47 @@ def to_dict(self): class Constant(Coefficient): - """A constant coefficient for reaction expressions.""" + """A constant coefficient for reaction expressions. + + The preferred way to create a constant coefficient is to use one of the following: + + - :meth:`MultispeciesQualityModel.add_constant_coeff()` + - :meth:`MultispeciesQualityModel.add_coefficient()` + - :meth:`MultispeciesQualityModel.add_variable()` + + .. rubric:: Attributes + .. autosummary:: + name + global_value + units + note + var_type + """ @property - def var_type(self) -> VariableType: + def var_type(self): return VariableType.CONST class Parameter(Coefficient): - """A variable parameter for reaction expressions.""" + """A variable parameter for reaction expressions. + + The preferred way to create a constant coefficient is to use one of the following: + + - :meth:`MultispeciesQualityModel.add_parameterized_coeff()` + - :meth:`MultispeciesQualityModel.add_coefficient()` + - :meth:`MultispeciesQualityModel.add_variable()` + + .. rubric:: Attributes + .. autosummary:: + name + global_value + units + note + var_type + pipe_values + tank_values + """ def __init__( self, @@ -306,8 +417,7 @@ def __init__( *, _qm: AbstractQualityModel = None, ): - """A coefficient, either constant or parameterized by pipe or tank, that is used in reaction expressions. - + """ Parameters ---------- name : str @@ -323,15 +433,10 @@ def __init__( tank_values : dict, optional the values of the parameter at specific tanks, by default None - Keyword Args - ------------ - _qm : AbstractQualityModel, optional, keyword-only - the model this variable is being added to, by default None - - Raises - ------ - ValueError - if ``name`` is a reserved name + Other Parameters + ---------------- + _qm : MultispeciesQualityModel + the model to link with, used internally when created via the :meth:`~MultispeciesQualityModel.add_coefficient()` API. """ super().__init__(name, global_value=global_value, note=note, units=units, _qm=_qm) self._pipe_values = pipe_values if pipe_values is not None else dict() @@ -352,7 +457,7 @@ def __eq__(self, other): return True @property - def var_type(self) -> VariableType: + def var_type(self): return VariableType.PARAM def get_value(self, pipe: str = None, tank: str = None) -> float: @@ -403,23 +508,27 @@ def to_dict(self): @dataclass(repr=False) class OtherTerm(ReactionVariable): - """A function definition used as a shortcut in reaction expressions (called a 'term' in EPANET-MSX) - - Parameters - ---------- - name : str - the name/symbol of the function (term) - expression : str - the mathematical expression described by this function - note : str, optional - a note for this function, by default None - - Keyword Args - ------------ - _qm : AbstractQualityModel, optional, keyword-only - the model this variable is being added to, by default None + """An expression term defined as a function of species, coefficients, or other terms. + + The preferred way to create a term is to use one of the following: + + - :meth:`MultispeciesQualityModel.add_other_term()` + - :meth:`MultispeciesQualityModel.add_variable()` + + .. rubric:: Attributes + .. autosummary:: + name + expression + note """ + name: str = None + """The name (symbol) for the variable, must be a valid MSX name""" + expression: str = None + """The mathematical expression this term represents""" + note: Union[str, Dict[str, str]] = None + """A note to go with this term""" + def __init__( self, name: str, @@ -428,10 +537,25 @@ def __init__( *, _qm: AbstractQualityModel = None, ): + """ + Parameters + ---------- + name : str + the name/symbol of the function (term) + expression : str + the mathematical expression described by this function + note : str, optional + a note for this function, by default None + + Other Parameters + ---------------- + _qm : MultispeciesQualityModel + the model to link with, used internally when created via the :meth:`~MultispeciesQualityModel.add_variable()` API. + """ if name in RESERVED_NAMES: raise ValueError("Name cannot be a reserved name") self.name = name - """The name (symbol) for the variable, must be a valid MSX name""" + """The name of the variable""" self.expression = expression """The expression this named-function is equivalent to""" self.note = note @@ -445,7 +569,7 @@ def __eq__(self, other): return isinstance(other, self.__class__) and self.name == other.name and self.expression == other.expression @property - def var_type(self) -> VariableType: + def var_type(self): return VariableType.TERM def to_symbolic(self, transformations=...): @@ -467,7 +591,23 @@ class InternalVariable(ReactionVariable): """A hydraulic variable or a placeholder for a built-in reserved word. For example, "Len" is the EPANET-MSX name for the length of a pipe, and "I" is a sympy - reserved symbol for the imaginary number.""" + reserved symbol for the imaginary number. + Objects of this type are instantiated when creating a new :class:`MultispeciesQualityModel`, + and should not need to be created by hand. + + .. rubric:: Attributes + .. autosummary:: + name + units + note + """ + + name: str = None + """The name (symbol) for the variable, must be a valid MSX name""" + units: str = None + """The units used for this variable""" + note: Union[str, Dict[str, str]] = None + """A note to go with this variable""" def __init__( self, @@ -475,8 +615,18 @@ def __init__( note: Union[str, Dict[str, str]] = "internal variable - not output to MSX", units: str = None, ): + """ + Parameters + ---------- + name : str + The name and symbol for the new variable + note : str or dict, optional + A note to go on the object, by default "internal variable - not output to MSX" + units : str, optional + Units used by values stored in this variable, by default None + """ self.name = name - """The name (symbol) for the variable, must be a valid MSX name""" + """The name of the variable""" self.note = note """A note about this function/term""" self.units = units @@ -489,7 +639,7 @@ def __eq__(self, other): return isinstance(other, self.__class__) and self.name == other.name @property - def var_type(self) -> VariableType: + def var_type(self): return VariableType.INTERNAL @@ -504,31 +654,52 @@ class RateDynamics(ReactionDynamics): \frac{d}{dt} C(species) = expression - Parameters - ---------- - species : str - the name of the species whose reaction dynamics is being described - location : RxnLocationType or str - the location the reaction occurs (pipes or tanks) - expression : str - the expression for the reaction dynamics, which is the rate-of-change of the species concentration - note : str, optional - a note about this reaction - - Keyword Args - ------------ - _qm : AbstractQualityModel, optional, keyword-only - the model this variable is being added to, by default None + The preferred way to create a new reaction is to use one of: + + - :meth:`MultispeciesQualityModel.add_pipe_reaction()` + - :meth:`MultispeciesQualityModel.add_tank_reaction()` + - :meth:`MultispeciesQualityModel.add_reaction()` + + .. rubric:: Attributes + .. autosummary:: + ~RateDynamics.species + ~RateDynamics.location + ~RateDynamics.expression + ~RateDynamics.expr_type + ~RateDynamics.note """ def __init__(self, species: str, location: LocationType, expression: str, note: Union[str, Dict[str, str]] = None, *, _qm: AbstractQualityModel = None): + """ + Parameters + ---------- + species : str + the name of the species whose reaction dynamics is being described + location : RxnLocationType or str + the location the reaction occurs (pipes or tanks) + expression : str + the expression for the reaction dynamics, which should equal to zero + note : str, optional + a note about this reaction + + Other Parameters + ---------------- + _qm : MultispeciesQualityModel + the model to link with, used internally when created via the :meth:`~MultispeciesQualityModel.add_reaction()` API. + """ self.species = species + """Name of the species being described""" self.location = location + """Location this reaction occurs""" self.expression = expression + """The expression""" self.note = note """A note or comment about this species reaction dynamics""" self._variable_registry = _qm + def __eq__(self, other): + return isinstance(other, self.__class__) and self.name == other.name and self.location == other.location and self.expression == other.expression + @property def expr_type(self) -> DynamicsType: return DynamicsType.RATE @@ -557,32 +728,53 @@ class EquilibriumDynamics(ReactionDynamics): 0 = expression - Parameters - ---------- - species : str - the name of the species whose reaction dynamics is being described - location : RxnLocationType or str - the location the reaction occurs (pipes or tanks) - expression : str - the expression for the reaction dynamics, which should equal to zero - note : str, optional - a note about this reaction - - Keyword Args - ------------ - _qm : AbstractQualityModel, optional, keyword-only - the model this variable is being added to, by default None + The preferred way to create a new reaction is to use one of: + + - :meth:`MultispeciesQualityModel.add_pipe_reaction()` + - :meth:`MultispeciesQualityModel.add_tank_reaction()` + - :meth:`MultispeciesQualityModel.add_reaction()` + + .. rubric:: Attributes + .. autosummary:: + ~EquilibriumDynamics.species + ~EquilibriumDynamics.location + ~EquilibriumDynamics.expression + ~EquilibriumDynamics.expr_type + ~EquilibriumDynamics.note """ def __init__(self, species: str, location: LocationType, expression: str, note: Union[str, Dict[str, str]] = None, *, _qm: AbstractQualityModel = None): + """ + Parameters + ---------- + species : str + the name of the species whose reaction dynamics is being described + location : RxnLocationType or str + the location the reaction occurs (pipes or tanks) + expression : str + the expression for the reaction dynamics, which should equal to zero + note : str, optional + a note about this reaction + + Other Parameters + ---------------- + _qm : MultispeciesQualityModel + the model to link with, used internally when created via the :meth:`~MultispeciesQualityModel.add_reaction()` API. + """ self.species = species + """Name of the species being described""" self.location = location + """Location this reaction occurs""" self.expression = expression + """The expression""" self.note = note """A note or comment about this species reaction dynamics""" self._variable_registry = _qm + def __eq__(self, other): + return isinstance(other, self.__class__) and self.name == other.name and self.location == other.location and self.expression == other.expression + @property def expr_type(self) -> DynamicsType: return DynamicsType.EQUIL @@ -603,7 +795,7 @@ def to_dict(self) -> dict: @dataclass(repr=False) class FormulaDynamics(ReactionDynamics): - """A formula based reaction dynamics. + """A formula-based reaction dynamics expression. Used when the concentration of the named species is a simple function of the remaining species. @@ -611,31 +803,52 @@ class FormulaDynamics(ReactionDynamics): C(species) = expression - Parameters - ---------- - species : str - the name of the species whose reaction dynamics is being described - location : RxnLocationType or str - the location the reaction occurs (pipes or tanks) - expression : str - the expression for the reaction formula, which is used to calculate the concentration of the species - note : str, optional - a note about this reaction - - Keyword Args - ------------ - _qm : RxnModelRegistry, optional - a link to the remainder of the larger model + The preferred way to create a new reaction is to use one of: + + - :meth:`MultispeciesQualityModel.add_pipe_reaction()` + - :meth:`MultispeciesQualityModel.add_tank_reaction()` + - :meth:`MultispeciesQualityModel.add_reaction()` + + .. rubric:: Attributes + .. autosummary:: + ~FormulaDynamics.species + ~FormulaDynamics.location + ~FormulaDynamics.expression + ~FormulaDynamics.expr_type + ~FormulaDynamics.note """ def __init__(self, species: str, location: LocationType, expression: str, note: Union[str, Dict[str, str]] = None, *, _qm: AbstractQualityModel = None): + """ + Parameters + ---------- + species : str + the name of the species whose reaction dynamics is being described + location : RxnLocationType or str + the location the reaction occurs (pipes or tanks) + expression : str + the expression for the reaction formula, which is used to calculate the concentration of the species + note : str, optional + a note about this reaction + + Other Parameters + ---------------- + _qm : MultispeciesQualityModel + the model to link with, used internally when created via the :meth:`~MultispeciesQualityModel.add_reaction()` API. + """ self.species = species + """Name of the species being described""" self.location = location + """Location this reaction occurs""" self.expression = expression + """The expression""" self.note = note """A note or comment about this species reaction dynamics""" self._variable_registry = _qm + def __eq__(self, other): + return isinstance(other, self.__class__) and self.name == other.name and self.location == other.location and self.expression == other.expression + @property def expr_type(self) -> DynamicsType: return DynamicsType.FORMULA @@ -655,14 +868,23 @@ def to_dict(self) -> dict: class MultispeciesQualityModel(AbstractQualityModel): + """A multispecies water quality reactions model, for use with EPANET-MSX. + + .. rubric:: Attributes + .. autosummary:: + ~MultispeciesQualityModel.name + ~MultispeciesQualityModel.title + ~MultispeciesQualityModel.citations + ~MultispeciesQualityModel.options + """ + def __init__(self, msx_file_name=None): - """Water quality reactions model object. + """Create a new multispecies water quality reaction model. Parameters ---------- msx_file_name : str, optional The name of the MSX input file to read - """ self.name: str = None """A one-line title for the model""" @@ -698,9 +920,10 @@ def __init__(self, msx_file_name=None): self._usage: Dict[str, Set[str]] = dict() # FIXME: currently no usage tracking - self._sources: Dict[str, Dict[str, Source]] = dict() - self._inital_quality: Dict[str, Dict[str, Dict[str, float]]] = dict() - self._patterns: Dict[str, Any] = dict() + self._source_dict: Dict[str, Dict[str, Source]] = dict() + self._inital_qual_dict: Dict[str, Dict[str, Dict[str, float]]] = dict() + self._pattern_dict: Dict[str, List[float]] = dict() + self._report = list() for v in HYDRAULIC_VARIABLES: @@ -823,8 +1046,8 @@ def add_variable(self, var_or_type: Union[ReactionVariable, VariableType], name: __variable._variable_registry = self if typ is VariableType.BULK or typ is VariableType.WALL: self._variables.add_item_to_group("species", name, __variable) - self._inital_quality[name] = dict(global_value=None, nodes=dict(), links=dict()) - self._sources[name] = dict() + self._inital_qual_dict[name] = dict(global_value=None, nodes=dict(), links=dict()) + self._source_dict[name] = dict() elif typ is VariableType.CONST or typ is VariableType.PARAM: self._variables.add_item_to_group("coeffs", name, __variable) elif typ is VariableType.TERM: @@ -834,7 +1057,7 @@ def add_variable(self, var_or_type: Union[ReactionVariable, VariableType], name: def add_species( self, - species_type: Union[str, Literal[VariableType.BULK], Literal[VariableType.WALL]], + species_type: Union[str, int, VariableType], name: str, units: str, atol: float = None, @@ -885,8 +1108,8 @@ def add_species( elif species_type is VariableType.WALL: var = WallSpecies(name=name, units=units, atol=atol, rtol=rtol, note=note, _qm=self) self._species[name] = var - self._inital_quality[name] = dict([("global", None), ("nodes", dict()), ("links", dict())]) - self._sources[name] = dict() + self._inital_qual_dict[name] = dict([("global", None), ("nodes", dict()), ("links", dict())]) + self._source_dict[name] = dict() return var def add_bulk_species(self, name: str, units: str, atol: float = None, rtol: float = None, note: str = None) -> BulkSpecies: @@ -952,7 +1175,7 @@ def add_wall_species(self, name: str, units: str, atol: float = None, rtol: floa return self.add_species(VariableType.WALL, name, units, atol, rtol, note) def add_coefficient( - self, coeff_type: Union[str, Literal[VariableType.CONST], Literal[VariableType.PARAM]], name: str, global_value: float, note: str = None, units: str = None, **kwargs + self, coeff_type: Union[str, int, VariableType], name: str, global_value: float, note: str = None, units: str = None, **kwargs ) -> Coefficient: """Add a new coefficient to the model. @@ -1102,10 +1325,10 @@ def remove_variable(self, name: str): name : str variable name """ - if name in self._inital_quality.keys(): - self._inital_quality.__delitem__(name) - if name in self._sources.keys(): - self._sources.__delitem__(name) + if name in self._inital_qual_dict.keys(): + self._inital_qual_dict.__delitem__(name) + if name in self._source_dict.keys(): + self._source_dict.__delitem__(name) return self._variables.__delitem__(name) def get_variable(self, name: str) -> ReactionVariable: @@ -1308,12 +1531,17 @@ def get_reaction(self, species, location): ReactionDynamics the requested reaction object """ + if species is None: + raise TypeError('species must be a string or Species') + if location is None: + raise TypeError('location must be a string, int, or LocationType') species = str(species) location = LocationType.get(location) + loc = location.name.lower() if location == LocationType.PIPE: - return self._pipe_dynamics.get(species, None) + return self._pipe_dynamics.get(species+'.'+loc) elif location == LocationType.TANK: - return self._tank_dynamics.get(species, None) + return self._tank_dynamics.get(species+'.'+loc) def init_printing(self, *args, **kwargs): """Call sympy.init_printing""" @@ -1345,9 +1573,6 @@ def options(self, value): def link_water_network_model(self, wn: WaterNetworkModel): self._wn = wn - def add_pattern(self, name, pat): - self._patterns[name] = pat - def to_dict(self) -> dict: """Convert this water quality model to a dictionary""" wntr.quality.io.to_dict() diff --git a/wntr/quality/options.py b/wntr/quality/options.py index 00656d325..d17f49846 100644 --- a/wntr/quality/options.py +++ b/wntr/quality/options.py @@ -78,36 +78,29 @@ class MultispeciesOptions(_OptionsBase): ---------- timestep : int >= 1 Water quality timestep (seconds), by default 60 (one minute). - area_units : str, optional The units of area to use in surface concentration forms, by default ``M2``. Valid values are ``FT2``, ``M2``, or ``CM2``. - rate_units : str, optional The time units to use in all rate reactions, by default ``MIN``. Valid values are ``SEC``, ``MIN``, ``HR``, or ``DAY``. - solver : str, optional The solver to use, by default ``RK5``. Options are ``RK5`` (5th order Runge-Kutta method), ``ROS2`` (2nd order Rosenbrock method), or ``EUL`` (Euler method). - coupling : str, optional Use coupling method for solution, by default ``NONE``. Valid options are ``FULL`` or ``NONE``. - atol : float, optional Absolute concentration tolerance, by default 0.01 (regardless of species concentration units). - rtol : float, optional Relative concentration tolerance, by default 0.001 (±0.1%). - compiler : str, optional Whether to use a compiler, by default ``NONE``. Valid options are ``VC``, ``GC``, or ``NONE`` - segments : int, optional Maximum number of segments per pipe (MSX 2.0 or newer only), by default 5000. - peclet : int, optional Peclet threshold for applying dispersion (MSX 2.0 or newer only), by default 1000. - - report : ReportOptions - Contains options for how for format and save report + + Other Parameters + ---------------- + report : ReportOptions or dict + Options on how to report out results. """ @@ -123,30 +116,31 @@ def __init__( compiler: str = "NONE", segments: int = 5000, peclet: int = 1000, - global_initial_quality: Dict[str, float] = None, + # global_initial_quality: Dict[str, float] = None, report: ReportOptions = None, ): - self.timestep = timestep + self.timestep: int = timestep """The timestep, in seconds, by default 360""" - self.area_units = area_units + self.area_units: str = area_units """The units used to express pipe wall surface area where, by default FT2. Valid values are FT2, M2, and CM2.""" - self.rate_units = rate_units + self.rate_units: str = rate_units """The units in which all reaction rate terms are expressed, by default HR. Valid values are HR, MIN, SEC, and DAY.""" - self.solver = solver + self.solver: str = solver """The solver to use, by default EUL. Valid values are EUL, RK5, and ROS2.""" - self.coupling = coupling + self.coupling: str = coupling """Whether coupling should occur during solving, by default NONE. Valid values are NONE and FULL.""" - self.rtol = rtol + self.rtol: float = rtol """The relative tolerance used during solvers ROS2 and RK5, by default 0.001 for all species. Can be overridden on a per-species basis.""" - self.atol = atol + self.atol: float = atol """The absolute tolerance used by the solvers, by default 0.01 for all species regardless of concentration units. Can be overridden on a per-species basis.""" - self.compiler = compiler + self.compiler: str = compiler """A compier to use if the equations should be compiled by EPANET-MSX, by default NONE. Valid options are VC, GC and NONE.""" - self.segments = segments + self.segments: int = segments """The number of segments per-pipe to use, by default 5000.""" - self.peclet = peclet + self.peclet: int = peclet """The threshold for applying dispersion, by default 1000.""" - self.report = ReportOptions.factory(report) + self.report: ReportOptions = ReportOptions.factory(report) + """The reporting output options.""" def __setattr__(self, name, value): if name == "report": diff --git a/wntr/tests/networks_for_testing/msx_example.inp b/wntr/tests/networks_for_testing/msx_example.inp new file mode 100644 index 000000000..0887e00db --- /dev/null +++ b/wntr/tests/networks_for_testing/msx_example.inp @@ -0,0 +1,36 @@ +[TITLE] +EPANET-MSX Example Network + +[JUNCTIONS] +;ID Elev Demand Pattern + A 0 4.1 + B 0 3.4 + C 0 5.5 + D 0 2.3 + +[RESERVOIRS] +;ID Head Pattern + Source 100 + +[PIPES] +;ID Node1 Node2 Length Diameter Roughness + 1 Source A 1000 200 100 + 2 A B 800 150 100 + 3 A C 1200 200 100 + 4 B C 1000 150 100 + 5 C D 2000 150 100 + +[TIMES] + Duration 48 + Hydraulic Timestep 1:00 + Quality Timestep 0:05 + Report Timestep 2 + Report Start 0 + Statistic NONE + +[OPTIONS] + Units CMH + Headloss H-W + Quality NONE + +[END] diff --git a/wntr/tests/networks_for_testing/msx_example.msx b/wntr/tests/networks_for_testing/msx_example.msx new file mode 100644 index 000000000..b20e0854b --- /dev/null +++ b/wntr/tests/networks_for_testing/msx_example.msx @@ -0,0 +1,58 @@ +[TITLE] +Arsenic Oxidation/Adsorption Example + +[OPTIONS] + AREA_UNITS M2 ;Surface concentration is mass/m2 + RATE_UNITS HR ;Reaction rates are concentration/hour + SOLVER RK5 ;5-th order Runge-Kutta integrator + TIMESTEP 360 ;360 sec (5 min) solution time step + RTOL 0.001 ;Relative concentration tolerance + ATOL 0.0001 ;Absolute concentration tolerance + +[SPECIES] + BULK AS3 UG ;Dissolved arsenite + BULK AS5 UG ;Dissolved arsenate + BULK AStot UG ;Total dissolved arsenic + WALL AS5s UG ;Adsorbed arsenate + BULK NH2CL MG ;Monochloramine + +[COEFFICIENTS] + CONSTANT Ka 10.0 ;Arsenite oxidation rate coefficient + CONSTANT Kb 0.1 ;Monochloramine decay rate coefficient + CONSTANT K1 5.0 ;Arsenate adsorption coefficient + CONSTANT K2 1.0 ;Arsenate desorption coefficient + CONSTANT Smax 50 ;Arsenate adsorption saturation limit + +[TERMS] + Ks K1/K2 ;Equil. adsorption coeff. + +[PIPES] + ;Arsenite oxidation + RATE AS3 -Ka*AS3*NH2CL + ;Arsenate production + RATE AS5 Ka*AS3*NH2CL - Av*(K1*(Smax-AS5s)*AS5 - K2*AS5s) + ;Monochloramine decay + RATE NH2CL -Kb*NH2CL + ;Arsenate adsorption + EQUIL AS5s Ks*Smax*AS5/(1+Ks*AS5) - AS5s + ;Total bulk arsenic + FORMULA AStot AS3 + AS5 + +[TANKS] + RATE AS3 -Ka*AS3*NH2CL + RATE AS5 Ka*AS3*NH2CL + RATE NH2CL -Kb*NH2CL + FORMULA AStot AS3 + AS5 + +[QUALITY] + ;Initial conditions (= 0 if not specified here) + NODE Source AS3 10.0 + NODE Source NH2CL 2.5 + +[REPORT] + NODES C D ;Report results for nodes C and D + LINKS 5 ;Report results for pipe 5 + SPECIES AStot YES ;Report results for each specie + SPECIES AS5 YES + SPECIES AS5s YES + SPECIES NH2CL YES diff --git a/wntr/tests/test_epanet_msx_io.py b/wntr/tests/test_epanet_msx_io.py new file mode 100644 index 000000000..0bcf73a2e --- /dev/null +++ b/wntr/tests/test_epanet_msx_io.py @@ -0,0 +1,42 @@ +import unittest +import warnings +from os.path import abspath, dirname, join + +import numpy as np +import pandas as pd +import wntr +import wntr.quality +import wntr.epanet.msx +import sympy + +testdir = dirname(abspath(str(__file__))) +test_network_dir = join(testdir, "networks_for_testing") +inp_filename = join(test_network_dir, "msx_example.inp") +msx_filename = join(test_network_dir, "msx_example.msx") + + +class Test(unittest.TestCase): + @classmethod + def setUpClass(self): + pass + + @classmethod + def tearDownClass(self): + pass + + def test_msx_io(self): + wn_model = wntr.network.WaterNetworkModel(inp_file_name=inp_filename) + msx_model = wntr.quality.MultispeciesQualityModel(msx_file_name=msx_filename) + wntr.epanet.InpFile().write("test.inp", wn_model) + wntr.epanet.msx.MsxFile().write("test.msx", msx_model) + msx_model2 = wntr.quality.MultispeciesQualityModel(msx_file_name="test.msx") + true_vars = ["AS3", "AS5", "AS5s", "AStot", "Av", "D", "Ff", "K1", "K2", "Ka", "Kb", "Kc", "Ks", "Len", "NH2CL", "Q", "Re", "Smax", "U", "Us"] + in_vars = msx_model.variable_name_list + in_vars.sort() + io_vars = msx_model2.variable_name_list + io_vars.sort() + self.assertListEqual(true_vars, in_vars) + self.assertListEqual(true_vars, io_vars) + +if __name__ == "__main__": + unittest.main(verbosity=2) diff --git a/wntr/tests/test_epanet_msx_tooklit.py b/wntr/tests/test_epanet_msx_tooklit.py new file mode 100644 index 000000000..3191d3f0e --- /dev/null +++ b/wntr/tests/test_epanet_msx_tooklit.py @@ -0,0 +1,35 @@ +import unittest +import warnings +from os.path import abspath, dirname, join + +import numpy as np +import pandas as pd +import wntr +import wntr.quality +import wntr.epanet.msx +import wntr.epanet.msx.toolkit +import sympy + +testdir = dirname(abspath(str(__file__))) +test_network_dir = join(testdir, "networks_for_testing") +inp_filename = join(test_network_dir, 'msx_example.inp') +msx_filename = join(test_network_dir, 'msx_example.msx') + +class Test(unittest.TestCase): + @classmethod + def setUpClass(self): + pass + + @classmethod + def tearDownClass(self): + pass + + def test_msx_io(self): + wn_model = wntr.network.WaterNetworkModel(inp_file_name=inp_filename) + msx_model = wntr.quality.MultispeciesQualityModel(msx_file_name=msx_filename) + wntr.epanet.msx.toolkit.MSXepanet(inp_filename, msxfile=msx_filename) + + + +if __name__ == "__main__": + unittest.main(verbosity=2) diff --git a/wntr/utils/enumtools.py b/wntr/utils/enumtools.py index e44235c33..f853551a7 100644 --- a/wntr/utils/enumtools.py +++ b/wntr/utils/enumtools.py @@ -78,6 +78,8 @@ def get(cls, value: Union[str, int, Enum], prefix='', abbrev=False): ValueError if ``value`` is invalid """ + if value is None: + return None name = str(value) if isinstance(value, cls): return value From 8862e25fc248ba42a43c47274ed5224e3ec11fe8 Mon Sep 17 00:00:00 2001 From: dbhart Date: Fri, 6 Oct 2023 13:07:48 -0600 Subject: [PATCH 29/75] Update to documentation and library functionality --- documentation/conf.py | 1 + wntr/epanet/msx/io.py | 206 +++++++++++---------- wntr/quality/base.py | 196 +++++++++++++++++--- wntr/quality/library.py | 265 ++++++++++++++++++++++----- wntr/quality/multispecies.py | 316 +++++++++++++-------------------- wntr/utils/disjoint_mapping.py | 14 +- wntr/utils/enumtools.py | 44 ++--- 7 files changed, 664 insertions(+), 378 deletions(-) diff --git a/documentation/conf.py b/documentation/conf.py index 6c36a33df..ae2d52802 100644 --- a/documentation/conf.py +++ b/documentation/conf.py @@ -104,6 +104,7 @@ # The reST default role (used for this markup: `text`) to use for all # documents. #default_role = None +napoleon_custom_sections = ['Read-only Simulation Attributes', 'Class Methods', 'Enum Members', 'Model Description'] # If true, '()' will be appended to :func: etc. cross-reference text. #add_function_parentheses = True diff --git a/wntr/epanet/msx/io.py b/wntr/epanet/msx/io.py index 2d3329aec..0f25ab925 100644 --- a/wntr/epanet/msx/io.py +++ b/wntr/epanet/msx/io.py @@ -6,6 +6,10 @@ import sys from io import FileIO, TextIOWrapper +import numpy as np +import pandas as pd + +import wntr.network from wntr.epanet.msx.exceptions import EpanetMsxException from wntr.epanet.util import ENcomment from wntr.network.elements import Source @@ -33,6 +37,7 @@ "[DIFFUSIVITY]", "[PATTERNS]", "[REPORT]", + "[END]", ] @@ -61,7 +66,7 @@ class MsxFile(object): read write - + """ def __init__(self): @@ -134,21 +139,22 @@ def _read(): section = sec # logger.info('%(fname)s:%(lnum)-6d %(sec)13s section found' % edata) continue - elif sec == "[END]": - # logger.info('%(fname)s:%(lnum)-6d %(sec)13s end of file found' % edata) - section = None - break + # elif sec == "[END]": + # # logger.info('%(fname)s:%(lnum)-6d %(sec)13s end of file found' % edata) + # section = None + # break else: logger.warning('%(fname)s:%(lnum)d: Invalid section "%(sec)s"' % edata) - raise EpanetMsxException(201, note='at line {}:\n{}'.format(lnum, line)) + raise EpanetMsxException(201, note="at line {}:\n{}".format(lnum, line)) elif section is None and line.startswith(";"): obj.top_comments.append(line[1:]) continue elif section is None: logger.debug("Found confusing line: %s", repr(line)) - raise EpanetMsxException(201, note='at line {}:\n{}'.format(lnum, line)) + raise EpanetMsxException(201, note="at line {}:\n{}".format(lnum, line)) # We have text, and we are in a section obj.sections[section].append((lnum, line)) + try: _read() obj._read_title() @@ -164,6 +170,7 @@ def _read(): obj._read_diffusivity() obj._read_patterns() obj._read_report() + obj._read_end() return obj.rxn except Exception as e: raise EpanetMsxException(200) from e @@ -198,8 +205,17 @@ def write(cls, filename: str, msx: MultispeciesQualityModel): obj._write_parameters(fout) obj._write_patterns(fout) obj._write_report(fout) + obj._write_end(fout) fout.write("; END of MSX file generated by WNTR\n") + def _read_end(self): + pass + + def _write_end(self, fout): + fout.write("[END]\n") + pass + + def _read_title(self): lines = [] title = None @@ -247,13 +263,13 @@ def _read_options(self): elif name == "PECLET": self.rxn._options.peclet = int(val) else: - raise EpanetMsxException(403, note='at line {} of [OPTIONS] section:\n{}'.format(lnum, line)) + raise EpanetMsxException(403, note="at line {} of [OPTIONS] section:\n{}".format(lnum, line)) except ValueError: - raise EpanetMsxException(404, note='at line {} of [OPTIONS] section:\n{}'.format(lnum, line)) + raise EpanetMsxException(404, note="at line {} of [OPTIONS] section:\n{}".format(lnum, line)) except EpanetMsxException: raise except Exception as e: - raise EpanetMsxException(201, note='at line {} of [OPTIONS] section:\n{}'.format(lnum, line)) from e + raise EpanetMsxException(201, note="at line {} of [OPTIONS] section:\n{}".format(lnum, line)) from e def _read_species(self): lines = [] @@ -268,17 +284,17 @@ def _read_species(self): if comment is not None: note.post = comment if len(vals) < 3: - raise EpanetMsxException(402, note='at line {} of [SPECIES] section:\n{}'.format(lnum, line)) + raise EpanetMsxException(402, note="at line {} of [SPECIES] section:\n{}".format(lnum, line)) if len(vals) == 3: species = self.rxn.add_species(vals[0], vals[1], vals[2], note=note) elif len(vals) == 5: species = self.rxn.add_species(vals[0], vals[1], vals[2], float(vals[3]), float(vals[4]), note=note) else: - raise EpanetMsxException(201, note='at line {} of [SPECIES] section:\n{}'.format(lnum, line)) + raise EpanetMsxException(201, note="at line {} of [SPECIES] section:\n{}".format(lnum, line)) except EpanetMsxException: raise except Exception as e: - raise EpanetMsxException(201, note='at line {} of [SPECIES] section:\n{}'.format(lnum, line)) from e + raise EpanetMsxException(201, note="at line {} of [SPECIES] section:\n{}".format(lnum, line)) from e else: note = ENcomment() @@ -295,12 +311,12 @@ def _read_coefficients(self): if comment is not None: note.post = comment if len(vals) < 3: - raise EpanetMsxException(402, note='at line {} of [COEFFICIENTS] section:\n{}'.format(lnum, line)) + raise EpanetMsxException(402, note="at line {} of [COEFFICIENTS] section:\n{}".format(lnum, line)) coeff = self.rxn.add_coefficient(vals[0], vals[1], float(vals[2]), note=note) except EpanetMsxException: raise except Exception as e: - raise EpanetMsxException(201, note='at line {} of [COEFFICIENTS] section:\n{}'.format(lnum, line)) from e + raise EpanetMsxException(201, note="at line {} of [COEFFICIENTS] section:\n{}".format(lnum, line)) from e else: note = ENcomment() @@ -322,7 +338,7 @@ def _read_terms(self): except EpanetMsxException: raise except Exception as e: - raise EpanetMsxException(201, note='at line {} of [TERMS] section:\n{}'.format(lnum, line)) from e + raise EpanetMsxException(201, note="at line {} of [TERMS] section:\n{}".format(lnum, line)) from e else: note = ENcomment() @@ -344,7 +360,7 @@ def _read_pipes(self): except EpanetMsxException: raise except Exception as e: - raise EpanetMsxException(201, note='at line {} of [PIPES] section:\n{}'.format(lnum, line)) from e + raise EpanetMsxException(201, note="at line {} of [PIPES] section:\n{}".format(lnum, line)) from e else: note = ENcomment() @@ -366,7 +382,7 @@ def _read_tanks(self): except EpanetMsxException: raise except Exception as e: - raise EpanetMsxException(201, note='at line {} of [TANKS] section:\n{}'.format(lnum, line)) from e + raise EpanetMsxException(201, note="at line {} of [TANKS] section:\n{}".format(lnum, line)) from e else: note = ENcomment() @@ -396,7 +412,7 @@ def _read_source_dict(self): except EpanetMsxException: raise except Exception as e: - raise EpanetMsxException(201, note='at line {} of [SOURCES] section:\n{}'.format(lnum, line)) from e + raise EpanetMsxException(201, note="at line {} of [SOURCES] section:\n{}".format(lnum, line)) from e else: note = ENcomment() @@ -431,7 +447,7 @@ def _read_quality(self): except EpanetMsxException: raise except Exception as e: - raise EpanetMsxException(201, note='at line {} of [QUALITY] section:\n{}'.format(lnum, line)) from e + raise EpanetMsxException(201, note="at line {} of [QUALITY] section:\n{}".format(lnum, line)) from e else: note = ENcomment() @@ -461,7 +477,7 @@ def _read_parameters(self): except EpanetMsxException: raise except Exception as e: - raise EpanetMsxException(201, note='at line {} of [PARAMETERS] section:\n{}'.format(lnum, line)) from e + raise EpanetMsxException(201, note="at line {} of [PARAMETERS] section:\n{}".format(lnum, line)) from e else: note = ENcomment() @@ -486,7 +502,7 @@ def _read_diffusivity(self): except EpanetMsxException: raise except Exception as e: - raise EpanetMsxException(201, note='at line {} of [DIFFUSIVITIES] section:\n{}'.format(lnum, line)) from e + raise EpanetMsxException(201, note="at line {} of [DIFFUSIVITIES] section:\n{}".format(lnum, line)) from e else: note = ENcomment() @@ -566,7 +582,7 @@ def _read_report(self): except EpanetMsxException: raise except Exception as e: - raise EpanetMsxException(201, note='at line {} of [REPORT] section:\n{}'.format(lnum, line)) from e + raise EpanetMsxException(201, note="at line {} of [REPORT] section:\n{}".format(lnum, line)) from e else: note = ENcomment() @@ -592,6 +608,7 @@ def _write_options(self, fout): def _write_species(self, fout): fout.write("[SPECIES]\n") + def to_msx_string(self) -> str: tols = self.get_tolerances() if tols is None: @@ -604,6 +621,7 @@ def to_msx_string(self) -> str: self.units, tolstr, ) + for var in self.rxn.variables(var_type=VariableType.BULK): if isinstance(var.note, ENcomment): fout.write("{}\n".format(var.note.wrap_msx_string(to_msx_string(var)))) @@ -622,17 +640,14 @@ def to_msx_string(self) -> str: def _write_coefficients(self, fout): fout.write("[COEFFICIENTS]\n") + def to_msx_string(self) -> str: # if self.units is not None: # post = r' ; {"units"="' + str(self.units) + r'"}' # else: - post = '' - return "{:<12s} {:<8s} {:<16s}{}".format( - self.var_type.name.upper(), - self.name, - str(self.global_value), - post - ) + post = "" + return "{:<12s} {:<8s} {:<16s}{}".format(self.var_type.name.upper(), self.name, str(self.global_value), post) + for var in self.rxn.variables(var_type=VariableType.CONST): if isinstance(var.note, ENcomment): fout.write("{}\n".format(var.note.wrap_msx_string(to_msx_string(var)))) @@ -651,8 +666,10 @@ def to_msx_string(self) -> str: def _write_terms(self, fout): fout.write("[TERMS]\n") + def to_msx_string(self) -> str: return "{:<8s} {:<64s}".format(self.name, self.expression) + for var in self.rxn.variables(var_type=VariableType.TERM): if isinstance(var.note, ENcomment): fout.write("{}\n".format(var.note.wrap_msx_string(to_msx_string(var)))) @@ -785,76 +802,69 @@ def _write_report(self, fout): fout.write(" PAGESIZE {}\n".format(self.rxn._options.report.pagesize)) fout.write("\n") -import numpy as np -import pandas as pd - -import wntr.network - def MsxBinFile(filename, wn: wntr.network.WaterNetworkModel): duration = int(wn.options.time.duration) - - with open(filename, 'rb') as fin: - ftype = '=f4' - idlen = 32 - prolog = np.fromfile(fin, dtype = np.int32, count=6) - magic1 = prolog[0] - version = prolog[1] - nnodes = prolog[2] - nlinks = prolog[3] - nspecies = prolog[4] - reportstep = prolog[5] - species_list = [] - node_list = wn.node_name_list - link_list = wn.link_name_list - - for i in range(nspecies): - species_len = int(np.fromfile(fin, dtype = np.int32, count=1)) - species_name = ''.join(chr(f) for f in np.fromfile(fin, dtype = np.uint8, count=species_len) if f!=0) - species_list.append(species_name) - species_mass = [] - for i in range(nspecies): - species_mass.append(''.join(chr(f) for f in np.fromfile(fin, dtype = np.uint8, count=16) if f != 0)) - timerange = range(0, duration+1, reportstep) - - tr = len(timerange) - - row1 = ['node']*nnodes*len(species_list)+['link']*nlinks*len(species_list) - row2 = [] - for i in [nnodes,nlinks]: - for j in species_list: - row2.append([j]*i) - row2 = [y for x in row2 for y in x] - row3 = [node_list for i in species_list] + [link_list for i in species_list] - row3 = [y for x in row3 for y in x] - - tuples = list(zip(row1, row2, row3)) - index = pd.MultiIndex.from_tuples(tuples, names = ['type','species','name']) - - try: - data = np.fromfile(fin, dtype = np.dtype(ftype), count = tr*(len(species_list*(nnodes + nlinks)))) - data = np.reshape(data, (tr, len(species_list*(nnodes + nlinks)))) - except Exception as e: - print(e) - print ("oops") - - postlog = np.fromfile(fin, dtype = np.int32, count=4) - offset = postlog[0] - numreport = postlog[1] - errorcode = postlog[2] - magicnew = postlog[3] - if errorcode !=0: - print(f'ERROR CODE: {errorcode}') - print(offset, numreport) - - df_fin = pd.DataFrame(index=index, columns=timerange).transpose() - if magic1 == magicnew: - # print("Magic# Match") - df_fin = pd.DataFrame(data.transpose(), index=index, columns=timerange) - df_fin = df_fin.transpose() - - else: - print("Magic#s do not match!") - return df_fin + with open(filename, "rb") as fin: + ftype = "=f4" + idlen = 32 + prolog = np.fromfile(fin, dtype=np.int32, count=6) + magic1 = prolog[0] + version = prolog[1] + nnodes = prolog[2] + nlinks = prolog[3] + nspecies = prolog[4] + reportstep = prolog[5] + species_list = [] + node_list = wn.node_name_list + link_list = wn.link_name_list + + for i in range(nspecies): + species_len = int(np.fromfile(fin, dtype=np.int32, count=1)) + species_name = "".join(chr(f) for f in np.fromfile(fin, dtype=np.uint8, count=species_len) if f != 0) + species_list.append(species_name) + species_mass = [] + for i in range(nspecies): + species_mass.append("".join(chr(f) for f in np.fromfile(fin, dtype=np.uint8, count=16) if f != 0)) + timerange = range(0, duration + 1, reportstep) + + tr = len(timerange) + + row1 = ["node"] * nnodes * len(species_list) + ["link"] * nlinks * len(species_list) + row2 = [] + for i in [nnodes, nlinks]: + for j in species_list: + row2.append([j] * i) + row2 = [y for x in row2 for y in x] + row3 = [node_list for i in species_list] + [link_list for i in species_list] + row3 = [y for x in row3 for y in x] + + tuples = list(zip(row1, row2, row3)) + index = pd.MultiIndex.from_tuples(tuples, names=["type", "species", "name"]) + try: + data = np.fromfile(fin, dtype=np.dtype(ftype), count=tr * (len(species_list * (nnodes + nlinks)))) + data = np.reshape(data, (tr, len(species_list * (nnodes + nlinks)))) + except Exception as e: + print(e) + print("oops") + + postlog = np.fromfile(fin, dtype=np.int32, count=4) + offset = postlog[0] + numreport = postlog[1] + errorcode = postlog[2] + magicnew = postlog[3] + if errorcode != 0: + print(f"ERROR CODE: {errorcode}") + print(offset, numreport) + + df_fin = pd.DataFrame(index=index, columns=timerange).transpose() + if magic1 == magicnew: + # print("Magic# Match") + df_fin = pd.DataFrame(data.transpose(), index=index, columns=timerange) + df_fin = df_fin.transpose() + + else: + print("Magic#s do not match!") + return df_fin diff --git a/wntr/quality/base.py b/wntr/quality/base.py index b217dd91d..45b758511 100644 --- a/wntr/quality/base.py +++ b/wntr/quality/base.py @@ -1,7 +1,6 @@ # -*- coding: utf-8 -*- -""" -The base classes for the the wntr.reaction module. +"""The base classes for the the WNTR quality extensions module. Other than the enum classes, the classes in this module are all abstract and/or mixin classes, and should not be instantiated directly. """ @@ -13,7 +12,7 @@ from collections.abc import MutableMapping from dataclasses import InitVar, dataclass from enum import Enum, IntFlag -from typing import ClassVar, Generator, List, Union +from typing import Any, ClassVar, Dict, Generator, List, Union import numpy as np @@ -26,17 +25,32 @@ has_sympy = False try: - from sympy import Float, Symbol, init_printing, symbols + from sympy import Float, Symbol, init_printing, symbols, Function, Mul, Add, Pow, Integer + from sympy.functions import cos, sin, tan, cot, Abs, sign, sqrt, log, exp, asin, acos, atan, acot, sinh, cosh, tanh, coth, Heaviside from sympy.parsing import parse_expr - from sympy.parsing.sympy_parser import convert_xor, standard_transformations - + from sympy.parsing.sympy_parser import convert_xor, standard_transformations, auto_number, auto_symbol + class _log10(Function): + @classmethod + def eval(cls, x): + return log(x, 10) has_sympy = True except ImportError: sympy = None + has_sympy = False logging.critical("This python installation does not have SymPy installed. Certain functionality will be disabled.") standard_transformations = (None,) convert_xor = None - has_sympy = False + if not has_sympy: + from numpy import cos, sin, tan, abs, sign, sqrt, log, exp, arcsin, arccos, arctan, sinh, cosh, tanh, heaviside, log10 + cot = lambda x : 1 / tan(x) + Abs = abs + asin = arcsin + acos = arccos + atan = arctan + acot = lambda x : 1 / arctan(1 / x) + coth = lambda x : 1 / tanh(x) + Heaviside = heaviside + _log10 = log10 logger = logging.getLogger(__name__) @@ -44,7 +58,7 @@ {"name": "D", "note": "pipe diameter (feet or meters) "}, { "name": "Kc", - "note": "pipe roughness coefcient (unitless for Hazen-Williams or Chezy-Manning head loss formulas, millifeet or millimeters for Darcy-Weisbach head loss formula)", + "note": "pipe roughness coefficient (unitless for Hazen-Williams or Chezy-Manning head loss formulas, millifeet or millimeters for Darcy-Weisbach head loss formula)", }, {"name": "Q", "note": "pipe flow rate (flow units) "}, {"name": "U", "note": "pipe flow velocity (ft/sec or m/sec) "}, @@ -55,18 +69,150 @@ {"name": "Len", "note": "Pipe length (feet or meters)"}, ] """The hydraulic variables defined in EPANET-MSX. +For reference, the valid values are provided in :numref:`table-msx-hyd-vars`. + +.. _table-msx-hyd-vars: +.. table:: Valid hydraulic variables in multispecies quality model expressions. + + ============== ================================================ + **Name** **Description** + -------------- ------------------------------------------------ + ``D`` pipe diameter + ``Kc`` pipe roughness coefficient + ``Q`` pipe flow rate + ``Re`` flow Reynolds number + ``Us`` pipe shear velocity + ``Ff`` Darcy-Weisbach friction factor + ``Av`` pipe surface area per unit volume + ``Len`` pipe length + ============== ================================================ + +:meta hide-value: +""" + +EXPR_FUNCTIONS = dict( + abs=abs, + sgn=sign, + sqrt=sqrt, + step=Heaviside, + log=log, + exp=exp, + sin=sin, + cos=cos, + tan=tan, + cot=cot, + asin=asin, + acos=acos, + atan=atan, + acot=acot, + sinh=sinh, + cosh=cosh, + tanh=tanh, + coth=coth, + log10=_log10, +) +"""Mathematical functions available for use in expressions. See +:numref:`table-msx-funcs` for a list and description of the +different functions recognized. These names, case insensitive, are +considered invalid when naming variables. + +Additionally, the following SymPy names - ``Mul``, ``Add``, ``Pow``, +``Integer``, ``Float`` - are used to convert numbers and symbolic +functions; therefore, these five words, case sensitive, are also invalid +for use as variable names. + +.. _table-msx-funcs: +.. table:: Functions defined for use in EPANET-MSX expressions. + + ============== ================================================================ + **Name** **Description** + -------------- ---------------------------------------------------------------- + ``abs`` absolute value (:func:`~sympy.functions.Abs`) + ``sgn`` sign (:func:`~sympy.functions.sign`) + ``sqrt`` square-root + ``step`` step function (:func:`~sympy.functions.Heaviside`) + ``exp`` natural number, `e`, raised to a power + ``log`` natural logarithm + ``log10`` base-10 logarithm (defined as internal function) + ``sin`` sine + ``cos`` cosine + ``tan`` tangent + ``cot`` cotangent + ``asin`` arcsine + ``acos`` arccosine + ``atan`` arctangent + ``acot`` arccotangent + ``sinh`` hyperbolic sine + ``cosh`` hyperbolic cosine + ``tanh`` hyperbolic tangent + ``coth`` hyperbolic cotangent + ``*`` multiplication (:func:`~sympy.Mul`) + ``/`` division (:func:`~sympy.Mul`) + ``+`` addition (:func:`~sympy.Add`) + ``-`` negation and subtraction (:func:`~sympy.Add`) + ``^`` power/exponents (:func:`~sympy.Pow`) + ``(``, ``)`` groupings and function parameters + `numbers` literal values (:func:`~sympy.Float` and :func:`~sympy.Integer`) + ============== ================================================================ :meta hide-value: """ -RESERVED_NAMES = tuple([v["name"] for v in HYDRAULIC_VARIABLES]) -"""The MSX reserved names.""" +RESERVED_NAMES = ( + tuple([v["name"] for v in HYDRAULIC_VARIABLES]) + + tuple([k for k, v in EXPR_FUNCTIONS.items()]) + + tuple([k.upper() for k, v in EXPR_FUNCTIONS.items()]) + + tuple([k.capitalize() for k, v in EXPR_FUNCTIONS.items()]) + + ('Mul', 'Add', 'Pow', 'Integer', 'Float') +) +"""The WNTR reserved names. This includes the MSX hydraulic variables +(see :numref:`table-msx-hyd-vars`) and the MSX defined functions +(see :numref:`table-msx-funcs`). -SYMPY_RESERVED = ("E", "I", "pi") -"""Some extra names reserved by sympy""" +:meta hide-value: +""" -EXPR_TRANSFORMS = standard_transformations + (convert_xor,) -"""The sympy transforms to use in expression parsing. +_global_dict = dict() +for k, v in EXPR_FUNCTIONS.items(): + _global_dict[k] = v + _global_dict[k.lower()] = v + _global_dict[k.capitalize()] = v + _global_dict[k.upper()] = v +for v in HYDRAULIC_VARIABLES: + _global_dict[v["name"]] = symbols(v["name"]) +_global_dict['Mul'] = Mul +_global_dict['Add'] = Add +_global_dict['Pow'] = Pow +_global_dict['Integer'] = Integer +_global_dict['Float'] = Float + +EXPR_TRANSFORMS = ( + auto_symbol, + auto_number, + convert_xor, +) +"""The sympy transforms to use in expression parsing. See +:numref:`table-sympy-transformations` for the list of transformations. + +.. _table-sympy-transformations: +.. table:: Transformations used by WNTR when parsing expressions using SymPy. + + ========================================== ================== + **Transformation** **Is used?** + ------------------------------------------ ------------------ + ``lambda_notation`` No + ``auto_symbol`` Yes + ``repeated_decimals`` No + ``auto_number`` Yes + ``factorial_notation`` No + ``implicit_multiplication_application`` No + ``convert_xor`` Yes + ``implicit_application`` No + ``implicit_multiplication`` No + ``convert_equals_signs`` No + ``function_exponentiation`` No + ``rationalize`` No + ========================================== ================== :meta hide-value: """ @@ -118,7 +264,7 @@ class VariableType(Enum): CONST = CONSTANT PARAM = PARAMETER - + @add_get(abbrev=True) class LocationType(Enum): @@ -135,7 +281,7 @@ class LocationType(Enum): .. rubric:: Class Methods .. autosummary:: :nosignatures: - + get """ @@ -157,6 +303,7 @@ class DynamicsType(Enum): .. rubric:: Enum Members .. autosummary:: + EQUIL RATE FORMULA @@ -164,7 +311,7 @@ class DynamicsType(Enum): .. rubric:: Class Methods .. autosummary:: :nosignatures: - + get """ @@ -346,20 +493,22 @@ def to_key(cls, species, location): return str(species) + "." + location.name.lower() @abstractmethod - def to_symbolic(self, transformations=EXPR_TRANSFORMS): + def to_symbolic(self, transformations: tuple = EXPR_TRANSFORMS): """Convert to a symbolic expression. Parameters ---------- transformations : tuple of sympy transformations - transformations to apply to the expression, by default EXPR_TRANSFORMS + transformations to apply to the expression, by default :data:`EXPR_TRANSFORMS` Returns ------- - sympy.Expr + sympy.Expr or sympy.Symbol the expression parsed by sympy """ - return parse_expr(self.expression, transformations=transformations) + if not has_sympy: + return self.expression + return parse_expr(self.expression, local_dict=self._variable_registry.variable_dict() if self._variable_registry is not None else None, transformations=transformations, global_dict=_global_dict, evaluate=False) class AbstractQualityModel(ABC): @@ -370,6 +519,11 @@ def variables(self, var_type=None): """Generator over all defined variables, optionally limited by variable type""" raise NotImplementedError + @abstractmethod + def variable_dict(self) -> Dict[str, Any]: + """Create a dictionary of variable names and their sympy represenations""" + raise NotImplementedError + @abstractmethod def add_variable(self, __variable: ReactionVariable): """Add a variable *object* to the model""" diff --git a/wntr/quality/library.py b/wntr/quality/library.py index a233f5fae..df8bae011 100644 --- a/wntr/quality/library.py +++ b/wntr/quality/library.py @@ -2,85 +2,216 @@ # @Contributors: # Jonathan Burkhardt, U.S. Environmental Protection Agency, Office of Research and Development -""" -A library of common reactions. -Values in libarary are for test purposes ONLY. These highlight the reaction form/relationship -but not necessarily the specific system kinetics. Citations are provided where appropriate for -sources of values or models. In most cases updates will be necessary to use for different -models - that is, sources, pipes, nodes are for a given network, and must be updated for different -models. +r"""A library of common multispecies reactions. + +Values in libarary are currently for test purposes only. These highlight the +reaction form/relationships but do not provide the specific system kinetics. +In all cases, updates will be necessary to use a specific model with a specific +network; that is, sources, pipes, nodes are for a given network, and must be +updated for different water network models. Citations are provided for the +reaction values and models. + +Notes +----- +.. important:: + + The docstrings you will write will likely use mathematics, as with the + models already provided. You will need to make them "raw" strings - e.g., + ``r'''docstring'''``. This is because most LaTeX commands will use ``\`` + characters in the commands, which can mess up documentation unless the docstrings + are specified as raw, not interpreted, text. +.. important:: + + Make sure to provide all appropriate citations to the model in your creation + function. """ + import logging from wntr.utils.citations import Citation from wntr.quality.multispecies import MultispeciesQualityModel +from wntr.network.model import WaterNetworkModel logger = logging.getLogger(__name__) + +########################################## +## +## IMPORTANT NOTE FOR CONTRIBUTORS +## +## The docstrings you write will likely use mathematics, as with the models already provided. +## you will need to make them "raw" strings -- i.e., r"""adocstring""" +## This is because most latex/mathjax formats use \ characters, which mess up docscrape +## unless you mark the string as raw, not interpreted, text. +## + +# FIXME: Need to actually do the checks and adding to the wn + + # ===================== Nicotine-chlorine model # -def nicotine() -> MultispeciesQualityModel: - """A nicotine-chlorine reaction model. - +def nicotine(wn: WaterNetworkModel = None) -> MultispeciesQualityModel: + r"""Create a new nicotine-chlorine reaction model, and optionally attach it to a water network model. + + Parameters + ---------- + wn : WaterNetworkModel, optional + the water network to use to hold the new or updated reaction model, by default None + Returns ------- MultispeciesQualityModel - a new model for a nicotine-chlorine reaction + the new or updated reaction/quality model + + Model Description + ----------------- + This model defines a simple nicotine-chlorine reaction. The model only defines bulk species + and does not specify any tank reactions. There is no reactive intermediate species in this + implementation, see :func:`nicotine_ri` for a model with a reactive intermediary. + + Bulk species + .. math:: + + Nx &:= \mathrm{mg}_\mathrm{(Nic)}~\text{[nicotine]} \\ + HOCL &:= \mathrm{mg}_\mathrm{(Cl)}~\text{[chlorine]} + + Coefficients + .. math:: + + k_d &= 2.33 \times 10^{-3}~\mathrm{min}^{-1} \\ + K_1 &= 5.92 \times 10^{-2}~\mathrm{L}\cdot\mathrm{min}^{-1}\cdot\mathrm{mg}_{\mathrm{(Nic)}}^{-1} \\ + K_2 &= 1.83 \times 10^{-1}~\mathrm{L}\cdot\mathrm{min}^{-1}\cdot\mathrm{mg}_{\mathrm{(Cl)}}^{-1} + + Other terms + .. math:: + + RxCl &= k_d \cdot HOCL + K_1 \cdot Nx \cdot HOCL \\ + RxN &= K_2 \cdot Nx \cdot HOCL + + Pipe reactions + .. math:: + + \frac{d}{dt}Nx &= -RxN \\ + \frac{d}{dt}HOCL &= -RxCl + + The tank reactions are not explicitly defined in this model. + + + Notes + ----- + If a water network is provided that does not have an ``msx`` attribute, then a new model will be + created and added to the network. The new model will also be returned as an object. + + If a water network is provided that already has an ``msx`` attribute, then this function will: + first check to see if there are variables that are in conflict with the existing reaction + model. If there are conflicts, an exception will be raised. The :attr:`~MultispeciesOptions.area_units` + and :attr:`~MultispeciesOptions.rate_units` will also be checked for conflicts, and an exception raised + if they differ from the already-existing units. + If there are no conflicts, then the variables and reactions for this model will be added to the + existing model. If there are conflicts, then the user must resolve them and try again. """ msx = MultispeciesQualityModel() msx.name = "nicotine" msx.title = ("Nicotine - Chlorine reaction",) - msx.options.area_units = "M2" - msx.options.rate_units = "MIN" + msx.options.area_units = "m2" + msx.options.rate_units = "min" msx.options.timestep = 1 - msx.add_bulk_species("Nx", units="MG", note="Nicotine") - msx.add_bulk_species("HOCL", units="MG", note="Free chlorine") + msx.add_bulk_species("Nx", units="mg", note="Nicotine") + msx.add_bulk_species("HOCL", units="mg", note="Free chlorine") msx.add_constant_coeff("kd", global_value=2.33e-3, units="min^(-1)", note="decay rate") msx.add_constant_coeff("K1", global_value=5.92e-2, units="L * min^(-1) * mg^(-1)", note="decay constant for chlorine as function of mass(Nic)") msx.add_constant_coeff("K2", global_value=1.84e-1, units="L * min^(-1) * mg^(-1)", note="decay constant for nicotine as function of mass(Cl)") - msx.add_other_term("RXCL", expression="kd * HOCL + K1 * Nx * HOCL") - msx.add_other_term("RXN", expression="K2 * Nx * HOCL") - msx.add_pipe_reaction("Nx", "rate", expression="-RXN") - msx.add_pipe_reaction("HOCL", "rate", expression="-RXCL") - msx.add_tank_reaction("Nx", "rate", "0") - msx.add_tank_reaction("HOCL", "rate", "0") + msx.add_other_term("RxCl", expression="kd * HOCL + K1 * Nx * HOCL") + msx.add_other_term("RxN", expression="K2 * Nx * HOCL") + msx.add_pipe_reaction("Nx", "rate", expression="-RxN") + msx.add_pipe_reaction("HOCL", "rate", expression="-RxCl") return msx # ===================== Nicotine-chlorine reactive intermediate species # -def nicotine_ri() -> MultispeciesQualityModel: - """A nicotine-chlorine reaction with a reactive intermediate. +def nicotine_ri(wn: WaterNetworkModel = None) -> MultispeciesQualityModel: + r"""A nicotine-chlorine reaction with a reactive intermediate. + Parameters + ---------- + wn : WaterNetworkModel, optional + the water network to use to hold the new or updated reaction model, by default None + Returns ------- MultispeciesQualityModel - a new model for a nicotine-chlorine reaction with a reactive intermediate + the new or updated reaction/quality model + + Model Description + ----------------- + This model defines a simple nicotine-chlorine reaction with a reactive intermediate species. + The model only defines bulk species, and the pipe and tank reactions use the same expressions. + For a simpler model, see :func:`nicotine`. + + Bulk species + .. math:: + Nx &:= \mathrm{mg}_\mathrm{(Nic)}~\text{[nicotine]} \\ + HOCL &:= \mathrm{mg}_\mathrm{(Cl)}~\text{[chlorine]} \\ + NX2 &:= \mathrm{mg}_\mathrm{(Nic_2)}~\text{[reaction~intermediary]} + + Coefficients + .. math:: + k_d &= 3.0 \times 10^{-5}~\mathrm{min}^{-1} \\ + K_1 &= 9.75 \times 10^{-2}~\mathrm{L}\cdot\mathrm{min}^{-1}\cdot\mathrm{mg}_{\mathrm{(Nic)}}^{-1}\\ + K_2 &= 5.73 \times 10^{-1}~\mathrm{L}\cdot\mathrm{min}^{-1}\cdot\mathrm{mg}_{\mathrm{(Cl)}}^{-1}\\ + K_3 &= 1.34 \times 10^{-2}~\mathrm{L}\cdot\mathrm{min}^{-1}\cdot\mathrm{mg}_{\mathrm{(Nic_2)}}^{-1}\\ + K_4 &= 2.19 \times 10^{-2}~\mathrm{L}\cdot\mathrm{min}^{-1}\cdot\mathrm{mg}_{\mathrm{(Cl)}}^{-1} + + Other terms + .. math:: + RXCL &= k_d \cdot HOCL + K_1 \cdot Nx \cdot HOCL + K_3 \cdot NX2 \cdot HOCL\\ + RXN &= K_2 \cdot Nx \cdot HOCL\\ + RXNX2 &= K_2 \cdot Nx \cdot HOCL - K_4 \cdot NX2 \cdot HOCL + + Pipe reactions and tank reactions *(defined separately for pipe and tank)* + .. math:: + \frac{d}{dt}Nx &= -RXN\\ + \frac{d}{dt}HOCL &= -RXCL\\ + \frac{d}{dt}HOCL &= RXNX2 + + Notes + ----- + If a water network is provided that does not have an ``msx`` attribute, then a new model will be + created and added to the network. The new model will also be returned as an object. + + If a water network is provided that already has an ``msx`` attribute, then this function will: + first check to see if there are variables that are in conflict with the existing reaction + model. If there are conflicts, an exception will be raised. The :attr:`~MultispeciesOptions.area_units` + and :attr:`~MultispeciesOptions.rate_units` will also be checked for conflicts, and an exception raised + if they differ. + If there are no conflicts, then the variables and reactions for this model will be added to the + existing model. If there are conflicts, then the user must resolve them and try again. """ msx = MultispeciesQualityModel() msx.name = "nicotine_ri" msx.title = ("Nicotine - Chlorine reaction with reactive intermediate",) # Set the options - msx.options.area_units = "M2" - msx.options.rate_units = "MIN" + msx.options.area_units = "m2" + msx.options.rate_units = "min" msx.options.timestep = 1 msx.options.atol = 1.0e-10 msx.options.rtol = 1.0e-10 # Add species - msx.add_bulk_species("Nx", units="MG", note="Nicotine") - msx.add_bulk_species("HOCL", units="MG", note="Free Chlorine") - msx.add_bulk_species("NX2", units="MG", note="Intermediate Nicotine Reactive") + msx.add_bulk_species("Nx", units="mg", note="Nicotine") + msx.add_bulk_species("HOCL", units="mg", note="Free Chlorine") + msx.add_bulk_species("NX2", units="mg", note="Intermediate Nicotine Reactive") # Add coefficients msx.add_constant_coeff("kd", 3.0e-5, note="decay rate", units="1/min") msx.add_constant_coeff("K1", global_value=9.75e-2, units="L * min^(-1) * mg^(-1)", note="decay constant for chlorine as function of mass(Nic)") msx.add_constant_coeff("K2", global_value=5.73e-1, units="L * min^(-1) * mg^(-1)", note="decay constant for nicotine as function of mass(Cl)") - msx.add_constant_coeff("K3", global_value=1.34e-2, units="L * min^(-1) * mg^(-1)", note="decay constant for nicotine as function of mass(N2)") + msx.add_constant_coeff("K3", global_value=1.34e-2, units="L * min^(-1) * mg^(-1)", note="decay constant for nicotine as function of mass(Nic2)") msx.add_constant_coeff("K4", global_value=2.19e-2, units="L * min^(-1) * mg^(-1)", note="decay constant for nicotine as function of mass(Cl)") # Add terms (named subexpressions) - msx.add_other_term("RXCL", expression="kd*HOCL + K1*Nx*HOCL + K3*NX2*HOCL") - msx.add_other_term("RXN", expression="K2*Nx*HOCL") - msx.add_other_term("RXNX2", expression="K2*Nx*HOCL - K4*NX2*HOCL") + msx.add_other_term("RXCL", expression="kd * HOCL + K1 * Nx * HOCL + K3 * NX2 * HOCL") + msx.add_other_term("RXN", expression="K2 * Nx * HOCL") + msx.add_other_term("RXNX2", expression="K2 * Nx * HOCL - K4 * NX2 * HOCL") # Add pipe reactions, one per species msx.add_pipe_reaction("Nx", "RATE", expression="-RXN") msx.add_pipe_reaction("HOCL", "RATE", expression="-RXCL") @@ -94,22 +225,76 @@ def nicotine_ri() -> MultispeciesQualityModel: # ===================== Lead plumbosolvency model # -def lead_ppm() -> MultispeciesQualityModel: - """A lead plumbosolvency model [BWMS20]_. +def lead_ppm(wn: WaterNetworkModel = None) -> MultispeciesQualityModel: + r"""A lead plumbosolvency model; please cite [BWMS20]_ if you use this model. + + Parameters + ---------- + wn : WaterNetworkModel, optional + the water network to use to hold the new or updated reaction model, by default None Returns ------- MultispeciesQualityModel - a new lead plumbosolvency model + the new or updated reaction/quality model - Notes - ----- + Model Description + ----------------- + This model is described in [BWMS20]_, and represents plumbosolvency of lead in lead pipes + within a dwelling. + + Bulk species + .. math:: + PB2 := \mathrm{μg}_\mathrm{(Pb)}~\text{[lead]} + + Coefficients + .. math:: + M &= 0.117~\mathrm{μg}_{\mathrm{(Pb)}} \cdot \mathrm{m}^{-2} \cdot \mathrm{s}^{-1} \\ + E &= 140.0~\mathrm{μg}_{\mathrm{(Pb)}} \cdot \mathrm{L}^{-1} + + Parameters [1]_ + .. math:: + F\langle pipe\rangle = \left\{\begin{matrix}1&\mathrm{if}~pipe~\mathrm{is~lead},\\0&\mathrm{otherwise}\end{matrix}\right. + + Pipe reactions [2]_ + .. math:: + \frac{d}{dt}PB2 = F \cdot Av \cdot M \frac{\left( E - PB2 \right)}{E} + + Tank reactions + .. math:: + \frac{d}{dt}PB2 = 0 + + References + ---------- + If this model is used, please cite the following paper(s). .. [BWMS20] J. B. Burkhardt, et al. (2020) "Framework for Modeling Lead in Premise Plumbing Systems Using EPANET". `Journal of water resources planning and management`. **146** (12). https://doi.org/10.1061/(asce)wr.1943-5452.0001304 + + Notes + ----- + If a water network is provided that does not have an ``msx`` attribute, then a new model will be + created and added to the network. The new model will also be returned as an object. + + If a water network is provided that already has an ``msx`` attribute, then this function will: + first check to see if there are variables that are in conflict with the existing reaction + model. If there are conflicts, an exception will be raised. The :attr:`~MultispeciesOptions.area_units` + and :attr:`~MultispeciesOptions.rate_units` will also be checked for conflicts, and an exception raised + if they differ. + If there are no conflicts, then the variables and reactions for this model will be added to the + existing model. If there are conflicts, then the user must resolve them and try again. + + .. [1] + The default value of a parameter is specified by "otherwise" in its mathematical definition. Because + the values of a parameter are network dependent, the non-global values will need to be added to any + parameter after the model is added to a network. + .. [2] + The hydraulic variable, :math:`Av`, is the surface area per unit volume (area units/L) of the pipe + where the reaction is taking place. See :numref:`table-msx-hyd-vars` for a list of valid names + for hydraulic variables that can be used in quality expressions. """ msx = MultispeciesQualityModel() msx.name = "lead_ppm" @@ -159,9 +344,9 @@ def lead_ppm() -> MultispeciesQualityModel: "atol": 1e-08, } msx.add_bulk_species("PB2", "ug", note="dissolved lead (Pb)") - msx.add_constant_coeff("M", global_value=0.117, note="Desorption rate (ug/m^2/s)", units="ug * m^(-1) * s^(-1)") + msx.add_constant_coeff("M", global_value=0.117, note="Desorption rate (ug/m^2/s)", units="ug * m^(-2) * s^(-1)") msx.add_constant_coeff("E", global_value=140.0, note="saturation/plumbosolvency level (ug/L)", units="ug/L") msx.add_parameterized_coeff("F", global_value=0, note="determines which pipes have reactions") - msx.add_pipe_reaction("PB2", "RATE", expression="F*Av*M*(E - PB2)/E") + msx.add_pipe_reaction("PB2", "RATE", expression="F * Av * M * (E - PB2) / E") msx.add_tank_reaction("PB2", "RATE", expression="0") return msx diff --git a/wntr/quality/multispecies.py b/wntr/quality/multispecies.py index 4f9182cae..04c7882cc 100644 --- a/wntr/quality/multispecies.py +++ b/wntr/quality/multispecies.py @@ -36,7 +36,7 @@ EXPR_TRANSFORMS, HYDRAULIC_VARIABLES, RESERVED_NAMES, - SYMPY_RESERVED, + EXPR_FUNCTIONS, AbstractQualityModel, DynamicsType, LocationType, @@ -67,21 +67,14 @@ class Species(ReactionVariable): """A species in a multispecies water quality model. - This is the abstract model for a water quality species. The preferred way - to create a new species is to use one of the following: - - - :meth:`MultispeciesQualityModel.add_bulk_species()` - - :meth:`MultispeciesQualityModel.add_wall_species()` - - :meth:`MultispeciesQualityModel.add_species()` - - :meth:`MultispeciesQualityModel.add_variable()` - - .. rubric:: Attributes - .. autosummary:: - name - units - note - diffusivity - var_type + .. rubric:: Constructor + + The preferred way to create a new species is to use one of the following + functions from the :class:`MultispeciesQualityModel`: + :meth:`~MultispeciesQualityModel.add_bulk_species()`, + :meth:`~MultispeciesQualityModel.add_wall_species()`, + :meth:`~MultispeciesQualityModel.add_species()`, or + :meth:`~MultispeciesQualityModel.add_variable()`. """ name: str = None @@ -128,18 +121,20 @@ def __init__( Other Parameters ---------------- _qm : MultispeciesQualityModel - the model to link with, used internally when created via the :meth:`~MultispeciesQualityModel.add_species()` API. + the model to link with, populated automatically if the :class:`MultispeciesQualityModel` API is used, by default None """ if name in RESERVED_NAMES: raise ValueError("Name cannot be a reserved name") - self.name = name + self.name: str = name """The name of the variable""" - self.units = units + self.units: str = units """The units used for this species""" self.note = note """A note about this species, by default None""" - self.diffusivity = diffusivity + self.diffusivity: float = diffusivity """The diffusivity value for this species, by default None""" + self.initial_quality: float = initial_quality + """The global initial quality for this species, by default None (C=0.0)""" if atol is not None: atol = float(atol) if rtol is not None: @@ -233,19 +228,13 @@ def to_dict(self): class BulkSpecies(Species): """A bulk species. - The preferred way to create a new bulk species is to use one of the following: - - - :meth:`MultispeciesQualityModel.add_bulk_species()` - - :meth:`MultispeciesQualityModel.add_species()` - - :meth:`MultispeciesQualityModel.add_variable()` - - .. rubric:: Attributes - .. autosummary:: - name - units - note - diffusivity - var_type + .. rubric:: Constructor + + The preferred way to create a new bulk species is to use one of the following + functions from the :class:`MultispeciesQualityModel`: + :meth:`~MultispeciesQualityModel.add_bulk_species()`, + :meth:`~MultispeciesQualityModel.add_species()`, or + :meth:`~MultispeciesQualityModel.add_variable()`. """ @property @@ -255,20 +244,14 @@ def var_type(self): class WallSpecies(Species): """A wall species. - - The preferred way to create a new wall species is to use one of the following: - - - :meth:`MultispeciesQualityModel.add_wall_species()` - - :meth:`MultispeciesQualityModel.add_species()` - - :meth:`MultispeciesQualityModel.add_variable()` - - .. rubric:: Attributes - .. autosummary:: - name - units - note - diffusivity - var_type + + .. rubric:: Constructor + + The preferred way to create a new wall species is to use one of the following + functions from the :class:`MultispeciesQualityModel`: + :meth:`~MultispeciesQualityModel.add_wall_species()`, + :meth:`~MultispeciesQualityModel.add_species()`, or + :meth:`~MultispeciesQualityModel.add_variable()`. """ @property @@ -279,21 +262,14 @@ def var_type(self): class Coefficient(ReactionVariable): """A coefficient, either constant or parameterized by pipe or tank, that is used in reaction expressions. - This is the abstract model for a reaction expression coefficient. The preferred way - to create a new coefficient is to use one of the following: - - - :meth:`MultispeciesQualityModel.add_constant_coeff()` - - :meth:`MultispeciesQualityModel.add_parameterized_coeff()` - - :meth:`MultispeciesQualityModel.add_coefficient()` - - :meth:`MultispeciesQualityModel.add_variable()` - - .. rubric:: Attributes - .. autosummary:: - name - global_value - units - note - var_type + .. rubric:: Constructor + + The preferred way to create a new coefficient is to use one of the following + functions from the :class:`MultispeciesQualityModel`: + :meth:`~MultispeciesQualityModel.add_constant_coeff()`, + :meth:`~MultispeciesQualityModel.add_parameterized_coeff()`, + :meth:`~MultispeciesQualityModel.add_coefficient()`, or + :meth:`~MultispeciesQualityModel.add_variable()`. """ name: str = None @@ -305,7 +281,6 @@ class Coefficient(ReactionVariable): global_value: float = None """The global value for the coefficient""" - def __init__(self, name: str, global_value: float, note: Union[str, Dict[str, str]] = None, units: str = None, *, _qm: AbstractQualityModel = None): """ Parameters @@ -322,7 +297,7 @@ def __init__(self, name: str, global_value: float, note: Union[str, Dict[str, st Other Parameters ---------------- _qm : MultispeciesQualityModel - the model to link with, used internally when created via the :meth:`~MultispeciesQualityModel.add_coefficient()` API. + the model to link with, populated automatically if the :class:`MultispeciesQualityModel` API is used, by default None """ if name in RESERVED_NAMES: raise ValueError("Name cannot be a reserved name") @@ -365,20 +340,14 @@ def to_dict(self): class Constant(Coefficient): """A constant coefficient for reaction expressions. - - The preferred way to create a constant coefficient is to use one of the following: - - - :meth:`MultispeciesQualityModel.add_constant_coeff()` - - :meth:`MultispeciesQualityModel.add_coefficient()` - - :meth:`MultispeciesQualityModel.add_variable()` - - .. rubric:: Attributes - .. autosummary:: - name - global_value - units - note - var_type + + .. rubric:: Constructor + + The preferred way to create a new constant coefficient is to use one of the following + functions from the :class:`MultispeciesQualityModel`: + :meth:`~MultispeciesQualityModel.add_constant_coeff()`, + :meth:`~MultispeciesQualityModel.add_coefficient()`, or + :meth:`~MultispeciesQualityModel.add_variable()`. """ @property @@ -388,22 +357,14 @@ def var_type(self): class Parameter(Coefficient): """A variable parameter for reaction expressions. - - The preferred way to create a constant coefficient is to use one of the following: - - - :meth:`MultispeciesQualityModel.add_parameterized_coeff()` - - :meth:`MultispeciesQualityModel.add_coefficient()` - - :meth:`MultispeciesQualityModel.add_variable()` - - .. rubric:: Attributes - .. autosummary:: - name - global_value - units - note - var_type - pipe_values - tank_values + + .. rubric:: Constructor + + The preferred way to create a new parameterized coefficient is to use one of the following + functions from the :class:`MultispeciesQualityModel`: + :meth:`~MultispeciesQualityModel.add_parameterized_coeff()`, + :meth:`~MultispeciesQualityModel.add_coefficient()`, or + :meth:`~MultispeciesQualityModel.add_variable()`. """ def __init__( @@ -436,7 +397,7 @@ def __init__( Other Parameters ---------------- _qm : MultispeciesQualityModel - the model to link with, used internally when created via the :meth:`~MultispeciesQualityModel.add_coefficient()` API. + the model to link with, populated automatically if the :class:`MultispeciesQualityModel` API is used, by default None """ super().__init__(name, global_value=global_value, note=note, units=units, _qm=_qm) self._pipe_values = pipe_values if pipe_values is not None else dict() @@ -510,16 +471,12 @@ def to_dict(self): class OtherTerm(ReactionVariable): """An expression term defined as a function of species, coefficients, or other terms. - The preferred way to create a term is to use one of the following: - - - :meth:`MultispeciesQualityModel.add_other_term()` - - :meth:`MultispeciesQualityModel.add_variable()` - - .. rubric:: Attributes - .. autosummary:: - name - expression - note + .. rubric:: Constructor + + The preferred way to create a new functional term is to use one of the following + functions from the :class:`MultispeciesQualityModel`: + :meth:`~MultispeciesQualityModel.add_other_term()` or + :meth:`~MultispeciesQualityModel.add_variable()`. """ name: str = None @@ -550,7 +507,7 @@ def __init__( Other Parameters ---------------- _qm : MultispeciesQualityModel - the model to link with, used internally when created via the :meth:`~MultispeciesQualityModel.add_variable()` API. + the model to link with, populated automatically if the :class:`MultispeciesQualityModel` API is used, by default None """ if name in RESERVED_NAMES: raise ValueError("Name cannot be a reserved name") @@ -572,8 +529,8 @@ def __eq__(self, other): def var_type(self): return VariableType.TERM - def to_symbolic(self, transformations=...): - return super().to_symbolic(transformations) + def to_symbolic(self): + return super().to_symbolic() def to_dict(self): rep = dict(name=self.name, expression=self.expression) @@ -592,14 +549,11 @@ class InternalVariable(ReactionVariable): For example, "Len" is the EPANET-MSX name for the length of a pipe, and "I" is a sympy reserved symbol for the imaginary number. - Objects of this type are instantiated when creating a new :class:`MultispeciesQualityModel`, - and should not need to be created by hand. + + .. rubric:: Constructor - .. rubric:: Attributes - .. autosummary:: - name - units - note + Objects of this type are instantiated when creating a new :class:`MultispeciesQualityModel`, + and should not need to be created by hand. """ name: str = None @@ -654,19 +608,13 @@ class RateDynamics(ReactionDynamics): \frac{d}{dt} C(species) = expression - The preferred way to create a new reaction is to use one of: - - - :meth:`MultispeciesQualityModel.add_pipe_reaction()` - - :meth:`MultispeciesQualityModel.add_tank_reaction()` - - :meth:`MultispeciesQualityModel.add_reaction()` - - .. rubric:: Attributes - .. autosummary:: - ~RateDynamics.species - ~RateDynamics.location - ~RateDynamics.expression - ~RateDynamics.expr_type - ~RateDynamics.note + .. rubric:: Constructor + + The preferred way to create a new rate reaction expression is to use one of the following + functions from the :class:`MultispeciesQualityModel`: + :meth:`~MultispeciesQualityModel.add_pipe_reaction()`, + :meth:`~MultispeciesQualityModel.add_tank_reaction()`, or + :meth:`~MultispeciesQualityModel.add_reaction()`. """ def __init__(self, species: str, location: LocationType, expression: str, note: Union[str, Dict[str, str]] = None, *, _qm: AbstractQualityModel = None): @@ -685,7 +633,7 @@ def __init__(self, species: str, location: LocationType, expression: str, note: Other Parameters ---------------- _qm : MultispeciesQualityModel - the model to link with, used internally when created via the :meth:`~MultispeciesQualityModel.add_reaction()` API. + the model to link with, populated automatically if the :class:`MultispeciesQualityModel` API is used, by default None """ self.species = species """Name of the species being described""" @@ -704,8 +652,8 @@ def __eq__(self, other): def expr_type(self) -> DynamicsType: return DynamicsType.RATE - def to_symbolic(self, transformations=...): - return super().to_symbolic(transformations) + def to_symbolic(self): + return super().to_symbolic() def to_dict(self) -> dict: rep = dict(species=self.species, expr_type=self.expr_type.name.lower(), expression=self.expression) @@ -728,20 +676,13 @@ class EquilibriumDynamics(ReactionDynamics): 0 = expression - The preferred way to create a new reaction is to use one of: - - - :meth:`MultispeciesQualityModel.add_pipe_reaction()` - - :meth:`MultispeciesQualityModel.add_tank_reaction()` - - :meth:`MultispeciesQualityModel.add_reaction()` - - - .. rubric:: Attributes - .. autosummary:: - ~EquilibriumDynamics.species - ~EquilibriumDynamics.location - ~EquilibriumDynamics.expression - ~EquilibriumDynamics.expr_type - ~EquilibriumDynamics.note + .. rubric:: Constructor + + The preferred way to create a new rate reaction expression is to use one of the following + functions from the :class:`MultispeciesQualityModel`: + :meth:`~MultispeciesQualityModel.add_pipe_reaction()`, + :meth:`~MultispeciesQualityModel.add_tank_reaction()`, or + :meth:`~MultispeciesQualityModel.add_reaction()`. """ def __init__(self, species: str, location: LocationType, expression: str, note: Union[str, Dict[str, str]] = None, *, _qm: AbstractQualityModel = None): @@ -760,7 +701,7 @@ def __init__(self, species: str, location: LocationType, expression: str, note: Other Parameters ---------------- _qm : MultispeciesQualityModel - the model to link with, used internally when created via the :meth:`~MultispeciesQualityModel.add_reaction()` API. + the model to link with, populated automatically if the :class:`MultispeciesQualityModel` API is used, by default None """ self.species = species """Name of the species being described""" @@ -779,8 +720,8 @@ def __eq__(self, other): def expr_type(self) -> DynamicsType: return DynamicsType.EQUIL - def to_symbolic(self, transformations=...): - return super().to_symbolic(transformations) + def to_symbolic(self): + return super().to_symbolic() def to_dict(self) -> dict: rep = dict(species=self.species, expr_type=self.expr_type.name.lower(), expression=self.expression) @@ -803,19 +744,13 @@ class FormulaDynamics(ReactionDynamics): C(species) = expression - The preferred way to create a new reaction is to use one of: - - - :meth:`MultispeciesQualityModel.add_pipe_reaction()` - - :meth:`MultispeciesQualityModel.add_tank_reaction()` - - :meth:`MultispeciesQualityModel.add_reaction()` - - .. rubric:: Attributes - .. autosummary:: - ~FormulaDynamics.species - ~FormulaDynamics.location - ~FormulaDynamics.expression - ~FormulaDynamics.expr_type - ~FormulaDynamics.note + .. rubric:: Constructor + + The preferred way to create a new rate reaction expression is to use one of the following + functions from the :class:`MultispeciesQualityModel`: + :meth:`~MultispeciesQualityModel.add_pipe_reaction()`, + :meth:`~MultispeciesQualityModel.add_tank_reaction()`, or + :meth:`~MultispeciesQualityModel.add_reaction()`. """ def __init__(self, species: str, location: LocationType, expression: str, note: Union[str, Dict[str, str]] = None, *, _qm: AbstractQualityModel = None): @@ -834,7 +769,7 @@ def __init__(self, species: str, location: LocationType, expression: str, note: Other Parameters ---------------- _qm : MultispeciesQualityModel - the model to link with, used internally when created via the :meth:`~MultispeciesQualityModel.add_reaction()` API. + the model to link with, populated automatically if the :class:`MultispeciesQualityModel` API is used, by default None """ self.species = species """Name of the species being described""" @@ -853,8 +788,8 @@ def __eq__(self, other): def expr_type(self) -> DynamicsType: return DynamicsType.FORMULA - def to_symbolic(self, transformations=...): - return super().to_symbolic(transformations) + def to_symbolic(self): + return super().to_symbolic() def to_dict(self) -> dict: rep = dict(species=self.species, expr_type=self.expr_type.name.lower(), expression=self.expression) @@ -869,13 +804,6 @@ def to_dict(self) -> dict: class MultispeciesQualityModel(AbstractQualityModel): """A multispecies water quality reactions model, for use with EPANET-MSX. - - .. rubric:: Attributes - .. autosummary:: - ~MultispeciesQualityModel.name - ~MultispeciesQualityModel.title - ~MultispeciesQualityModel.citations - ~MultispeciesQualityModel.options """ def __init__(self, msx_file_name=None): @@ -898,9 +826,6 @@ def __init__(self, msx_file_name=None): self._citations: List[Union[Citation, str]] = list() """A list of citations for the sources of this model's dynamics""" - self._allow_sympy_reserved_names: InitVar[bool] = True - """Allow sympy reserved names (I, E, pi)""" - self._options: InitVar[MultispeciesOptions] = None """A link to the options object""" @@ -923,14 +848,15 @@ def __init__(self, msx_file_name=None): self._source_dict: Dict[str, Dict[str, Source]] = dict() self._inital_qual_dict: Dict[str, Dict[str, Dict[str, float]]] = dict() self._pattern_dict: Dict[str, List[float]] = dict() - + self._report = list() for v in HYDRAULIC_VARIABLES: self._variables[v["name"]] = InternalVariable(v["name"], note=v["note"]) - if not self._allow_sympy_reserved_names: - for name in SYMPY_RESERVED: - self._variables[name] = InternalVariable(name, note="sympy reserved name") + for name in EXPR_FUNCTIONS.keys(): + self._variables[name.lower()] = InternalVariable(name, note="MSX function") + self._variables[name.upper()] = InternalVariable(name, note="MSX function") + self._variables[name.capitalize()] = InternalVariable(name, note="MSX function") if msx_file_name is not None: from wntr.epanet.msx.io import MsxFile @@ -958,24 +884,34 @@ def has_variable(self, name: str) -> bool: """ return name in self._variables.keys() + def variable_dict(self) -> Dict[str, Any]: + vars = dict() + for symb, spec in self._species.items(): + vars[symb] = symbols(symb) + for symb, coeff in self._coeffs.items(): + vars[symb] = symbols(symb) + for symb, term in self._terms.items(): + vars[symb] = symbols(symb) + return vars + @property def variable_name_list(self) -> List[str]: - """A list of all defined variable names""" + """all defined variable names""" return list(self._variables.keys()) @property def species_name_list(self) -> List[str]: - """A list of all defined species names""" + """all defined species names""" return list(self._species.keys()) @property def coefficient_name_list(self) -> List[str]: - """A list of all defined coefficient names""" + """all defined coefficient names""" return list(self._coeffs.keys()) @property def other_term_name_list(self) -> List[str]: - """A list of all defined function (MSX 'terms') names""" + """all defined function (MSX 'terms') names""" return list(self._terms.keys()) def variables(self, var_type: VariableType = None): @@ -1002,7 +938,7 @@ def add_variable(self, var_or_type: Union[ReactionVariable, VariableType], name: Parameters ---------- - var_or_type : RxnVariable or RxnVariableType + var_or_type : RxnVariable | RxnVariableType the variable object to add to the model, or the type if creating a new variable object name : str or None the name of a new variable, must be None if adding an existing object, by default None @@ -1069,7 +1005,7 @@ def add_species( Parameters ---------- - species_type : BULK or WALL + species_type : ~VariableType.BULK | ~VariableType.WALL the type of species name : str the name/symbol of the species @@ -1174,9 +1110,7 @@ def add_wall_species(self, name: str, units: str, atol: float = None, rtol: floa """ return self.add_species(VariableType.WALL, name, units, atol, rtol, note) - def add_coefficient( - self, coeff_type: Union[str, int, VariableType], name: str, global_value: float, note: str = None, units: str = None, **kwargs - ) -> Coefficient: + def add_coefficient(self, coeff_type: Union[str, int, VariableType], name: str, global_value: float, note: str = None, units: str = None, **kwargs) -> Coefficient: """Add a new coefficient to the model. Parameters @@ -1532,16 +1466,16 @@ def get_reaction(self, species, location): the requested reaction object """ if species is None: - raise TypeError('species must be a string or Species') + raise TypeError("species must be a string or Species") if location is None: - raise TypeError('location must be a string, int, or LocationType') + raise TypeError("location must be a string, int, or LocationType") species = str(species) location = LocationType.get(location) loc = location.name.lower() if location == LocationType.PIPE: - return self._pipe_dynamics.get(species+'.'+loc) + return self._pipe_dynamics.get(species + "." + loc) elif location == LocationType.TANK: - return self._tank_dynamics.get(species+'.'+loc) + return self._tank_dynamics.get(species + "." + loc) def init_printing(self, *args, **kwargs): """Call sympy.init_printing""" diff --git a/wntr/utils/disjoint_mapping.py b/wntr/utils/disjoint_mapping.py index fb767057d..8370f9d0c 100644 --- a/wntr/utils/disjoint_mapping.py +++ b/wntr/utils/disjoint_mapping.py @@ -52,8 +52,8 @@ def add_disjoint_group(self, name): def get_disjoint_group(self, name: str): return self.__groups[name] - def get_groupname(self, __key: Hashable): - return self.__key_groupnames[__key] + def get_groupname(self, _key: Hashable): + return self.__key_groupnames[_key] def add_item_to_group(self, groupname, key, value): current = self.__key_groupnames.get(key, None) @@ -153,21 +153,21 @@ class DisjointMappingGroup(MutableMapping): __keyspace: "DisjointMapping" = None _data: dict = None - def __new__(cls, name: str, __keyspace: "DisjointMapping"): + def __new__(cls, name: str, _keyspace: "DisjointMapping"): if name is None: raise TypeError("A name must be specified") - if __keyspace is None: + if _keyspace is None: raise TypeError("A registry must be specified") newobj = super().__new__(cls) return newobj - def __init__(self, name: str, __keyspace: "DisjointMapping"): + def __init__(self, name: str, _keyspace: "DisjointMapping"): if name is None: raise TypeError("A name must be specified") - if __keyspace is None: + if _keyspace is None: raise TypeError("A registry must be specified") self.__name: str = name - self.__keyspace: DisjointMapping = __keyspace + self.__keyspace: DisjointMapping = _keyspace self._data = dict() def __getitem__(self, __key: Any) -> Any: diff --git a/wntr/utils/enumtools.py b/wntr/utils/enumtools.py index f853551a7..8f02fe281 100644 --- a/wntr/utils/enumtools.py +++ b/wntr/utils/enumtools.py @@ -36,27 +36,6 @@ def wrap(cls, prefix, abbrev): def get(cls, value: Union[str, int, Enum], prefix='', abbrev=False): """Get the proper enum based on the name or value of the argument. - The get method behaves as follows. - For an integer, the integer value will be used to select the proper member. - For an :class:`Enum` object, the object's ``name`` will be used, and it will - be processed as a string. For a string, the method will: - - 1. capitalize the string - 2. remove leading or trailing spaces - 3. convert interior spaces or dashes to underscores - 4. optionally, remove a specified prefix from a string (using ``prefix``, which - should have a default assigned by the :func:`wntr.utils.enumtools.add_get` - function.) - - It will then try to get the member with the name corresponding to the converted - string. - - 5. optionally, if ``abbrev`` is True, then the string will be truncated to the first - letter, only, after trying to use the full string as passed in. The ``abbrev`` - parameter will have a default value based on how the :func:`~wntr.utils.enumtools.add_get` - decorator was called on this class. - - Parameters ---------- value : Union[str, int, Enum] @@ -77,6 +56,29 @@ def get(cls, value: Union[str, int, Enum], prefix='', abbrev=False): if ``value`` is an invalid type ValueError if ``value`` is invalid + + Notes + ----- + The get method behaves as follows. + For an integer, the integer value will be used to select the proper member. + For an :class:`Enum` object, the object's ``name`` will be used, and it will + be processed as a string. For a string, the method will: + + 1. capitalize the string + 2. remove leading or trailing spaces + 3. convert interior spaces or dashes to underscores + 4. optionally, remove a specified prefix from a string (using ``prefix``, which + should have a default assigned by the :func:`wntr.utils.enumtools.add_get` + function.) + + It will then try to get the member with the name corresponding to the converted + string. + + 5. optionally, if ``abbrev`` is True, then the string will be truncated to the first + letter, only, after trying to use the full string as passed in. The ``abbrev`` + parameter will have a default value based on how the :func:`~wntr.utils.enumtools.add_get` + decorator was called on this class. + """ if value is None: return None From 6b73e6c4e63abe543c2d9ae59805510aaaf9f6f9 Mon Sep 17 00:00:00 2001 From: dbhart Date: Thu, 12 Oct 2023 12:53:13 -0600 Subject: [PATCH 30/75] Updates pulling MSX into the WaterNetworkModel * Added as a part of the WaterNetworkModel named "msx" * Made names consistent with wntr.network namings --- wntr/network/base.py | 2 +- wntr/network/model.py | 14 ++++++++++ wntr/network/options.py | 7 ----- wntr/quality/__init__.py | 4 +-- wntr/quality/base.py | 16 ++++++------ wntr/quality/multispecies.py | 48 ++++++++++++++++------------------ wntr/utils/disjoint_mapping.py | 9 +++++-- 7 files changed, 55 insertions(+), 45 deletions(-) diff --git a/wntr/network/base.py b/wntr/network/base.py index 1ce26e832..20ddc94eb 100644 --- a/wntr/network/base.py +++ b/wntr/network/base.py @@ -502,7 +502,7 @@ def status(self, status): @property def initial_quality(self): - """float or dict : The initial quality (concentration) at the node, or a dict of species and quality if multispecies""" + """float or dict : a dict of species and quality if multispecies is active""" if not self._initial_quality: return 0.0 return self._initial_quality diff --git a/wntr/network/model.py b/wntr/network/model.py index 346a01f8d..5fee95248 100644 --- a/wntr/network/model.py +++ b/wntr/network/model.py @@ -83,6 +83,7 @@ def __init__(self, inp_file_name=None): self._curve_reg = CurveRegistry(self) self._controls = OrderedDict() self._sources = SourceRegistry(self) + self._msx = None self._node_reg._finalize_(self) self._link_reg._finalize_(self) @@ -327,6 +328,19 @@ def gpvs(self): """Iterator over all general purpose valves (GPVs)""" return self._link_reg.gpvs + @property + def msx(self): + """A multispecies water quality model, if defined""" + return self._msx + + @msx.setter + def msx(self, msx): + if msx is None: + self._msx = None + from wntr.quality.base import AbstractQualityModel + if not isinstance(msx, AbstractQualityModel): + raise TypeError('Expected AbstractQualityModel (or derived), got {}'.format(type(msx))) + """ ### # ### Create blank, unregistered objects (for direct assignment) diff --git a/wntr/network/options.py b/wntr/network/options.py index a63127675..8daa855f2 100644 --- a/wntr/network/options.py +++ b/wntr/network/options.py @@ -1,13 +1,6 @@ """ The wntr.network.options module includes simulation options. -.. note:: - - This module has been changed in version 0.2.3 to incorporate the new options - that EPANET 2.2 requires. It also reorganizes certain options to better align - with EPANET nomenclature. This change is not backwards compatible, particularly - when trying to use pickle files with older options. - .. rubric:: Classes .. autosummary:: diff --git a/wntr/quality/__init__.py b/wntr/quality/__init__.py index 5f7c85291..52691d7c7 100644 --- a/wntr/quality/__init__.py +++ b/wntr/quality/__init__.py @@ -9,8 +9,8 @@ from .base import ( DynamicsType, LocationType, - ReactionDynamics, - ReactionVariable, + AbstractReaction, + AbstractVariable, VariableType, ) from .multispecies import FormulaDynamics diff --git a/wntr/quality/base.py b/wntr/quality/base.py index 45b758511..bd8bc3cf9 100644 --- a/wntr/quality/base.py +++ b/wntr/quality/base.py @@ -252,7 +252,7 @@ class VariableType(Enum): """A coefficient that has a value dependent on the pipe or tank""" TERM = 16 """A term that is aliased for ease of writing expressions""" - INTERNAL = 32 + EXTERNAL = 32 """An internal variable - see :attr:`~wntr.reaction.base.RESERVED_NAMES`""" B = BULK @@ -260,7 +260,7 @@ class VariableType(Enum): C = CONSTANT P = PARAMETER T = TERM - I = INTERNAL + E = EXTERNAL CONST = CONSTANT PARAM = PARAMETER @@ -328,7 +328,7 @@ class DynamicsType(Enum): F = FORMULA -class ReactionVariable(ABC): +class AbstractVariable(ABC): """The base for a reaction variable. Attributes @@ -423,7 +423,7 @@ def to_symbolic(self, transformations=EXPR_TRANSFORMS): return self.symbol -class ReactionDynamics(ABC): +class AbstractReaction(ABC): """The base for a reaction. Attributes @@ -525,12 +525,12 @@ def variable_dict(self) -> Dict[str, Any]: raise NotImplementedError @abstractmethod - def add_variable(self, __variable: ReactionVariable): + def add_variable(self, __variable: AbstractVariable): """Add a variable *object* to the model""" raise NotImplementedError @abstractmethod - def get_variable(self, name: str) -> ReactionVariable: + def get_variable(self, name: str) -> AbstractVariable: """Get a specific variable by name""" raise NotImplementedError @@ -545,12 +545,12 @@ def reactions(self, location=None): raise NotImplementedError @abstractmethod - def add_reaction(self, __reaction: ReactionDynamics): + def add_reaction(self, __reaction: AbstractReaction): """Add a reaction *object* to the model""" raise NotImplementedError @abstractmethod - def get_reaction(self, species, location=None) -> List[ReactionDynamics]: + def get_reaction(self, species, location=None) -> List[AbstractReaction]: """Get reaction(s) for a species, optionally only for one location""" raise NotImplementedError diff --git a/wntr/quality/multispecies.py b/wntr/quality/multispecies.py index 04c7882cc..2f9654705 100644 --- a/wntr/quality/multispecies.py +++ b/wntr/quality/multispecies.py @@ -40,8 +40,8 @@ AbstractQualityModel, DynamicsType, LocationType, - ReactionDynamics, - ReactionVariable, + AbstractReaction, + AbstractVariable, VariableType, ) from .options import MultispeciesOptions @@ -64,7 +64,7 @@ logger = logging.getLogger(__name__) -class Species(ReactionVariable): +class Species(AbstractVariable): """A species in a multispecies water quality model. .. rubric:: Constructor @@ -259,7 +259,7 @@ def var_type(self): return VariableType.WALL -class Coefficient(ReactionVariable): +class Coefficient(AbstractVariable): """A coefficient, either constant or parameterized by pipe or tank, that is used in reaction expressions. .. rubric:: Constructor @@ -468,7 +468,7 @@ def to_dict(self): @dataclass(repr=False) -class OtherTerm(ReactionVariable): +class OtherTerm(AbstractVariable): """An expression term defined as a function of species, coefficients, or other terms. .. rubric:: Constructor @@ -544,7 +544,7 @@ def to_dict(self): @dataclass(repr=False) -class InternalVariable(ReactionVariable): +class InternalVariable(AbstractVariable): """A hydraulic variable or a placeholder for a built-in reserved word. For example, "Len" is the EPANET-MSX name for the length of a pipe, and "I" is a sympy @@ -594,11 +594,11 @@ def __eq__(self, other): @property def var_type(self): - return VariableType.INTERNAL + return VariableType.EXTERNAL @dataclass(repr=False) -class RateDynamics(ReactionDynamics): +class RateDynamics(AbstractReaction): r"""A rate-of-change reaction dynamics expression. Used to supply the equation that expresses the rate of change of the given species @@ -667,7 +667,7 @@ def to_dict(self) -> dict: @dataclass(repr=False) -class EquilibriumDynamics(ReactionDynamics): +class EquilibriumDynamics(AbstractReaction): """An equilibrium reaction expression. Used for equilibrium expressions where it is assumed that the expression supplied is being equated to zero. @@ -735,7 +735,7 @@ def to_dict(self) -> dict: @dataclass(repr=False) -class FormulaDynamics(ReactionDynamics): +class FormulaDynamics(AbstractReaction): """A formula-based reaction dynamics expression. Used when the concentration of the named species is a simple function of the remaining species. @@ -826,14 +826,12 @@ def __init__(self, msx_file_name=None): self._citations: List[Union[Citation, str]] = list() """A list of citations for the sources of this model's dynamics""" - self._options: InitVar[MultispeciesOptions] = None + self._options: MultispeciesOptions() """A link to the options object""" self._wn: WaterNetworkModel = None """A link to a water network model""" - self._options = MultispeciesOptions() - self._variables: DisjointMapping = DisjointMapping() self._species = self._variables.add_disjoint_group("species") self._coeffs = self._variables.add_disjoint_group("coeffs") @@ -863,7 +861,7 @@ def __init__(self, msx_file_name=None): inp = MsxFile() inp.read(msx_file_name, self) - def _is_variable_registered(self, var_or_name: Union[str, ReactionVariable]) -> bool: + def _is_variable_registered(self, var_or_name: Union[str, AbstractVariable]) -> bool: name = str(var_or_name) if name in self._variables.keys(): return True @@ -933,7 +931,7 @@ def variables(self, var_type: VariableType = None): continue yield v - def add_variable(self, var_or_type: Union[ReactionVariable, VariableType], name: str = None, **kwargs): + def add_variable(self, var_or_type: Union[AbstractVariable, VariableType], name: str = None, **kwargs): """Add an new variable to the model, or add an existing, unlinked variable object to the model. Parameters @@ -954,7 +952,7 @@ def add_variable(self, var_or_type: Union[ReactionVariable, VariableType], name: VariableNameExistsError if the variable or name uses the same name an existing variable already uses """ - if not isinstance(var_or_type, (ReactionVariable,)): + if not isinstance(var_or_type, (AbstractVariable,)): try: var_or_type = VariableType.get(var_or_type) except Exception as e: @@ -1265,7 +1263,7 @@ def remove_variable(self, name: str): self._source_dict.__delitem__(name) return self._variables.__delitem__(name) - def get_variable(self, name: str) -> ReactionVariable: + def get_variable(self, name: str) -> AbstractVariable: """Get a variable based on its name (symbol). Parameters @@ -1341,7 +1339,7 @@ def add_reaction(self, location: LocationType, species: Union[str, Species], dyn species = str(species) if species not in self._species.keys(): raise ValueError("The species {} does not exist in the model, failed to add reaction.".format(species)) - _key = ReactionDynamics.to_key(species, location) + _key = AbstractReaction.to_key(species, location) if _key in self._dynamics.keys(): raise RuntimeError("The species {} already has a {} reaction defined. Use set_reaction instead.") dynamics = DynamicsType.get(dynamics) @@ -1362,7 +1360,7 @@ def add_reaction(self, location: LocationType, species: Union[str, Species], dyn raise ValueError("Invalid location type, {}".format(location)) return new - def add_pipe_reaction(self, species: Union[str, Species], dynamics: Union[str, int, DynamicsType], expression: str, note: str = None) -> ReactionDynamics: + def add_pipe_reaction(self, species: Union[str, Species], dynamics: Union[str, int, DynamicsType], expression: str, note: str = None) -> AbstractReaction: """Add a pipe reaction. See also :meth:`add_reaction`. Parameters @@ -1383,7 +1381,7 @@ def add_pipe_reaction(self, species: Union[str, Species], dynamics: Union[str, i """ return self.add_reaction(LocationType.PIPE, species=species, dynamics=dynamics, expression=expression, note=note) - def add_tank_reaction(self, species: Union[str, Species], dynamics: Union[str, int, DynamicsType], expression: str, note: str = None) -> ReactionDynamics: + def add_tank_reaction(self, species: Union[str, Species], dynamics: Union[str, int, DynamicsType], expression: str, note: str = None) -> AbstractReaction: """Add a pipe reaction. See also :meth:`add_reaction`. Parameters @@ -1425,24 +1423,24 @@ def remove_reaction(self, species: Union[str, Species], location: Union[str, int if location is None: raise TypeError('location cannot be None when removing a reaction. Use "all" for all locations.') elif location == "all": - name = ReactionDynamics.to_key(species, LocationType.PIPE) + name = AbstractReaction.to_key(species, LocationType.PIPE) try: self._pipe_dynamics.__delitem__(name) except KeyError: pass - name = ReactionDynamics.to_key(species, LocationType.TANK) + name = AbstractReaction.to_key(species, LocationType.TANK) try: self._tank_dynamics.__delitem__(name) except KeyError: pass elif location is LocationType.PIPE: - name = ReactionDynamics.to_key(species, LocationType.PIPE) + name = AbstractReaction.to_key(species, LocationType.PIPE) try: self._pipe_dynamics.__delitem__(name) except KeyError: pass elif location is LocationType.TANK: - name = ReactionDynamics.to_key(species, LocationType.TANK) + name = AbstractReaction.to_key(species, LocationType.TANK) try: self._tank_dynamics.__delitem__(name) except KeyError: @@ -1500,7 +1498,7 @@ def options(self, value): if isinstance(value, dict): self._options = MultispeciesOptions.factory(value) elif not isinstance(value, MultispeciesOptions): - raise TypeError("Expected a RxnOptions object, got {}".format(type(value))) + raise TypeError("Expected a MultispeciesOptions object, got {}".format(type(value))) else: self._options = value diff --git a/wntr/utils/disjoint_mapping.py b/wntr/utils/disjoint_mapping.py index 8370f9d0c..27dc32c34 100644 --- a/wntr/utils/disjoint_mapping.py +++ b/wntr/utils/disjoint_mapping.py @@ -42,10 +42,15 @@ def __init__(self, *args, **kwargs): self.__key_groupnames[k] = None self.__usage[k] = set() - def add_disjoint_group(self, name): + def add_disjoint_group(self, name, cls = None): if name in self.__groups.keys(): raise KeyError("Disjoint group already exists within registry") - new = DisjointMappingGroup(name, self) + if cls is None: + new = DisjointMappingGroup(name, self) + elif issubclass(cls, DisjointMappingGroup): + new = cls(name, self) + else: + raise TypeError('cls must be a subclass of DisjointMappingGroup, got {}'.format(cls)) self.__groups.__setitem__(name, new) return new From ca3451a38edf31ca25c429f7dc379217fb0b2140 Mon Sep 17 00:00:00 2001 From: dbhart Date: Tue, 24 Oct 2023 12:55:03 -0600 Subject: [PATCH 31/75] Stashing --- wntr/quality/base.py | 221 +++++++--- wntr/quality/multispecies.py | 781 +++++++++++++++++++++++++---------- 2 files changed, 733 insertions(+), 269 deletions(-) diff --git a/wntr/quality/base.py b/wntr/quality/base.py index bd8bc3cf9..1912aab46 100644 --- a/wntr/quality/base.py +++ b/wntr/quality/base.py @@ -10,8 +10,7 @@ import logging from abc import ABC, abstractmethod, abstractproperty from collections.abc import MutableMapping -from dataclasses import InitVar, dataclass -from enum import Enum, IntFlag +from enum import Enum, IntFlag, IntEnum from typing import Any, ClassVar, Dict, Generator, List, Union import numpy as np @@ -25,30 +24,89 @@ has_sympy = False try: - from sympy import Float, Symbol, init_printing, symbols, Function, Mul, Add, Pow, Integer - from sympy.functions import cos, sin, tan, cot, Abs, sign, sqrt, log, exp, asin, acos, atan, acot, sinh, cosh, tanh, coth, Heaviside + from sympy import ( + Float, + Symbol, + init_printing, + symbols, + Function, + Mul, + Add, + Pow, + Integer, + ) + from sympy.functions import ( + cos, + sin, + tan, + cot, + Abs, + sign, + sqrt, + log, + exp, + asin, + acos, + atan, + acot, + sinh, + cosh, + tanh, + coth, + Heaviside, + ) from sympy.parsing import parse_expr - from sympy.parsing.sympy_parser import convert_xor, standard_transformations, auto_number, auto_symbol + from sympy.parsing.sympy_parser import ( + convert_xor, + standard_transformations, + auto_number, + auto_symbol, + ) + class _log10(Function): @classmethod def eval(cls, x): return log(x, 10) + has_sympy = True except ImportError: sympy = None has_sympy = False - logging.critical("This python installation does not have SymPy installed. Certain functionality will be disabled.") + logging.critical( + "This python installation does not have SymPy installed. Certain functionality will be disabled." + ) standard_transformations = (None,) convert_xor = None if not has_sympy: - from numpy import cos, sin, tan, abs, sign, sqrt, log, exp, arcsin, arccos, arctan, sinh, cosh, tanh, heaviside, log10 - cot = lambda x : 1 / tan(x) + from numpy import ( + cos, + sin, + tan, + abs, + sign, + sqrt, + log, + exp, + arcsin, + arccos, + arctan, + sinh, + cosh, + tanh, + heaviside, + log10, + ) + + def _cot(x): return 1 / tan(x) + cot = _cot Abs = abs asin = arcsin acos = arccos atan = arctan - acot = lambda x : 1 / arctan(1 / x) - coth = lambda x : 1 / tanh(x) + def _acot(x): return 1 / arctan(1 / x) + acot = _acot + def _coth(x): return 1 / tanh(x) + coth = _coth Heaviside = heaviside _log10 = log10 @@ -163,7 +221,7 @@ def eval(cls, x): + tuple([k for k, v in EXPR_FUNCTIONS.items()]) + tuple([k.upper() for k, v in EXPR_FUNCTIONS.items()]) + tuple([k.capitalize() for k, v in EXPR_FUNCTIONS.items()]) - + ('Mul', 'Add', 'Pow', 'Integer', 'Float') + + ("Mul", "Add", "Pow", "Integer", "Float") ) """The WNTR reserved names. This includes the MSX hydraulic variables (see :numref:`table-msx-hyd-vars`) and the MSX defined functions @@ -180,11 +238,11 @@ def eval(cls, x): _global_dict[k.upper()] = v for v in HYDRAULIC_VARIABLES: _global_dict[v["name"]] = symbols(v["name"]) -_global_dict['Mul'] = Mul -_global_dict['Add'] = Add -_global_dict['Pow'] = Pow -_global_dict['Integer'] = Integer -_global_dict['Float'] = Float +_global_dict["Mul"] = Mul +_global_dict["Add"] = Add +_global_dict["Pow"] = Pow +_global_dict["Integer"] = Integer +_global_dict["Float"] = Float EXPR_TRANSFORMS = ( auto_symbol, @@ -217,9 +275,17 @@ def eval(cls, x): :meta hide-value: """ +class AnnotatedFloat(float): + def __new__(self, value, note=None): + return float.__new__(self, value) + + def __init__(self, value, note=None): + float.__init__(value) + self.note = note + @add_get(abbrev=True) -class VariableType(Enum): +class QualityVarType(IntEnum): """The type of reaction variable. The following types are defined, and aliases of just the first character @@ -227,12 +293,49 @@ class VariableType(Enum): .. rubric:: Enum Members .. autosummary:: - BULK - WALL + + SPECIES CONSTANT PARAMETER TERM - INTERNAL + RESERVED + + .. rubric:: Class Methods + .. autosummary:: + :nosignatures: + + get + + """ + + SPECIES = 3 + """A chemical or biological water quality species""" + TERM = 4 + """A functional term - ie named expression - for use in reaction expressions""" + PARAMETER = 5 + """A reaction expression coefficient that is parameterized by tank or pipe""" + CONSTANT = 6 + """A constant coefficient for use in reaction expressions""" + RESERVED = 9 + """A 'variable' that is either a hydraulic variable or other reserved word""" + S = SPEC = SPECIES + T = TERM + P = PARAM = PARAMETER + C = CONST = CONSTANT + R = RES = RESERVED + + +@add_get(abbrev=True) +class SpeciesType(IntEnum): + """The enumeration for species type. + + .. warning:: These enum values are note the same as the MSX SpeciesType. + + .. rubric:: Enum Members + + .. autosummary:: + BULK + WALL .. rubric:: Class Methods .. autosummary:: @@ -243,28 +346,12 @@ class VariableType(Enum): """ BULK = 1 - """A species that reacts with other bulk chemicals""" + """bulk species""" WALL = 2 - """A species that reacts with the pipe walls""" - CONSTANT = 4 - """A constant coefficient for use in a reaction expression""" - PARAMETER = 8 - """A coefficient that has a value dependent on the pipe or tank""" - TERM = 16 - """A term that is aliased for ease of writing expressions""" - EXTERNAL = 32 - """An internal variable - see :attr:`~wntr.reaction.base.RESERVED_NAMES`""" - + """wall species""" B = BULK W = WALL - C = CONSTANT - P = PARAMETER - T = TERM - E = EXTERNAL - - CONST = CONSTANT - PARAM = PARAMETER - + @add_get(abbrev=True) class LocationType(Enum): @@ -353,7 +440,9 @@ def _variable_registry(self) -> "AbstractQualityModel": @_variable_registry.setter def _variable_registry(self, value): if value is not None and not isinstance(value, AbstractQualityModel): - raise TypeError("Linked model must be a RxnModelRegistry, got {}".format(type(value))) + raise TypeError( + "Linked model must be a RxnModelRegistry, got {}".format(type(value)) + ) self.__variable_registry = value def validate(self): @@ -368,7 +457,7 @@ def validate(self): raise TypeError("This object is not connected to any RxnModelRegistry") @abstractproperty - def var_type(self) -> VariableType: + def var_type(self) -> QualityVarType: """The variable type.""" raise NotImplementedError @@ -380,7 +469,7 @@ def is_species(self) -> bool: bool True if this is a species object, False otherwise """ - return self.var_type == VariableType.BULK or self.var_type == VariableType.WALL + return self.var_type == QualityVarType.SPECIES def is_coeff(self) -> bool: """Check to see if this variable represents a coefficient (constant or parameter). @@ -390,7 +479,10 @@ def is_coeff(self) -> bool: bool True if this is a coefficient object, False otherwise """ - return self.var_type == VariableType.CONST or self.var_type == VariableType.PARAM + return ( + self.var_type == QualityVarType.CONST + or self.var_type == QualityVarType.PARAM + ) def is_other_term(self) -> bool: """Check to see if this variable represents a function (MSX term). @@ -400,7 +492,7 @@ def is_other_term(self) -> bool: bool True if this is a term/function object, False otherwise """ - return self.var_type == VariableType.TERM + return self.var_type == QualityVarType.TERM @property def symbol(self): @@ -430,19 +522,34 @@ class AbstractReaction(ABC): ---------- species : str the name of the species whose reaction dynamics is being described - location : RxnLocationType or str + location : LocationType | str the location the reaction occurs (pipes or tanks) + dynamics : DynamicsType | str + the type of reaction dynamics (left-hand-side) expression : str the expression for the reaction dynamics (right-hand-side) """ def __str__(self) -> str: - """Names the reaction with the format `species-dot-location` (for example, ``PB2.pipe``)""" - return self.to_key(self.species, self.location) + """Name of the species""" + return self.species # self.to_key(self.species, self.location) def __hash__(self) -> int: """Makes the reaction hashable by hashing the `str` representation""" - return hash(str(self)) + return hash(self.to_key(self.species, self.location)) + + def __repr__(self) -> str: + return "{}(species={}, location={}, expression={}, note={})".format( + self.__class__.__name__, + repr(self.species), + repr( + self.location.name + if isinstance(self.location, LocationType) + else self.location + ), + repr(self.expression), + repr(self.note.to_dict() if hasattr(self.note, "to_dict") else self.note), + ) __variable_registry = None @@ -453,7 +560,9 @@ def _variable_registry(self) -> "AbstractQualityModel": @_variable_registry.setter def _variable_registry(self, value): if value is not None and not isinstance(value, AbstractQualityModel): - raise TypeError("Linked model must be a RxnModelRegistry, got {}".format(type(value))) + raise TypeError( + "Linked model must be a RxnModelRegistry, got {}".format(type(value)) + ) self.__variable_registry = value def validate(self): @@ -468,7 +577,7 @@ def validate(self): raise TypeError("This object is not connected to any RxnModelRegistry") @abstractproperty - def expr_type(self) -> DynamicsType: + def dynamics(self) -> DynamicsType: """The type of reaction dynamics being described (or, the left-hand-side of the equation)""" raise NotImplementedError @@ -490,7 +599,7 @@ def to_key(cls, species, location): a species/location unique name """ location = LocationType.get(location) - return str(species) + "." + location.name.lower() + return str(species) + "::" + location.name.lower() @abstractmethod def to_symbolic(self, transformations: tuple = EXPR_TRANSFORMS): @@ -508,7 +617,15 @@ def to_symbolic(self, transformations: tuple = EXPR_TRANSFORMS): """ if not has_sympy: return self.expression - return parse_expr(self.expression, local_dict=self._variable_registry.variable_dict() if self._variable_registry is not None else None, transformations=transformations, global_dict=_global_dict, evaluate=False) + return parse_expr( + self.expression, + local_dict=self._variable_registry.variable_dict() + if self._variable_registry is not None + else None, + transformations=transformations, + global_dict=_global_dict, + evaluate=False, + ) class AbstractQualityModel(ABC): diff --git a/wntr/quality/multispecies.py b/wntr/quality/multispecies.py index 2f9654705..d9adccdb6 100644 --- a/wntr/quality/multispecies.py +++ b/wntr/quality/multispecies.py @@ -9,7 +9,7 @@ import logging import warnings from collections.abc import MutableMapping -from dataclasses import InitVar, asdict, dataclass, field +from dataclasses import InitVar, asdict, field from enum import Enum, IntFlag from typing import ( Any, @@ -29,7 +29,6 @@ from wntr.epanet.util import ENcomment from wntr.network.elements import Source from wntr.network.model import PatternRegistry, SourceRegistry, WaterNetworkModel -from wntr.utils.citations import Citation from wntr.utils.disjoint_mapping import DisjointMapping, KeyExistsError from .base import ( @@ -42,7 +41,8 @@ LocationType, AbstractReaction, AbstractVariable, - VariableType, + QualityVarType, + SpeciesType, ) from .options import MultispeciesOptions @@ -55,7 +55,9 @@ has_sympy = True except ImportError: sympy = None - logging.critical("This python installation does not have SymPy installed. Certain functionality will be disabled.") + logging.critical( + "This python installation does not have SymPy installed. Certain functionality will be disabled." + ) standard_transformations = (None,) convert_xor = None has_sympy = False @@ -70,7 +72,7 @@ class Species(AbstractVariable): .. rubric:: Constructor The preferred way to create a new species is to use one of the following - functions from the :class:`MultispeciesQualityModel`: + functions from the :class:`MultispeciesQualityModel`: :meth:`~MultispeciesQualityModel.add_bulk_species()`, :meth:`~MultispeciesQualityModel.add_wall_species()`, :meth:`~MultispeciesQualityModel.add_species()`, or @@ -85,24 +87,24 @@ class Species(AbstractVariable): """A note to go with this species""" diffusivity: float = None """A value for diffusivity for this species""" - initial_quality: float = None - """Global initial quality for this species""" def __init__( self, + species_type: Union[SpeciesType, str], name: str, units: str, atol: float = None, rtol: float = None, note: Union[str, Dict[str, str]] = None, diffusivity: float = None, - initial_quality: float = None, *, _qm: AbstractQualityModel = None, ): """ Parameters ---------- + species_type: SpeciesType | str + The type of species, either BULK or WALL name : str The name (symbol) for the variable, must be a valid MSX name units : str @@ -115,8 +117,6 @@ def __init__( A note about this species, by default None diffusivity : float, optional The diffusivity value for this species, by default None - initial_quality: float, optional - The global initial quality for this species, by default None Other Parameters ---------------- @@ -125,6 +125,9 @@ def __init__( """ if name in RESERVED_NAMES: raise ValueError("Name cannot be a reserved name") + self._species_type = SpeciesType.get(species_type) + if self._species_type is None: + raise TypeError("species_type cannot be None") self.name: str = name """The name of the variable""" self.units: str = units @@ -133,20 +136,29 @@ def __init__( """A note about this species, by default None""" self.diffusivity: float = diffusivity """The diffusivity value for this species, by default None""" - self.initial_quality: float = initial_quality - """The global initial quality for this species, by default None (C=0.0)""" if atol is not None: atol = float(atol) if rtol is not None: rtol = float(rtol) if (atol is None) ^ (rtol is None): - raise TypeError("atol and rtol must be the same type, got {} and {}".format(atol, rtol)) + raise TypeError( + "atol and rtol must be the same type, got {} and {}".format(atol, rtol) + ) self._atol = atol self._rtol = rtol self._variable_registry = _qm def __repr__(self): - return "{}(name={}, unit={}, atol={}, rtol={}, note={})".format(self.__class__.__name__, repr(self.name), repr(self.units), self._atol, self._rtol, repr(self.note)) + return "{}(name={}, unit={}, atol={}, rtol={}, note={})".format( + self.__class__.__name__, + repr(self.name), + repr(self.units), + self._atol, + self._rtol, + repr( + self.note if not isinstance(self.note, ENcomment) else asdict(self.note) + ), + ) def __eq__(self, other): return ( @@ -158,6 +170,25 @@ def __eq__(self, other): and self._rtol == other._rtol ) + @property + def var_type(self): + return QualityVarType.SPECIES + + @property + def species_type(self) -> SpeciesType: + """Type type of species (bulk or wall)""" + return self._species_type + + @property + def is_bulk(self) -> bool: + """Is this a bulk species?""" + return self._species_type is SpeciesType.BULK + + @property + def is_wall(self) -> bool: + """Is this a wall species?""" + return self._species_type is SpeciesType.WALL + def get_tolerances(self) -> Tuple[float, float]: """Get the species-specific solver tolerances. @@ -197,7 +228,11 @@ def set_tolerances(self, absolute: float, relative: float): if not isinstance(relative, float): relative = float(relative) except Exception as e: - raise TypeError("absolute and relative must be the same type, got {} and {}".format(absolute, relative)) + raise TypeError( + "absolute and relative must be the same type, got {} and {}".format( + absolute, relative + ) + ) if absolute <= 0: raise ValueError("Absolute tolerance must be greater than 0") if relative <= 0: @@ -210,12 +245,17 @@ def clear_tolerances(self): self._atol = self._rtol = None def to_dict(self): - rep = dict(name=self.name, unist=self.units) + rep = dict( + name=self.name, + species_type=self.species_type.name.lower(), + units=self.units, + ) tols = self.get_tolerances() if tols is not None: rep["atol"] = tols[0] rep["rtol"] = tols[1] - rep["diffusivity"] = self.diffusivity + if self.diffusivity: + rep["diffusivity"] = self.diffusivity if isinstance(self.note, str): rep["note"] = self.note elif isinstance(self.note, ENcomment): @@ -225,49 +265,15 @@ def to_dict(self): return rep -class BulkSpecies(Species): - """A bulk species. - - .. rubric:: Constructor - - The preferred way to create a new bulk species is to use one of the following - functions from the :class:`MultispeciesQualityModel`: - :meth:`~MultispeciesQualityModel.add_bulk_species()`, - :meth:`~MultispeciesQualityModel.add_species()`, or - :meth:`~MultispeciesQualityModel.add_variable()`. - """ - - @property - def var_type(self): - return VariableType.BULK - - -class WallSpecies(Species): - """A wall species. - - .. rubric:: Constructor - - The preferred way to create a new wall species is to use one of the following - functions from the :class:`MultispeciesQualityModel`: - :meth:`~MultispeciesQualityModel.add_wall_species()`, - :meth:`~MultispeciesQualityModel.add_species()`, or - :meth:`~MultispeciesQualityModel.add_variable()`. - """ - - @property - def var_type(self): - return VariableType.WALL - - -class Coefficient(AbstractVariable): - """A coefficient, either constant or parameterized by pipe or tank, that is used in reaction expressions. +class Constant(AbstractVariable): + """A constant coefficient that is used in reaction expressions. .. rubric:: Constructor The preferred way to create a new coefficient is to use one of the following - functions from the :class:`MultispeciesQualityModel`: - :meth:`~MultispeciesQualityModel.add_constant_coeff()`, - :meth:`~MultispeciesQualityModel.add_parameterized_coeff()`, + functions from the :class:`MultispeciesQualityModel`: + :meth:`~MultispeciesQualityModel.add_constant()`, + :meth:`~MultispeciesQualityModel.add_parameter()`, :meth:`~MultispeciesQualityModel.add_coefficient()`, or :meth:`~MultispeciesQualityModel.add_variable()`. """ @@ -281,7 +287,15 @@ class Coefficient(AbstractVariable): global_value: float = None """The global value for the coefficient""" - def __init__(self, name: str, global_value: float, note: Union[str, Dict[str, str]] = None, units: str = None, *, _qm: AbstractQualityModel = None): + def __init__( + self, + name: str, + global_value: float, + note: Union[str, Dict[str, str]] = None, + units: str = None, + *, + _qm: AbstractQualityModel = None, + ): """ Parameters ---------- @@ -312,10 +326,23 @@ def __init__(self, name: str, global_value: float, note: Union[str, Dict[str, st self._variable_registry = _qm def __repr__(self): - return "{}(name={}, global_value={}, units={}, note={})".format(self.__class__.__name__, repr(self.name), repr(self.global_value), repr(self.units), repr(self.note)) + return "{}(name={}, global_value={}, units={}, note={})".format( + self.__class__.__name__, + repr(self.name), + repr(self.global_value), + repr(self.units), + repr( + self.note if not isinstance(self.note, ENcomment) else asdict(self.note) + ), + ) def __eq__(self, other): - return isinstance(other, self.__class__) and self.name == other.name and self.global_value == other.global_value and self.units == other.units + return ( + isinstance(other, self.__class__) + and self.name == other.name + and self.global_value == other.global_value + and self.units == other.units + ) def get_value(self) -> float: """Get the value of the coefficient @@ -337,36 +364,32 @@ def to_dict(self): rep["note"] = None return rep - -class Constant(Coefficient): - """A constant coefficient for reaction expressions. - - .. rubric:: Constructor - - The preferred way to create a new constant coefficient is to use one of the following - functions from the :class:`MultispeciesQualityModel`: - :meth:`~MultispeciesQualityModel.add_constant_coeff()`, - :meth:`~MultispeciesQualityModel.add_coefficient()`, or - :meth:`~MultispeciesQualityModel.add_variable()`. - """ - @property def var_type(self): - return VariableType.CONST + return QualityVarType.CONST -class Parameter(Coefficient): +class Parameter(AbstractVariable): """A variable parameter for reaction expressions. .. rubric:: Constructor The preferred way to create a new parameterized coefficient is to use one of the following - functions from the :class:`MultispeciesQualityModel`: - :meth:`~MultispeciesQualityModel.add_parameterized_coeff()`, + functions from the :class:`MultispeciesQualityModel`: + :meth:`~MultispeciesQualityModel.add_parameter()`, :meth:`~MultispeciesQualityModel.add_coefficient()`, or :meth:`~MultispeciesQualityModel.add_variable()`. """ + name: str = None + """The name (symbol) for the variable, must be a valid MSX name""" + units: str = None + """The units used for this variable""" + global_value: float = None + """The global value for the coefficient""" + note: Union[str, Dict[str, str]] = None + """A note to go with this varibale""" + def __init__( self, name: str, @@ -399,14 +422,29 @@ def __init__( _qm : MultispeciesQualityModel the model to link with, populated automatically if the :class:`MultispeciesQualityModel` API is used, by default None """ - super().__init__(name, global_value=global_value, note=note, units=units, _qm=_qm) + if name in RESERVED_NAMES: + raise ValueError("Name cannot be a reserved name") + self.name = name + """The name of the variable""" + self.global_value = float(global_value) + """The global value for the coefficient""" + self.note = note + """A note about this species, by default None""" + self.units = units + """The units used for this species""" + self._variable_registry = _qm self._pipe_values = pipe_values if pipe_values is not None else dict() """A dictionary of parameter values for various pipes""" self._tank_values = tank_values if tank_values is not None else dict() """A dictionary of parameter values for various tanks""" def __eq__(self, other): - basic = isinstance(other, self.__class__) and self.name == other.name and self.global_value == other.global_value and self.units == other.units + basic = ( + isinstance(other, self.__class__) + and self.name == other.name + and self.global_value == other.global_value + and self.units == other.units + ) if not basic: return False for k, v in self._pipe_values: @@ -417,9 +455,20 @@ def __eq__(self, other): return False return True + def __repr__(self): + return "{}(name={}, global_value={}, units={}, note={})".format( + self.__class__.__name__, + repr(self.name), + repr(self.global_value), + repr(self.units), + repr( + self.note if not isinstance(self.note, ENcomment) else asdict(self.note) + ), + ) + @property def var_type(self): - return VariableType.PARAM + return QualityVarType.PARAM def get_value(self, pipe: str = None, tank: str = None) -> float: """Get the value of the parameter, either globally or for a specific pipe or tank. @@ -443,7 +492,9 @@ def get_value(self, pipe: str = None, tank: str = None) -> float: if both pipe and tank are specified """ if pipe is not None and tank is not None: - raise TypeError("Cannot get a value for a pipe and tank at the same time - one or both must be None") + raise TypeError( + "Cannot get a value for a pipe and tank at the same time - one or both must be None" + ) if pipe is not None: return self._pipe_values.get(pipe, self.global_value) if tank is not None: @@ -461,13 +512,18 @@ def tank_values(self) -> Dict[str, float]: return self._tank_values def to_dict(self): - rep = super().to_dict() + rep = dict(name=self.name, global_value=self.global_value, units=self.units) + if isinstance(self.note, str): + rep["note"] = self.note + elif isinstance(self.note, ENcomment): + rep["note"] = asdict(self.note) if self.note.pre else self.note.post + else: + rep["note"] = None rep["pipe_values"] = self._pipe_values.copy() rep["tank_values"] = self._tank_values.copy() return rep -@dataclass(repr=False) class OtherTerm(AbstractVariable): """An expression term defined as a function of species, coefficients, or other terms. @@ -520,14 +576,25 @@ def __init__( self._variable_registry = _qm def __repr__(self): - return "{}(name={}, expression={}, note={})".format(self.__class__.__name__, repr(self.name), repr(self.expression), repr(self.note)) + return "{}(name={}, expression={}, note={})".format( + self.__class__.__name__, + repr(self.name), + repr(self.expression), + repr( + self.note if not isinstance(self.note, ENcomment) else asdict(self.note) + ), + ) def __eq__(self, other): - return isinstance(other, self.__class__) and self.name == other.name and self.expression == other.expression + return ( + isinstance(other, self.__class__) + and self.name == other.name + and self.expression == other.expression + ) @property def var_type(self): - return VariableType.TERM + return QualityVarType.TERM def to_symbolic(self): return super().to_symbolic() @@ -543,13 +610,12 @@ def to_dict(self): return rep -@dataclass(repr=False) class InternalVariable(AbstractVariable): """A hydraulic variable or a placeholder for a built-in reserved word. For example, "Len" is the EPANET-MSX name for the length of a pipe, and "I" is a sympy reserved symbol for the imaginary number. - + .. rubric:: Constructor Objects of this type are instantiated when creating a new :class:`MultispeciesQualityModel`, @@ -587,17 +653,23 @@ def __init__( """The units used for this species""" def __repr__(self): - return "{}(name={}, note={}, units={})".format(self.__class__.__name__, repr(self.name), repr(self.note), repr(self.units)) + return "{}(name={}, units={}, note={})".format( + self.__class__.__name__, + repr(self.name), + repr(self.units), + repr( + self.note if not isinstance(self.note, ENcomment) else asdict(self.note) + ), + ) def __eq__(self, other): return isinstance(other, self.__class__) and self.name == other.name @property def var_type(self): - return VariableType.EXTERNAL + return QualityVarType.RESERVED -@dataclass(repr=False) class RateDynamics(AbstractReaction): r"""A rate-of-change reaction dynamics expression. @@ -611,20 +683,28 @@ class RateDynamics(AbstractReaction): .. rubric:: Constructor The preferred way to create a new rate reaction expression is to use one of the following - functions from the :class:`MultispeciesQualityModel`: + functions from the :class:`MultispeciesQualityModel`: :meth:`~MultispeciesQualityModel.add_pipe_reaction()`, :meth:`~MultispeciesQualityModel.add_tank_reaction()`, or :meth:`~MultispeciesQualityModel.add_reaction()`. """ - def __init__(self, species: str, location: LocationType, expression: str, note: Union[str, Dict[str, str]] = None, *, _qm: AbstractQualityModel = None): + def __init__( + self, + species: str, + dynamics: DynamicsType, + expression: str, + note: Union[str, Dict[str, str]] = None, + *, + _qm: AbstractQualityModel = None, + ): """ Parameters ---------- species : str the name of the species whose reaction dynamics is being described - location : RxnLocationType or str - the location the reaction occurs (pipes or tanks) + dynamics : DynamicsType | str | int + the type of dynamics that the expression describes expression : str the expression for the reaction dynamics, which should equal to zero note : str, optional @@ -637,8 +717,8 @@ def __init__(self, species: str, location: LocationType, expression: str, note: """ self.species = species """Name of the species being described""" - self.location = location - """Location this reaction occurs""" + self.dynamics = DynamicsType.get(dynamics) + """Type of reaction dynamics described by the expression""" self.expression = expression """The expression""" self.note = note @@ -646,17 +726,26 @@ def __init__(self, species: str, location: LocationType, expression: str, note: self._variable_registry = _qm def __eq__(self, other): - return isinstance(other, self.__class__) and self.name == other.name and self.location == other.location and self.expression == other.expression + return ( + isinstance(other, self.__class__) + and self.species == other.species + and self.dynamics == other.dynamics + and self.expression == other.expression + ) @property - def expr_type(self) -> DynamicsType: + def dynamics(self) -> DynamicsType: return DynamicsType.RATE def to_symbolic(self): return super().to_symbolic() def to_dict(self) -> dict: - rep = dict(species=self.species, expr_type=self.expr_type.name.lower(), expression=self.expression) + rep = dict( + species=self.species, + dynamics=self.dynamics.name.lower(), + expression=self.expression, + ) if isinstance(self.note, str): rep["note"] = self.note elif isinstance(self.note, ENcomment): @@ -666,7 +755,6 @@ def to_dict(self) -> dict: return rep -@dataclass(repr=False) class EquilibriumDynamics(AbstractReaction): """An equilibrium reaction expression. @@ -679,13 +767,21 @@ class EquilibriumDynamics(AbstractReaction): .. rubric:: Constructor The preferred way to create a new rate reaction expression is to use one of the following - functions from the :class:`MultispeciesQualityModel`: + functions from the :class:`MultispeciesQualityModel`: :meth:`~MultispeciesQualityModel.add_pipe_reaction()`, :meth:`~MultispeciesQualityModel.add_tank_reaction()`, or :meth:`~MultispeciesQualityModel.add_reaction()`. """ - def __init__(self, species: str, location: LocationType, expression: str, note: Union[str, Dict[str, str]] = None, *, _qm: AbstractQualityModel = None): + def __init__( + self, + species: str, + location: LocationType, + expression: str, + note: Union[str, Dict[str, str]] = None, + *, + _qm: AbstractQualityModel = None, + ): """ Parameters ---------- @@ -714,17 +810,26 @@ def __init__(self, species: str, location: LocationType, expression: str, note: self._variable_registry = _qm def __eq__(self, other): - return isinstance(other, self.__class__) and self.name == other.name and self.location == other.location and self.expression == other.expression + return ( + isinstance(other, self.__class__) + and self.name == other.name + and self.location == other.location + and self.expression == other.expression + ) @property - def expr_type(self) -> DynamicsType: + def dynamics(self) -> DynamicsType: return DynamicsType.EQUIL def to_symbolic(self): return super().to_symbolic() def to_dict(self) -> dict: - rep = dict(species=self.species, expr_type=self.expr_type.name.lower(), expression=self.expression) + rep = dict( + species=self.species, + dynamics=self.dynamics.name.lower(), + expression=self.expression, + ) if isinstance(self.note, str): rep["note"] = self.note elif isinstance(self.note, ENcomment): @@ -734,7 +839,6 @@ def to_dict(self) -> dict: return rep -@dataclass(repr=False) class FormulaDynamics(AbstractReaction): """A formula-based reaction dynamics expression. @@ -747,13 +851,21 @@ class FormulaDynamics(AbstractReaction): .. rubric:: Constructor The preferred way to create a new rate reaction expression is to use one of the following - functions from the :class:`MultispeciesQualityModel`: + functions from the :class:`MultispeciesQualityModel`: :meth:`~MultispeciesQualityModel.add_pipe_reaction()`, :meth:`~MultispeciesQualityModel.add_tank_reaction()`, or :meth:`~MultispeciesQualityModel.add_reaction()`. """ - def __init__(self, species: str, location: LocationType, expression: str, note: Union[str, Dict[str, str]] = None, *, _qm: AbstractQualityModel = None): + def __init__( + self, + species: str, + location: LocationType, + expression: str, + note: Union[str, Dict[str, str]] = None, + *, + _qm: AbstractQualityModel = None, + ): """ Parameters ---------- @@ -782,17 +894,26 @@ def __init__(self, species: str, location: LocationType, expression: str, note: self._variable_registry = _qm def __eq__(self, other): - return isinstance(other, self.__class__) and self.name == other.name and self.location == other.location and self.expression == other.expression + return ( + isinstance(other, self.__class__) + and self.name == other.name + and self.location == other.location + and self.expression == other.expression + ) @property - def expr_type(self) -> DynamicsType: + def dynamics(self) -> DynamicsType: return DynamicsType.FORMULA def to_symbolic(self): return super().to_symbolic() def to_dict(self) -> dict: - rep = dict(species=self.species, expr_type=self.expr_type.name.lower(), expression=self.expression) + rep = dict( + species=self.species, + dynamics=self.dynamics.name.lower(), + expression=self.expression, + ) if isinstance(self.note, str): rep["note"] = self.note elif isinstance(self.note, ENcomment): @@ -803,8 +924,7 @@ def to_dict(self) -> dict: class MultispeciesQualityModel(AbstractQualityModel): - """A multispecies water quality reactions model, for use with EPANET-MSX. - """ + """A multispecies water quality reactions model, for use with EPANET-MSX.""" def __init__(self, msx_file_name=None): """Create a new multispecies water quality reaction model. @@ -820,13 +940,16 @@ def __init__(self, msx_file_name=None): self.title: str = None """The title line from the MSX file""" + self.desc: str = None + """A longer description, to/from comments in top of MSX file""" + self._msxfile: str = msx_file_name """The original filename""" - self._citations: List[Union[Citation, str]] = list() - """A list of citations for the sources of this model's dynamics""" + self._references: List[Union[dict, str]] = list() + """A list of references for the sources of this model's dynamics""" - self._options: MultispeciesOptions() + self._options: MultispeciesOptions = MultispeciesOptions() """A link to the options object""" self._wn: WaterNetworkModel = None @@ -834,12 +957,12 @@ def __init__(self, msx_file_name=None): self._variables: DisjointMapping = DisjointMapping() self._species = self._variables.add_disjoint_group("species") - self._coeffs = self._variables.add_disjoint_group("coeffs") - self._terms = self._variables.add_disjoint_group("funcs") + self._constants = self._variables.add_disjoint_group("constants") + self._params = self._variables.add_disjoint_group("parameters") + self._terms = self._variables.add_disjoint_group("terms") - self._dynamics: DisjointMapping = DisjointMapping() - self._pipe_dynamics = self._dynamics.add_disjoint_group("pipe") - self._tank_dynamics = self._dynamics.add_disjoint_group("tank") + self._pipe_rxns = dict() + self._tank_rxns = dict() self._usage: Dict[str, Set[str]] = dict() # FIXME: currently no usage tracking @@ -854,14 +977,18 @@ def __init__(self, msx_file_name=None): for name in EXPR_FUNCTIONS.keys(): self._variables[name.lower()] = InternalVariable(name, note="MSX function") self._variables[name.upper()] = InternalVariable(name, note="MSX function") - self._variables[name.capitalize()] = InternalVariable(name, note="MSX function") + self._variables[name.capitalize()] = InternalVariable( + name, note="MSX function" + ) if msx_file_name is not None: from wntr.epanet.msx.io import MsxFile inp = MsxFile() inp.read(msx_file_name, self) - def _is_variable_registered(self, var_or_name: Union[str, AbstractVariable]) -> bool: + def _is_variable_registered( + self, var_or_name: Union[str, AbstractVariable] + ) -> bool: name = str(var_or_name) if name in self._variables.keys(): return True @@ -886,7 +1013,9 @@ def variable_dict(self) -> Dict[str, Any]: vars = dict() for symb, spec in self._species.items(): vars[symb] = symbols(symb) - for symb, coeff in self._coeffs.items(): + for symb, coeff in self._constants.items(): + vars[symb] = symbols(symb) + for symb, coeff in self._params.items(): vars[symb] = symbols(symb) for symb, term in self._terms.items(): vars[symb] = symbols(symb) @@ -903,21 +1032,26 @@ def species_name_list(self) -> List[str]: return list(self._species.keys()) @property - def coefficient_name_list(self) -> List[str]: + def constant_name_list(self) -> List[str]: + """all defined coefficient names""" + return list(self._constants.keys()) + + @property + def parameter_name_list(self) -> List[str]: """all defined coefficient names""" - return list(self._coeffs.keys()) + return list(self._params.keys()) @property def other_term_name_list(self) -> List[str]: """all defined function (MSX 'terms') names""" return list(self._terms.keys()) - def variables(self, var_type: VariableType = None): + def variables(self, var_type: QualityVarType = None): """A generator to loop over the variables. Parameters ---------- - var_type : RxnVariableType, optional + var_type : QualityVarType, optional limit results to a specific type, by default None Yields @@ -925,18 +1059,23 @@ def variables(self, var_type: VariableType = None): RxnVariable a variable defined within the model """ - var_type = VariableType.get(var_type) + var_type = QualityVarType.get(var_type) for v in self._variables.values(): if var_type is not None and v.var_type != var_type: continue yield v - def add_variable(self, var_or_type: Union[AbstractVariable, VariableType], name: str = None, **kwargs): + def add_variable( + self, + var_or_type: Union[AbstractVariable, QualityVarType], + name: str = None, + **kwargs, + ): """Add an new variable to the model, or add an existing, unlinked variable object to the model. Parameters ---------- - var_or_type : RxnVariable | RxnVariableType + var_or_type : RxnVariable | QualityVarType the variable object to add to the model, or the type if creating a new variable object name : str or None the name of a new variable, must be None if adding an existing object, by default None @@ -954,44 +1093,58 @@ def add_variable(self, var_or_type: Union[AbstractVariable, VariableType], name: """ if not isinstance(var_or_type, (AbstractVariable,)): try: - var_or_type = VariableType.get(var_or_type) + var_or_type = QualityVarType.get(var_or_type) except Exception as e: - raise TypeError("Cannot add an object that is not a RxnVariable subclass or create a new object without a valid var_type") from e + raise TypeError( + "Cannot add an object that is not a RxnVariable subclass or create a new object without a valid var_type" + ) from e if name is None: raise ValueError("When adding a new variable, a name must be supplied") typ = var_or_type - if typ is VariableType.BULK or typ is VariableType.WALL: - self.add_species(var_or_type, name, **kwargs) - elif typ is VariableType.CONST or typ is VariableType.PARAM: - self.add_coefficient(var_or_type, name, **kwargs) - elif typ is VariableType.TERM: + if typ is QualityVarType.SPECIES: + self.add_species(name, **kwargs) + elif typ is QualityVarType.CONST: + self.add_constant(name, **kwargs) + elif typ is QualityVarType.PARAM: + self.add_parameter(name, **kwargs) + elif typ is QualityVarType.TERM: self.add_other_term(var_or_type, name, **kwargs) else: - raise TypeError("Cannot create new objects of the INTERNAL type using this function") + raise TypeError( + "Cannot create new objects of the EXTERNAL type using this function" + ) else: if name is None or len(kwargs) > 0: - raise ValueError("When adding an existing variable object, no other arguments may be supplied") + raise ValueError( + "When adding an existing variable object, no other arguments may be supplied" + ) __variable = var_or_type if self._is_variable_registered(__variable): - raise KeyExistsError("A variable with this name already exists in the model") + raise KeyExistsError( + "A variable with this name already exists in the model" + ) typ = __variable.var_type name = __variable.name if hasattr(__variable, "_variable_registry"): __variable._variable_registry = self - if typ is VariableType.BULK or typ is VariableType.WALL: + if typ is QualityVarType.SPECIES: self._variables.add_item_to_group("species", name, __variable) - self._inital_qual_dict[name] = dict(global_value=None, nodes=dict(), links=dict()) + self._inital_qual_dict[name] = dict( + global_value=None, nodes=dict(), links=dict() + ) self._source_dict[name] = dict() - elif typ is VariableType.CONST or typ is VariableType.PARAM: - self._variables.add_item_to_group("coeffs", name, __variable) - elif typ is VariableType.TERM: - self._variables.add_item_to_group("funcs", name, __variable) + elif typ is QualityVarType.CONST: + self._variables.add_item_to_group("constants", name, __variable) + elif typ is QualityVarType.PARAM: + self._variables.add_item_to_group("parameters", name, __variable) + elif typ is QualityVarType.TERM: + self._variables.add_item_to_group("terms", name, __variable) else: self._variables.add_item_to_group(None, name, __variable) def add_species( self, - species_type: Union[str, int, VariableType], + species_type: Union[str, int, SpeciesType], name: str, units: str, atol: float = None, @@ -1003,7 +1156,7 @@ def add_species( Parameters ---------- - species_type : ~VariableType.BULK | ~VariableType.WALL + species_type : BULK | WALL the type of species name : str the name/symbol of the species @@ -1030,23 +1183,43 @@ def add_species( TypeError if atol and rtol are not both None or both a float """ - species_type = VariableType.get(species_type) - if species_type not in [VariableType.BULK, VariableType.WALL]: - raise ValueError("Species must be BULK or WALL, got {:s}".format(species_type)) + species_type = SpeciesType.get(species_type) + if species_type not in [SpeciesType.BULK, SpeciesType.WALL]: + raise ValueError( + "Species must be BULK or WALL, got {:s}".format(species_type) + ) if self._is_variable_registered(name): - raise KeyExistsError("The variable {} already exists in this model".format(name)) + raise KeyExistsError( + "The variable {} already exists in this model".format(name) + ) if (atol is None) ^ (rtol is None): - raise TypeError("atol and rtol must be the same type, got {} and {}".format(atol, rtol)) - if species_type is VariableType.BULK: - var = BulkSpecies(name=name, units=units, atol=atol, rtol=rtol, note=note, _qm=self) - elif species_type is VariableType.WALL: - var = WallSpecies(name=name, units=units, atol=atol, rtol=rtol, note=note, _qm=self) + raise TypeError( + "atol and rtol must be the same type, got {} and {}".format(atol, rtol) + ) + var = Species( + species_type=species_type, + name=name, + units=units, + atol=atol, + rtol=rtol, + note=note, + _qm=self, + ) self._species[name] = var - self._inital_qual_dict[name] = dict([("global", None), ("nodes", dict()), ("links", dict())]) + self._inital_qual_dict[name] = dict( + [("global", None), ("nodes", dict()), ("links", dict())] + ) self._source_dict[name] = dict() return var - def add_bulk_species(self, name: str, units: str, atol: float = None, rtol: float = None, note: str = None) -> BulkSpecies: + def add_bulk_species( + self, + name: str, + units: str, + atol: float = None, + rtol: float = None, + note: str = None, + ) -> Species: """Add a new bulk species to the model. The atol and rtol parameters must either both be omitted or both be provided. @@ -1075,9 +1248,16 @@ def add_bulk_species(self, name: str, units: str, atol: float = None, rtol: floa TypeError if atol and rtol are not both None or both a float """ - return self.add_species(VariableType.BULK, name, units, atol, rtol, note) + return self.add_species(SpeciesType.BULK, name, units, atol, rtol, note) - def add_wall_species(self, name: str, units: str, atol: float = None, rtol: float = None, note: str = None) -> WallSpecies: + def add_wall_species( + self, + name: str, + units: str, + atol: float = None, + rtol: float = None, + note: str = None, + ) -> Species: """Add a new wall species to the model. The atol and rtol parameters must either both be omitted or both be provided. @@ -1106,9 +1286,17 @@ def add_wall_species(self, name: str, units: str, atol: float = None, rtol: floa TypeError if atol and rtol are not both None or both a float """ - return self.add_species(VariableType.WALL, name, units, atol, rtol, note) + return self.add_species(SpeciesType.WALL, name, units, atol, rtol, note) - def add_coefficient(self, coeff_type: Union[str, int, VariableType], name: str, global_value: float, note: str = None, units: str = None, **kwargs) -> Coefficient: + def add_coefficient( + self, + coeff_type: Union[str, int, QualityVarType], + name: str, + global_value: float, + note: str = None, + units: str = None, + **kwargs, + ) -> Union[Constant, Parameter]: """Add a new coefficient to the model. Parameters @@ -1139,19 +1327,27 @@ def add_coefficient(self, coeff_type: Union[str, int, VariableType], name: str, VariableNameExistsError if a variable with this name already exists in the model """ - coeff_type = VariableType.get(coeff_type) - if coeff_type not in [VariableType.CONST, VariableType.PARAM]: - raise ValueError("coeff_type must be CONST or PARAM, got {:s}".format(coeff_type)) + coeff_type = QualityVarType.get(coeff_type) + if coeff_type not in [QualityVarType.CONST, QualityVarType.PARAM]: + raise ValueError( + "coeff_type must be CONST or PARAM, got {:s}".format(coeff_type) + ) if self._is_variable_registered(name): - raise KeyExistsError("The variable {} already exists in this model".format(name)) - if coeff_type is VariableType.CONST: - var = Constant(name=name, global_value=global_value, note=note, units=units, _qm=self) - elif coeff_type is VariableType.PARAM: - var = Parameter(name=name, global_value=global_value, note=note, units=units, _qm=self, **kwargs) - self._coeffs[name] = var - return var + raise KeyExistsError( + "The variable {} already exists in this model".format(name) + ) + if coeff_type is QualityVarType.CONST: + return self.add_constant( + name=name, global_value=global_value, note=note, units=units + ) + else: + return self.add_parameter( + name=name, global_value=global_value, note=note, units=units, **kwargs + ) - def add_constant_coeff(self, name: str, global_value: float, note: str = None, units: str = None) -> Constant: + def add_constant( + self, name: str, global_value: float, note: str = None, units: str = None + ) -> Constant: """Add a new constant coefficient to the model. Parameters @@ -1179,10 +1375,24 @@ def add_constant_coeff(self, name: str, global_value: float, note: str = None, u VariableNameExistsError if a variable with this name already exists in the model """ - return self.add_coefficient(VariableType.CONST, name=name, global_value=global_value, note=note, units=units) + if self._is_variable_registered(name): + raise KeyExistsError( + "The variable {} already exists in this model".format(name) + ) + var = Constant( + name=name, global_value=global_value, note=note, units=units, _qm=self + ) + self._constants[name] = var + return var - def add_parameterized_coeff( - self, name: str, global_value: float, note: str = None, units: str = None, pipe_values: Dict[str, float] = None, tank_values: Dict[str, float] = None + def add_parameter( + self, + name: str, + global_value: float, + note: str = None, + units: str = None, + pipe_values: Dict[str, float] = None, + tank_values: Dict[str, float] = None, ) -> Parameter: """Add a new parameterized coefficient (based on pipe/tank name) to the model. @@ -1215,7 +1425,21 @@ def add_parameterized_coeff( VariableNameExistsError if a variable with this name already exists in the model """ - return self.add_coefficient(VariableType.PARAM, name=name, global_value=global_value, note=note, units=units, pipe_values=pipe_values, tank_values=tank_values) + if self._is_variable_registered(name): + raise KeyExistsError( + "The variable {} already exists in this model".format(name) + ) + var = Parameter( + name=name, + global_value=global_value, + note=note, + units=units, + pipe_values=pipe_values, + tank_values=tank_values, + _qm=self, + ) + self._params[name] = var + return var def add_other_term(self, name: str, expression: str, note: str = None) -> OtherTerm: """Add a new user-defined function to the model. @@ -1244,7 +1468,9 @@ def add_other_term(self, name: str, expression: str, note: str = None) -> OtherT if a variable with this name already exists in the model """ if self._is_variable_registered(name): - raise KeyExistsError("The variable {} already exists in this model".format(name)) + raise KeyExistsError( + "The variable {} already exists in this model".format(name) + ) var = OtherTerm(name=name, expression=expression, note=note, _qm=self) self._terms[name] = var return var @@ -1297,12 +1523,21 @@ def reactions(self, location: LocationType = None): a reaction defined within the model """ location = LocationType.get(location) - for v in self._dynamics.values(): - if location is not None and v.location != location: - continue - yield v - - def add_reaction(self, location: LocationType, species: Union[str, Species], dynamics: Union[str, int, DynamicsType], expression: str, note: str = None): + if location is None or location is LocationType.PIPE: + for v in self._pipe_rxns.values(): + yield v + if location is None or location is LocationType.TANK: + for v in self._tank_rxns.values(): + yield v + + def add_reaction( + self, + location: LocationType, + species: Union[str, Species], + dynamics: Union[str, int, DynamicsType], + expression: str, + note: str = None, + ): """Add a multispecies water quality reaction to the model. Parameters @@ -1338,29 +1573,59 @@ def add_reaction(self, location: LocationType, species: Union[str, Species], dyn location = LocationType.get(location) species = str(species) if species not in self._species.keys(): - raise ValueError("The species {} does not exist in the model, failed to add reaction.".format(species)) - _key = AbstractReaction.to_key(species, location) - if _key in self._dynamics.keys(): - raise RuntimeError("The species {} already has a {} reaction defined. Use set_reaction instead.") + raise ValueError( + "The species {} does not exist in the model, failed to add reaction.".format( + species + ) + ) + _key = species # = AbstractReaction.to_key(species, location) + if (location is LocationType.PIPE and _key in self._pipe_rxns.keys()) or ( + location is LocationType.TANK and _key in self._tank_rxns.keys() + ): + raise RuntimeError("The species {} already has a {} reaction defined.") dynamics = DynamicsType.get(dynamics) new = None if dynamics is DynamicsType.EQUIL: - new = EquilibriumDynamics(species=species, location=location, expression=expression, note=note, _qm=self) + new = EquilibriumDynamics( + species=species, + location=location, + expression=expression, + note=note, + _qm=self, + ) elif dynamics is DynamicsType.RATE: - new = RateDynamics(species=species, location=location, expression=expression, note=note, _qm=self) + new = RateDynamics( + species=species, + location=location, + expression=expression, + note=note, + _qm=self, + ) elif dynamics is DynamicsType.FORMULA: - new = FormulaDynamics(species=species, location=location, expression=expression, note=note, _qm=self) + new = FormulaDynamics( + species=species, + location=location, + expression=expression, + note=note, + _qm=self, + ) else: raise ValueError("Invalid dynamics type, {}".format(dynamics)) if location is LocationType.PIPE: - self._pipe_dynamics[str(new)] = new + self._pipe_rxns[str(new)] = new elif location is LocationType.TANK: - self._tank_dynamics[str(new)] = new + self._tank_rxns[str(new)] = new else: raise ValueError("Invalid location type, {}".format(location)) return new - def add_pipe_reaction(self, species: Union[str, Species], dynamics: Union[str, int, DynamicsType], expression: str, note: str = None) -> AbstractReaction: + def add_pipe_reaction( + self, + species: Union[str, Species], + dynamics: Union[str, int, DynamicsType], + expression: str, + note: str = None, + ) -> AbstractReaction: """Add a pipe reaction. See also :meth:`add_reaction`. Parameters @@ -1379,9 +1644,21 @@ def add_pipe_reaction(self, species: Union[str, Species], dynamics: Union[str, i ReactionDynamics the reaction object """ - return self.add_reaction(LocationType.PIPE, species=species, dynamics=dynamics, expression=expression, note=note) + return self.add_reaction( + LocationType.PIPE, + species=species, + dynamics=dynamics, + expression=expression, + note=note, + ) - def add_tank_reaction(self, species: Union[str, Species], dynamics: Union[str, int, DynamicsType], expression: str, note: str = None) -> AbstractReaction: + def add_tank_reaction( + self, + species: Union[str, Species], + dynamics: Union[str, int, DynamicsType], + expression: str, + note: str = None, + ) -> AbstractReaction: """Add a pipe reaction. See also :meth:`add_reaction`. Parameters @@ -1400,9 +1677,19 @@ def add_tank_reaction(self, species: Union[str, Species], dynamics: Union[str, i ReactionDynamics the reaction object """ - return self.add_reaction(LocationType.TANK, species=species, dynamics=dynamics, expression=expression, note=note) + return self.add_reaction( + LocationType.TANK, + species=species, + dynamics=dynamics, + expression=expression, + note=note, + ) - def remove_reaction(self, species: Union[str, Species], location: Union[str, int, LocationType, Literal["all"]]): + def remove_reaction( + self, + species: Union[str, Species], + location: Union[str, int, LocationType, Literal["all"]], + ): """Remove a reaction for a species from the model Parameters @@ -1421,28 +1708,30 @@ def remove_reaction(self, species: Union[str, Species], location: Union[str, int location = LocationType.get(location) species = str(species) if location is None: - raise TypeError('location cannot be None when removing a reaction. Use "all" for all locations.') + raise TypeError( + 'location cannot be None when removing a reaction. Use "all" for all locations.' + ) elif location == "all": name = AbstractReaction.to_key(species, LocationType.PIPE) try: - self._pipe_dynamics.__delitem__(name) + self._pipe_rxns.__delitem__(name) except KeyError: pass name = AbstractReaction.to_key(species, LocationType.TANK) try: - self._tank_dynamics.__delitem__(name) + self._tank_rxns.__delitem__(name) except KeyError: pass elif location is LocationType.PIPE: name = AbstractReaction.to_key(species, LocationType.PIPE) try: - self._pipe_dynamics.__delitem__(name) + self._pipe_rxns.__delitem__(name) except KeyError: pass elif location is LocationType.TANK: name = AbstractReaction.to_key(species, LocationType.TANK) try: - self._tank_dynamics.__delitem__(name) + self._tank_rxns.__delitem__(name) except KeyError: pass else: @@ -1469,24 +1758,20 @@ def get_reaction(self, species, location): raise TypeError("location must be a string, int, or LocationType") species = str(species) location = LocationType.get(location) - loc = location.name.lower() if location == LocationType.PIPE: - return self._pipe_dynamics.get(species + "." + loc) + return self._pipe_rxns.get(species) elif location == LocationType.TANK: - return self._tank_dynamics.get(species + "." + loc) + return self._tank_rxns.get(species) def init_printing(self, *args, **kwargs): """Call sympy.init_printing""" init_printing(*args, **kwargs) @property - def citations(self) -> List[Union[str, Citation]]: - """A list of citation strings or Citation objects. - The Citation object from wntr.utils does not have to be used, but an object of - a different type should have a "to_dict" method to ensure that dictionary and - json conversions work as intended. + def references(self) -> List[Union[str, dict]]: + """A list of citation strings or dict objects. """ - return self._citations + return self._references @property def options(self) -> MultispeciesOptions: @@ -1498,7 +1783,9 @@ def options(self, value): if isinstance(value, dict): self._options = MultispeciesOptions.factory(value) elif not isinstance(value, MultispeciesOptions): - raise TypeError("Expected a MultispeciesOptions object, got {}".format(type(value))) + raise TypeError( + "Expected a MultispeciesOptions object, got {}".format(type(value)) + ) else: self._options = value @@ -1507,7 +1794,7 @@ def link_water_network_model(self, wn: WaterNetworkModel): def to_dict(self) -> dict: """Convert this water quality model to a dictionary""" - wntr.quality.io.to_dict() + return wntr.quality.io.to_dict(self) def from_dict(self, d) -> dict: """Append to this water quality model from a dictionary""" @@ -1515,5 +1802,65 @@ def from_dict(self, d) -> dict: def __repr__(self): if self._msxfile or self.name: - return "{}({})".format(self.__class__.__name__, repr(self._msxfile) if self._msxfile else repr(self.name)) + return "{}({})".format( + self.__class__.__name__, + repr(self._msxfile) if self._msxfile else repr(self.name), + ) return super().__repr__() + + def pycode(self): + lines = list() + lines.append("msx = {}()".format(self.__class__.__qualname__)) + lines.append("msx.title = {}".format(repr(self.title))) + for citation in self.references: + lines.append("msx.references.append({})".format(repr(self.references))) + for v in self._species.values(): + lines.append( + "msx.add_species({})".format( + ", ".join( + ["{}={}".format(k, repr(v1)) for k, v1 in v.to_dict().items()] + ) + ) + ) + for v in self._constants.values(): + lines.append( + "msx.add_constant({})".format( + ", ".join( + ["{}={}".format(k, repr(v1)) for k, v1 in v.to_dict().items()] + ) + ) + ) + for v in self._params.values(): + lines.append( + "msx.add_parameter({})".format( + ", ".join( + ["{}={}".format(k, repr(v1)) for k, v1 in v.to_dict().items()] + ) + ) + ) + for v in self._terms.values(): + lines.append( + "msx.add_other_term({})".format( + ", ".join( + ["{}={}".format(k, repr(v1)) for k, v1 in v.to_dict().items()] + ) + ) + ) + for v in self._pipe_rxns.values(): + lines.append( + "msx.add_pipe_reaction({})".format( + ", ".join( + ["{}={}".format(k, repr(v1)) for k, v1 in v.to_dict().items()] + ) + ) + ) + for v in self._tank_rxns.values(): + lines.append( + "msx.add_tank_reaction({})".format( + ", ".join( + ["{}={}".format(k, repr(v1)) for k, v1 in v.to_dict().items()] + ) + ) + ) + lines.append("msx.options = {}".format(self.options.to_dict())) + return lines From 9902471d253910cad7ec1b8ad3b65e41b6591ed5 Mon Sep 17 00:00:00 2001 From: dbhart Date: Tue, 24 Oct 2023 19:35:03 -0600 Subject: [PATCH 32/75] Update to package structure --- wntr/quality/__init__.py | 24 +- wntr/quality/base.py | 340 ++--- wntr/quality/io.py | 42 - wntr/quality/library.py | 568 ++++++-- wntr/quality/multispecies.py | 2607 ++++++++++++++-------------------- wntr/quality/options.py | 4 +- 6 files changed, 1653 insertions(+), 1932 deletions(-) delete mode 100644 wntr/quality/io.py diff --git a/wntr/quality/__init__.py b/wntr/quality/__init__.py index 52691d7c7..e625cb7ae 100644 --- a/wntr/quality/__init__.py +++ b/wntr/quality/__init__.py @@ -6,25 +6,7 @@ # sympy from ..epanet.msx.exceptions import EpanetMsxException -from .base import ( - DynamicsType, - LocationType, - AbstractReaction, - AbstractVariable, - VariableType, -) -from .multispecies import FormulaDynamics -from .multispecies import ( - BulkSpecies, - Coefficient, - Constant, - EquilibriumDynamics, - InternalVariable, - MultispeciesQualityModel, - OtherTerm, - Parameter, - RateDynamics, - Species, - WallSpecies, -) +from .base import * +from .multispecies import * from .options import MultispeciesOptions +from . import library diff --git a/wntr/quality/base.py b/wntr/quality/base.py index 1912aab46..43e67e955 100644 --- a/wntr/quality/base.py +++ b/wntr/quality/base.py @@ -5,22 +5,16 @@ and/or mixin classes, and should not be instantiated directly. """ -import abc -import enum -import logging from abc import ABC, abstractmethod, abstractproperty -from collections.abc import MutableMapping -from enum import Enum, IntFlag, IntEnum -from typing import Any, ClassVar, Dict, Generator, List, Union +import logging +from enum import Enum, IntEnum +from typing import Any, Dict +from wntr.epanet.util import ENcomment +from wntr.quality.multispecies import Species +from wntr.utils.disjoint_mapping import KeyExistsError, VariablesRegistry -import numpy as np -from wntr.network.base import AbstractModel -from wntr.network.model import WaterNetworkModel -from wntr.network.elements import Pattern -from wntr.quality.options import MultispeciesOptions from wntr.utils.enumtools import add_get -from wntr.utils.ordered_set import OrderedSet has_sympy = False try: @@ -218,9 +212,9 @@ def _coth(x): return 1 / tanh(x) RESERVED_NAMES = ( tuple([v["name"] for v in HYDRAULIC_VARIABLES]) - + tuple([k for k, v in EXPR_FUNCTIONS.items()]) - + tuple([k.upper() for k, v in EXPR_FUNCTIONS.items()]) - + tuple([k.capitalize() for k, v in EXPR_FUNCTIONS.items()]) + + tuple([k.lower() for k in EXPR_FUNCTIONS.keys()]) + + tuple([k.upper() for k in EXPR_FUNCTIONS.keys()]) + + tuple([k.capitalize() for k in EXPR_FUNCTIONS.keys()]) + ("Mul", "Add", "Pow", "Integer", "Float") ) """The WNTR reserved names. This includes the MSX hydraulic variables @@ -232,7 +226,6 @@ def _coth(x): return 1 / tanh(x) _global_dict = dict() for k, v in EXPR_FUNCTIONS.items(): - _global_dict[k] = v _global_dict[k.lower()] = v _global_dict[k.capitalize()] = v _global_dict[k.upper()] = v @@ -414,264 +407,131 @@ class DynamicsType(Enum): R = RATE F = FORMULA +__all__ = [ + 'HYDRAULIC_VARIABLES', + 'EXPR_FUNCTIONS', + 'RESERVED_NAMES', + 'EXPR_TRANSFORMS', + 'QualityVarType', + 'SpeciesType', + 'LocationType', + 'DynamicsType', + 'WaterQualityVariable', + 'WaterQualityReaction', +] -class AbstractVariable(ABC): - """The base for a reaction variable. - - Attributes - ---------- - name : str - The name (symbol) for the variable, must be a valid MSX name - """ - def __str__(self) -> str: - """Returns the name of the variable""" - return self.name +class WaterQualityReaction(ABC): + def __init__(self, dynamics_type: DynamicsType, *, note=None) -> None: + """A water quality reaction definition. - def __hash__(self) -> int: - return hash(str(self)) + This abstract class must be subclassed. - __variable_registry = None + Arguments + --------- + dynamics_type : DynamicsType + The type of reaction dynamics being described by the expression: one of RATE, FORMULA, or EQUIL. - @property - def _variable_registry(self) -> "AbstractQualityModel": - return self.__variable_registry - @_variable_registry.setter - def _variable_registry(self, value): - if value is not None and not isinstance(value, AbstractQualityModel): - raise TypeError( - "Linked model must be a RxnModelRegistry, got {}".format(type(value)) - ) - self.__variable_registry = value + Keyword Arguments + ----------------- + note : str | dict | ENcomment, optional + Supplementary information regarding this reaction, by default None (see :class:`~wntr.epanet.util.ENcomment` for dict structure). - def validate(self): - """Validate that this object is a member of the RxnModelRegistry Raises ------ TypeError - if the model registry isn't linked + if dynamics_type is invalid """ - if not isinstance(self._variable_registry, AbstractQualityModel): - raise TypeError("This object is not connected to any RxnModelRegistry") - - @abstractproperty - def var_type(self) -> QualityVarType: - """The variable type.""" - raise NotImplementedError - - def is_species(self) -> bool: - """Check to see if this variable represents a species (bulk or wall). + dynamics_type = DynamicsType.get(dynamics_type) + if dynamics_type is None: + raise TypeError("dynamics cannot be None") + self._dynamics_type = dynamics_type + self.note = note - Returns - ------- - bool - True if this is a species object, False otherwise + def dynamics_type(self) -> DynamicsType: + """The type of dynamics being described. + See :class:`DynamicsType` for valid values. """ - return self.var_type == QualityVarType.SPECIES + raise NotImplementedError - def is_coeff(self) -> bool: - """Check to see if this variable represents a coefficient (constant or parameter). + def __str__(self) -> str: + """Return a string representation of the reaction""" + return "{}({}) = ".format(self.__class__.__name__, self._dynamics_type.name) - Returns - ------- - bool - True if this is a coefficient object, False otherwise - """ + def __repr__(self) -> str: return ( - self.var_type == QualityVarType.CONST - or self.var_type == QualityVarType.PARAM + "{}(".format(self.__class__.__name__) + + ", ".join(["{}={}".format(k, repr(v)) for k, v in self.to_dict().items()]) + + ")" ) - def is_other_term(self) -> bool: - """Check to see if this variable represents a function (MSX term). - - Returns - ------- - bool - True if this is a term/function object, False otherwise - """ - return self.var_type == QualityVarType.TERM - - @property - def symbol(self): - """Representation of the variable's name as a sympy.Symbol""" - return Symbol(self.name) + @abstractmethod + def to_dict(self) -> dict: + raise NotImplementedError - def to_symbolic(self, transformations=EXPR_TRANSFORMS): - """Convert to a symbolic expression. - Parameters - ---------- - transformations : tuple of sympy transformations - transformations to apply to the expression, by default EXPR_TRANSFORMS +class WaterQualityVariable(ABC): + """A multi-species water quality model variable. - Returns - ------- - sympy.Expr - the expression parsed by sympy - """ - return self.symbol - - -class AbstractReaction(ABC): - """The base for a reaction. - - Attributes - ---------- - species : str - the name of the species whose reaction dynamics is being described - location : LocationType | str - the location the reaction occurs (pipes or tanks) - dynamics : DynamicsType | str - the type of reaction dynamics (left-hand-side) - expression : str - the expression for the reaction dynamics (right-hand-side) + This abstract class must be extended before use. There are several concrete classes + that inhert from this class, including + :class:`~wntr.quality.msx.Species`, + :class:`~wntr.quality.msx.Constant`, + :class:`~wntr.quality.msx.Parameter`, + and :class:`~wntr.quality.msx.Term`. + See also the :class:`~wntr.quality.msx.MultispeciesModel`, which has the functions + required to create these variables and define reactions. """ - def __str__(self) -> str: - """Name of the species""" - return self.species # self.to_key(self.species, self.location) - - def __hash__(self) -> int: - """Makes the reaction hashable by hashing the `str` representation""" - return hash(self.to_key(self.species, self.location)) + def __init__(self, name: str, *, note=None, _vars=None) -> None: + """Multi-species variable constructor arguments. - def __repr__(self) -> str: - return "{}(species={}, location={}, expression={}, note={})".format( - self.__class__.__name__, - repr(self.species), - repr( - self.location.name - if isinstance(self.location, LocationType) - else self.location - ), - repr(self.expression), - repr(self.note.to_dict() if hasattr(self.note, "to_dict") else self.note), - ) - - __variable_registry = None - - @property - def _variable_registry(self) -> "AbstractQualityModel": - return self.__variable_registry + Arguments + --------- + name : str + The name/symbol for the variable. Must be a valid MSX variable name. - @_variable_registry.setter - def _variable_registry(self, value): - if value is not None and not isinstance(value, AbstractQualityModel): - raise TypeError( - "Linked model must be a RxnModelRegistry, got {}".format(type(value)) - ) - self.__variable_registry = value - - def validate(self): - """Validate that this object is a member of the RxnModelRegistry + Keyword Arguments + ----------------- + note : str | dict | ENcomment, optional + Supplementary information regarding this variable, by default None (see :class:`~wntr.epanet.util.ENcomment` for dict structure). + As dict it can have two keys, "pre" and "post". See :class:`ENcomment` + for more details. Raises ------ - TypeError - if the model registry isn't linked - """ - if not isinstance(self._variable_registry, AbstractQualityModel): - raise TypeError("This object is not connected to any RxnModelRegistry") + KeyExistsError + the name is already taken + ValueError + the name is a reserved word - @abstractproperty - def dynamics(self) -> DynamicsType: - """The type of reaction dynamics being described (or, the left-hand-side of the equation)""" - raise NotImplementedError - @classmethod - def to_key(cls, species, location): - """Generate a dictionary key (equivalent to the ``str`` casting of a reaction) - without having the object itself. - - Parameters - ---------- - species : str - the species for the reaction - location : RxnLocationType or str - the location of the reaction - - Returns - ------- - str - a species/location unique name - """ - location = LocationType.get(location) - return str(species) + "::" + location.name.lower() + The following should only be used by model building functions, and the + user should never need to pass these arguments. - @abstractmethod - def to_symbolic(self, transformations: tuple = EXPR_TRANSFORMS): - """Convert to a symbolic expression. - - Parameters - ---------- - transformations : tuple of sympy transformations - transformations to apply to the expression, by default :data:`EXPR_TRANSFORMS` - - Returns - ------- - sympy.Expr or sympy.Symbol - the expression parsed by sympy + Other Parameters + ---------------- + _vars : VariablesRegistry, optional + the variables registry object of the model this variable was added to, by default None """ - if not has_sympy: - return self.expression - return parse_expr( - self.expression, - local_dict=self._variable_registry.variable_dict() - if self._variable_registry is not None - else None, - transformations=transformations, - global_dict=_global_dict, - evaluate=False, - ) - - -class AbstractQualityModel(ABC): - """Abstract methods any water quality model should include.""" - - @abstractmethod - def variables(self, var_type=None): - """Generator over all defined variables, optionally limited by variable type""" - raise NotImplementedError - - @abstractmethod - def variable_dict(self) -> Dict[str, Any]: - """Create a dictionary of variable names and their sympy represenations""" - raise NotImplementedError - - @abstractmethod - def add_variable(self, __variable: AbstractVariable): - """Add a variable *object* to the model""" - raise NotImplementedError - - @abstractmethod - def get_variable(self, name: str) -> AbstractVariable: - """Get a specific variable by name""" - raise NotImplementedError - - @abstractmethod - def remove_variable(self, name: str): - """Delete a specified variable from the model""" - raise NotImplementedError - - @abstractmethod - def reactions(self, location=None): - """Generator over all defined reactions, optionally limited by reaction location""" - raise NotImplementedError - - @abstractmethod - def add_reaction(self, __reaction: AbstractReaction): - """Add a reaction *object* to the model""" - raise NotImplementedError + if _vars is not None and name in _vars: + raise KeyExistsError("This variable name is already taken") + elif name in RESERVED_NAMES: + raise ValueError("Name cannot be a reserved name") + self.name: str = name + """The name/ID of this variable, must be a valid EPANET/MSX ID""" + self.note = note + """A note related to this variable""" + self._vars: VariablesRegistry = _vars - @abstractmethod - def get_reaction(self, species, location=None) -> List[AbstractReaction]: - """Get reaction(s) for a species, optionally only for one location""" + @abstractproperty + def var_type(self) -> QualityVarType: + """The type of reaction model variable""" raise NotImplementedError @abstractmethod - def remove_reaction(self, species, location=None): - """Remove reaction(s) for a species, optionally only for one location""" - raise NotImplementedError + def to_dict(self) -> Dict[str, Any]: + """Represent the object as a dictionary""" + raise NotImplementedError \ No newline at end of file diff --git a/wntr/quality/io.py b/wntr/quality/io.py deleted file mode 100644 index a0ad77e76..000000000 --- a/wntr/quality/io.py +++ /dev/null @@ -1,42 +0,0 @@ -# coding: utf-8 -"""Mulispecies reaction model I/O functions. - -""" - -import wntr.epanet.msx -import json - -from wntr.utils.citations import Citation, to_jsontypes - - -def to_dict(msx): - """Convert a multispecies reaction model to a dictionary representation""" - from wntr import __version__ - rep = dict( - version="wntr-{}".format(__version__), - name=msx.name if msx.name else msx._msxfile, - comment=msx.title if msx.title else "WaterQualityModel - units assumed to be internally consistent", - citations=to_jsontypes(msx._citations), - options=msx._options.to_dict(), - variables=dict( - species=[v.to_dict() for v in msx._species.values()], - coefficients=[v.to_dict() for v in msx._coeffs.values()], - other_terms=[v.to_dict() for v in msx._terms.values()], - ), - reactions=dict( - pipes=[v.to_dict() for v in msx._pipe_dynamics.values()], - tanks=[v.to_dict() for v in msx._tank_dynamics.values()], - ), - patterns=msx._patterns.copy(), - initial_quality=msx._initial_quality.copy(), - ) - # rep["sources"] = dict() - # for sp, v in msx._sources: - # if v is not None and len(v) > 0: - # rep["sources"][sp] = dict() - # for node, source in v.items(): - # rep["sources"][sp][node] = source.to_dict() - return rep - -def from_dict(d): - raise NotImplementedError \ No newline at end of file diff --git a/wntr/quality/library.py b/wntr/quality/library.py index df8bae011..db2dea20a 100644 --- a/wntr/quality/library.py +++ b/wntr/quality/library.py @@ -23,18 +23,51 @@ .. important:: - Make sure to provide all appropriate citations to the model in your creation + Make sure to provide all appropriate references to the model in your creation function. + +.. _msx_library_note: + +.. rubric:: Note regarding functions within the library that accept a water network model + +If a water network is provided that does not have an ``msx`` attribute, then a new model will be +created and added to the network. The new model will also be returned as an object. + +If a water network is provided that already has an ``msx`` attribute, then this function will: +first check to see if there are variables that are in conflict with the existing reaction +model. If there are conflicts, an exception will be raised. The :attr:`~MultispeciesOptions.area_units` +and :attr:`~MultispeciesOptions.rate_units` will also be checked for conflicts, and an exception raised +if they differ from the already-existing units. +If there are no conflicts, then the variables and reactions for this model will be added to the +existing model. If there are conflicts, then the user must resolve them and try again. + """ import logging -from wntr.utils.citations import Citation from wntr.quality.multispecies import MultispeciesQualityModel from wntr.network.model import WaterNetworkModel +from .multispecies import MultispeciesQualityModel +from .base import LocationType, SpeciesType, DynamicsType + +PIPE = LocationType.PIPE +TANK = LocationType.TANK +BULK = SpeciesType.BULK +WALL = SpeciesType.WALL +RATE = DynamicsType.RATE +EQUIL = DynamicsType.EQUIL +FORMULA = DynamicsType.FORMULA logger = logging.getLogger(__name__) +__all__ = [ + "cite_msx", + "nicotine", + "nicotine_ri", + "lead_ppm", + "arsenic_chloramine", + "batch_chloramine_decay", +] ########################################## ## @@ -46,6 +79,30 @@ ## unless you mark the string as raw, not interpreted, text. ## + +def cite_msx() -> dict: + """A citation generator for the EPANET-MSX user guide. + + References + ---------- + [SRU23]_ Shang, F. and Rossman, L.A. and Uber, J.G. (2023) "EPANET-MSX 2.0 User Manual". (Cincinnati, OH: Water Infrastructure Division (CESER), U.S. Environmental Protection Agency). EPA/600/R-22/199. + + """ + return 'Shang, F. and Rossman, L.A. and Uber, J.G. (2023) "EPANET-MSX 2.0 User Manual". (Cincinnati, OH: Water Infrastructure Division (CESER), U.S. Environmental Protection Agency). EPA/600/R-22/199.' + # return dict( + # entry_type="report", + # key="SRU23", + # fields=dict( + # title="EPANET-MSX 2.0 User Manual", + # year=2023, + # author="Shang, F. and Rossman, L.A. and Uber, J.G.", + # institution="Water Infrastructure Division (CESER), U.S. Environmental Protection Agency", + # location="Cincinnati, OH", + # number="EPA/600/R-22/199", + # ), + # ) + + # FIXME: Need to actually do the checks and adding to the wn @@ -80,14 +137,14 @@ def nicotine(wn: WaterNetworkModel = None) -> MultispeciesQualityModel: .. math:: k_d &= 2.33 \times 10^{-3}~\mathrm{min}^{-1} \\ - K_1 &= 5.92 \times 10^{-2}~\mathrm{L}\cdot\mathrm{min}^{-1}\cdot\mathrm{mg}_{\mathrm{(Nic)}}^{-1} \\ - K_2 &= 1.83 \times 10^{-1}~\mathrm{L}\cdot\mathrm{min}^{-1}\cdot\mathrm{mg}_{\mathrm{(Cl)}}^{-1} + k_1 &= 5.92 \times 10^{-2}~\mathrm{L}\,\mathrm{min}^{-1}\,\mathrm{mg}_{\mathrm{(Nic)}}^{-1} \\ + k_2 &= 1.83 \times 10^{-1}~\mathrm{L}\,\mathrm{min}^{-1}\,\mathrm{mg}_{\mathrm{(Cl)}}^{-1} Other terms .. math:: - RxCl &= k_d \cdot HOCL + K_1 \cdot Nx \cdot HOCL \\ - RxN &= K_2 \cdot Nx \cdot HOCL + RxCl &= k_d \, HOCL + k_1 \, Nx \, HOCL \\ + RxN &= k_2 \, Nx \, HOCL Pipe reactions .. math:: @@ -100,16 +157,8 @@ def nicotine(wn: WaterNetworkModel = None) -> MultispeciesQualityModel: Notes ----- - If a water network is provided that does not have an ``msx`` attribute, then a new model will be - created and added to the network. The new model will also be returned as an object. + Please see `msx_library_note`_ for information on how a model that is passed in should be handled. - If a water network is provided that already has an ``msx`` attribute, then this function will: - first check to see if there are variables that are in conflict with the existing reaction - model. If there are conflicts, an exception will be raised. The :attr:`~MultispeciesOptions.area_units` - and :attr:`~MultispeciesOptions.rate_units` will also be checked for conflicts, and an exception raised - if they differ from the already-existing units. - If there are no conflicts, then the variables and reactions for this model will be added to the - existing model. If there are conflicts, then the user must resolve them and try again. """ msx = MultispeciesQualityModel() msx.name = "nicotine" @@ -117,15 +166,25 @@ def nicotine(wn: WaterNetworkModel = None) -> MultispeciesQualityModel: msx.options.area_units = "m2" msx.options.rate_units = "min" msx.options.timestep = 1 - msx.add_bulk_species("Nx", units="mg", note="Nicotine") - msx.add_bulk_species("HOCL", units="mg", note="Free chlorine") - msx.add_constant_coeff("kd", global_value=2.33e-3, units="min^(-1)", note="decay rate") - msx.add_constant_coeff("K1", global_value=5.92e-2, units="L * min^(-1) * mg^(-1)", note="decay constant for chlorine as function of mass(Nic)") - msx.add_constant_coeff("K2", global_value=1.84e-1, units="L * min^(-1) * mg^(-1)", note="decay constant for nicotine as function of mass(Cl)") - msx.add_other_term("RxCl", expression="kd * HOCL + K1 * Nx * HOCL") - msx.add_other_term("RxN", expression="K2 * Nx * HOCL") - msx.add_pipe_reaction("Nx", "rate", expression="-RxN") - msx.add_pipe_reaction("HOCL", "rate", expression="-RxCl") + msx.add_species("Nx", "bulk", units="mg", note="Nicotine") + msx.add_species(name="HOCL", species_type=BULK, units="mg", note="Free chlorine") + msx.add_constant("kd", value=2.33e-3, units="min^(-1)", note="decay rate") + msx.add_constant( + "K1", + value=5.92e-2, + units="L * min^(-1) * mg^(-1)", + note="decay constant for chlorine as function of mass(Nic)", + ) + msx.add_constant( + "K2", + value=1.84e-1, + units="L * min^(-1) * mg^(-1)", + note="decay constant for nicotine as function of mass(Cl)", + ) + msx.add_term("RxCl", expression="kd * HOCL + K1 * Nx * HOCL") + msx.add_term("RxN", expression="K2 * Nx * HOCL") + msx.add_reaction(species="Nx", location="pipe", dynamics_type="rate", expression="-RxN") + msx.add_reaction("HOCL", PIPE, dynamics_type=RATE, expression="-RxCl") return msx @@ -159,16 +218,16 @@ def nicotine_ri(wn: WaterNetworkModel = None) -> MultispeciesQualityModel: Coefficients .. math:: k_d &= 3.0 \times 10^{-5}~\mathrm{min}^{-1} \\ - K_1 &= 9.75 \times 10^{-2}~\mathrm{L}\cdot\mathrm{min}^{-1}\cdot\mathrm{mg}_{\mathrm{(Nic)}}^{-1}\\ - K_2 &= 5.73 \times 10^{-1}~\mathrm{L}\cdot\mathrm{min}^{-1}\cdot\mathrm{mg}_{\mathrm{(Cl)}}^{-1}\\ - K_3 &= 1.34 \times 10^{-2}~\mathrm{L}\cdot\mathrm{min}^{-1}\cdot\mathrm{mg}_{\mathrm{(Nic_2)}}^{-1}\\ - K_4 &= 2.19 \times 10^{-2}~\mathrm{L}\cdot\mathrm{min}^{-1}\cdot\mathrm{mg}_{\mathrm{(Cl)}}^{-1} + k_1 &= 9.75 \times 10^{-2}~\mathrm{L}\,\mathrm{min}^{-1}\,\mathrm{mg}_{\mathrm{(Nic)}}^{-1}\\ + k_2 &= 5.73 \times 10^{-1}~\mathrm{L}\,\mathrm{min}^{-1}\,\mathrm{mg}_{\mathrm{(Cl)}}^{-1}\\ + K_3 &= 1.34 \times 10^{-2}~\mathrm{L}\,\mathrm{min}^{-1}\,\mathrm{mg}_{\mathrm{(Nic_2)}}^{-1}\\ + K_4 &= 2.19 \times 10^{-2}~\mathrm{L}\,\mathrm{min}^{-1}\,\mathrm{mg}_{\mathrm{(Cl)}}^{-1} Other terms .. math:: - RXCL &= k_d \cdot HOCL + K_1 \cdot Nx \cdot HOCL + K_3 \cdot NX2 \cdot HOCL\\ - RXN &= K_2 \cdot Nx \cdot HOCL\\ - RXNX2 &= K_2 \cdot Nx \cdot HOCL - K_4 \cdot NX2 \cdot HOCL + RXCL &= k_d \, HOCL + k_1 \, Nx \, HOCL + K_3 \, NX2 \, HOCL\\ + RXN &= k_2 \, Nx \, HOCL\\ + RXNX2 &= k_2 \, Nx \, HOCL - K_4 \, NX2 \, HOCL Pipe reactions and tank reactions *(defined separately for pipe and tank)* .. math:: @@ -192,34 +251,45 @@ def nicotine_ri(wn: WaterNetworkModel = None) -> MultispeciesQualityModel: msx = MultispeciesQualityModel() msx.name = "nicotine_ri" msx.title = ("Nicotine - Chlorine reaction with reactive intermediate",) + # Set the options msx.options.area_units = "m2" msx.options.rate_units = "min" msx.options.timestep = 1 msx.options.atol = 1.0e-10 msx.options.rtol = 1.0e-10 + # Add species - msx.add_bulk_species("Nx", units="mg", note="Nicotine") - msx.add_bulk_species("HOCL", units="mg", note="Free Chlorine") - msx.add_bulk_species("NX2", units="mg", note="Intermediate Nicotine Reactive") + msx.add_species("Nx", "bulk", units="mg", note="Nicotine") + msx.add_species("HOCL", BULK, units="mg", note="Free Chlorine") + msx.add_species("NX2", "b", units="mg", note="Intermediate Nicotine Reactive") + # Add coefficients - msx.add_constant_coeff("kd", 3.0e-5, note="decay rate", units="1/min") - msx.add_constant_coeff("K1", global_value=9.75e-2, units="L * min^(-1) * mg^(-1)", note="decay constant for chlorine as function of mass(Nic)") - msx.add_constant_coeff("K2", global_value=5.73e-1, units="L * min^(-1) * mg^(-1)", note="decay constant for nicotine as function of mass(Cl)") - msx.add_constant_coeff("K3", global_value=1.34e-2, units="L * min^(-1) * mg^(-1)", note="decay constant for nicotine as function of mass(Nic2)") - msx.add_constant_coeff("K4", global_value=2.19e-2, units="L * min^(-1) * mg^(-1)", note="decay constant for nicotine as function of mass(Cl)") + msx.add_constant("kd", 3.0e-5, units="1/min", note="decay constant for chlorine over time") + msx.add_constant( + "K1", 9.75e-2, units="L * min^(-1) * mg^(-1)", note="decay constant for chlorine as function of mass(Nic)" + ) + msx.add_constant("K2", 5.73e-1, units="L * min^(-1) * mg^(-1)", note="decay constant for nicotine as function of mass(Cl)") + msx.add_constant( + "K3", 1.34e-2, units="L * min^(-1) * mg^(-1)", note="decay constant for nicotine as function of mass(Nic2)" + ) + msx.add_constant("K4", 2.19e-2, units="L * min^(-1) * mg^(-1)", note="decay constant for nicotine as function of mass(Cl)") + # Add terms (named subexpressions) - msx.add_other_term("RXCL", expression="kd * HOCL + K1 * Nx * HOCL + K3 * NX2 * HOCL") - msx.add_other_term("RXN", expression="K2 * Nx * HOCL") - msx.add_other_term("RXNX2", expression="K2 * Nx * HOCL - K4 * NX2 * HOCL") + msx.add_term("RXCL", "kd * HOCL + K1 * Nx * HOCL + K3 * NX2 * HOCL") + msx.add_term("RXN", "K2 * Nx * HOCL") + msx.add_term("RXNX2", "K2 * Nx * HOCL - K4 * NX2 * HOCL") + # Add pipe reactions, one per species - msx.add_pipe_reaction("Nx", "RATE", expression="-RXN") - msx.add_pipe_reaction("HOCL", "RATE", expression="-RXCL") - msx.add_pipe_reaction("NX2", "RATE", expression="RXNX2") + msx.add_reaction("Nx", "pipe", "RATE", "-RXN") + msx.add_reaction("HOCL", PIPE, RATE, "-RXCL") + msx.add_reaction("NX2", "p", "r", "RXNX2") + # Tank reactions actually aren't necessary since there aren't any wall species - msx.add_tank_reaction("Nx", "RATE", expression="-RXN") - msx.add_tank_reaction("HOCL", "RATE", expression="-RXCL") - msx.add_tank_reaction("NX2", "RATE", expression="RXNX2") + # but it is good form to add them anyway + msx.add_reaction("Nx", "tank", "rate", "-RXN") + msx.add_reaction("HOCL", TANK, RATE, "-RXCL") + msx.add_reaction("NX2", "t", "r", "RXNX2") return msx @@ -233,11 +303,13 @@ def lead_ppm(wn: WaterNetworkModel = None) -> MultispeciesQualityModel: wn : WaterNetworkModel, optional the water network to use to hold the new or updated reaction model, by default None + Returns ------- MultispeciesQualityModel the new or updated reaction/quality model + Model Description ----------------- This model is described in [BWMS20]_, and represents plumbosolvency of lead in lead pipes @@ -249,8 +321,8 @@ def lead_ppm(wn: WaterNetworkModel = None) -> MultispeciesQualityModel: Coefficients .. math:: - M &= 0.117~\mathrm{μg}_{\mathrm{(Pb)}} \cdot \mathrm{m}^{-2} \cdot \mathrm{s}^{-1} \\ - E &= 140.0~\mathrm{μg}_{\mathrm{(Pb)}} \cdot \mathrm{L}^{-1} + M &= 0.117~\mathrm{μg}_{\mathrm{(Pb)}} \, \mathrm{m}^{-2} \, \mathrm{s}^{-1} \\ + E &= 140.0~\mathrm{μg}_{\mathrm{(Pb)}} \, \mathrm{L}^{-1} Parameters [1]_ .. math:: @@ -258,12 +330,13 @@ def lead_ppm(wn: WaterNetworkModel = None) -> MultispeciesQualityModel: Pipe reactions [2]_ .. math:: - \frac{d}{dt}PB2 = F \cdot Av \cdot M \frac{\left( E - PB2 \right)}{E} + \frac{d}{dt}PB2 = F \, Av \, M \frac{\left( E - PB2 \right)}{E} Tank reactions .. math:: \frac{d}{dt}PB2 = 0 + References ---------- If this model is used, please cite the following paper(s). @@ -276,16 +349,6 @@ def lead_ppm(wn: WaterNetworkModel = None) -> MultispeciesQualityModel: Notes ----- - If a water network is provided that does not have an ``msx`` attribute, then a new model will be - created and added to the network. The new model will also be returned as an object. - - If a water network is provided that already has an ``msx`` attribute, then this function will: - first check to see if there are variables that are in conflict with the existing reaction - model. If there are conflicts, an exception will be raised. The :attr:`~MultispeciesOptions.area_units` - and :attr:`~MultispeciesOptions.rate_units` will also be checked for conflicts, and an exception raised - if they differ. - If there are no conflicts, then the variables and reactions for this model will be added to the - existing model. If there are conflicts, then the user must resolve them and try again. .. [1] The default value of a parameter is specified by "otherwise" in its mathematical definition. Because @@ -300,35 +363,36 @@ def lead_ppm(wn: WaterNetworkModel = None) -> MultispeciesQualityModel: msx.name = "lead_ppm" msx.title = "Lead Plumbosolvency Model (from Burkhardt et al 2020)" msx.desc = "Parameters for EPA HPS Simulator Model" - msx.citations.append( - Citation( - "article", - "BWMS20", - fields=dict( - title="Framework for Modeling Lead in Premise Plumbing Systems Using EPANET", - year=2020, - author=[ - "Jonathan B. Burkhardt", - "Hyoungmin Woo", - "James Mason", - "Feng Shang", - "Simoni Triantafyllidou", - "Michael R. Schock", - "Darren Lytle", - "Regan Murray", - ], - journaltitle="J Water Resour Plan Manag", - volume=146, - number=12, - date="2020-12-01", - doi="10.1061/(asce)wr.1943-5452.0001304", - eprint=[ - "PMID:33627937", - "PMCID:PMC7898126", - "NIHMSID:NIHMS1664627", - ], - ), - ) + msx.references.append( + """J. B. Burkhardt, et al. (2020) "Framework for Modeling Lead in Premise Plumbing Systems Using EPANET". `Journal of water resources planning and management`. 146(12). https://doi.org/10.1061/(asce)wr.1943-5452.0001304""" + # dict( + # entry_type="article", + # key="BWMS20", + # fields=dict( + # title="Framework for Modeling Lead in Premise Plumbing Systems Using EPANET", + # year=2020, + # author=[ + # "Jonathan B. Burkhardt", + # "Hyoungmin Woo", + # "James Mason", + # "Feng Shang", + # "Simoni Triantafyllidou", + # "Michael R. Schock", + # "Darren Lytle", + # "Regan Murray", + # ], + # journaltitle="J Water Resour Plan Manag", + # volume=146, + # number=12, + # date="2020-12-01", + # doi="10.1061/(asce)wr.1943-5452.0001304", + # eprint=[ + # "PMID:33627937", + # "PMCID:PMC7898126", + # "NIHMSID:NIHMS1664627", + # ], + # ), + # ) ) msx.options = { "report": { @@ -343,10 +407,322 @@ def lead_ppm(wn: WaterNetworkModel = None) -> MultispeciesQualityModel: "rtol": 1e-08, "atol": 1e-08, } - msx.add_bulk_species("PB2", "ug", note="dissolved lead (Pb)") - msx.add_constant_coeff("M", global_value=0.117, note="Desorption rate (ug/m^2/s)", units="ug * m^(-2) * s^(-1)") - msx.add_constant_coeff("E", global_value=140.0, note="saturation/plumbosolvency level (ug/L)", units="ug/L") - msx.add_parameterized_coeff("F", global_value=0, note="determines which pipes have reactions") - msx.add_pipe_reaction("PB2", "RATE", expression="F * Av * M * (E - PB2) / E") - msx.add_tank_reaction("PB2", "RATE", expression="0") + PB2 = msx.add_species(name="PB2", species_type=BULK, units="ug", note="dissolved lead (Pb)") + msx.add_constant("M", 0.117, note="Desorption rate (ug/m^2/s)", units="ug * m^(-2) * s^(-1)") + msx.add_constant("E", 140.0, note="saturation/plumbosolvency level (ug/L)", units="ug/L") + msx.add_parameter("F", global_value=0, note="determines which pipes have reactions") + PB2.add_reaction("pipes", "RATE", expression="F * Av * M * (E - PB2) / E") + PB2.add_reaction("tanks", RATE, expression="0") + return msx + + +def arsenic_chloramine(wn: WaterNetworkModel = None) -> MultispeciesQualityModel: + r"""Model monochloramine-arsenite-arsenate adsorption/desorption with fast equilibrium. + + Parameters + ---------- + wn : WaterNetworkModel, optional + the water network to use to hold the new or updated reaction model, by default None + + Returns + ------- + MultispeciesQualityModel + the new or updated reaction/quality model + + Model Description + ----------------- + This example models monochloramine oxidation of arsenite/arsenate and wall + adsorption/desorption, as given in section 3 of the EPANET-MSX user manual. + + The system of equations for the reaction in pipes is given in Eq. (2.4) through (2.7) + in [SRU23]_. + + .. math:: + + \frac{d}{dt}{(\mathsf{As}^\mathrm{III})} &= -k_a ~ {(\mathsf{As}^\mathrm{III})} ~ {(\mathsf{NH_2Cl})} \\ + \frac{d}{dt}{(\mathsf{As}^\mathrm{V})} &= k_a ~ {(\mathsf{As}^\mathrm{III})} ~ {(\mathsf{NH_2CL})} - Av \left( k_1 \left(S_\max - {(\mathsf{As}^\mathrm{V}_s)} \right) {(\mathsf{As}^\mathrm{V})} - k_2 ~ {(\mathsf{As}^\mathrm{V}_s)} \right) \\ + \frac{d}{dt}{(\mathsf{NH_2Cl})} &= -k_b ~ {(\mathsf{NH_2Cl})} \\ + {(\mathsf{As}^\mathrm{V}_s)} &= \frac{k_s ~ S_\max ~ {(\mathsf{As}^\mathrm{V})}}{1 + k_s {(\mathsf{As}^\mathrm{V})}} + + + where the various species, coefficients, and expressions are described in the tables below. + + + .. list-table:: Options + :header-rows: 1 + :widths: 3 3 10 + + * - Option + - Code + - Description + * - Rate units + - "HR" + - :math:`\mathrm{h}^{-1}` + * - Area units + - "M2" + - :math:`\mathrm{m}^2` + + + .. list-table:: Species + :header-rows: 1 + :widths: 2 2 2 3 4 6 + + * - Name + - Type + - Value + - Symbol + - Units + - Note + * - AS3 + - Bulk + - "UG" + - :math:`{\mathsf{As}^\mathrm{III}}` + - :math:`\require{upgreek}\upmu\mathrm{g~L^{-1}}` + - dissolved arsenite + * - AS5 + - Bulk + - "UG" + - :math:`{\mathsf{As}^\mathrm{V}}` + - :math:`\require{upgreek}\upmu\mathrm{g~L^{-1}}` + - dissolved arsenate + * - AStot + - Bulk + - "UG" + - :math:`{\mathsf{As}^\mathrm{tot}}` + - :math:`\require{upgreek}\upmu\mathrm{g~L^{-1}}` + - dissolved arsenic (total) + * - NH2CL + - Bulk + - "MG" + - :math:`{\mathsf{NH_2Cl}}` + - :math:`\mathrm{mg~L^{-1}}` + - dissolved monochloramine + * - AS5s + - Wall + - "UG" + - :math:`{\mathsf{As}^\mathrm{V}_{s}}` + - :math:`\require{upgreek}\upmu\mathrm{g}~\mathrm{m}^{-2}` + - adsorped arsenate (surface) + + + .. list-table:: Coefficients [1]_ + :header-rows: 1 + :widths: 2 2 2 3 4 6 + + * - Name + - Type + - Value + - Symbol + - Units + - Note + * - Ka + - Const + - :math:`10` + - :math:`k_a` + - :math:`\mathrm{mg}^{-1}_{\left(\mathsf{NH_2Cl}\right)}~\mathrm{h}^{-1}` + - arsenite oxidation + * - Kb + - Const + - :math:`0.1` + - :math:`k_b` + - :math:`\mathrm{h}^{-1}` + - chloromine decay + * - K1 + - Const + - :math:`5.0` + - :math:`k_1` + - :math:`\require{upgreek}\textrm{L}~\upmu\mathrm{g}^{-1}_{\left(\mathsf{As}^\mathrm{V}\right)}~\mathrm{h}^{-1}` + - arsenate adsorption + * - K2 + - Const + - :math:`1.0` + - :math:`k_2` + - :math:`\textrm{L}~\mathrm{h}^{-1}` + - arsenate desporbtion + * - Smax + - Const + - :math:`50.0` + - :math:`S_{\max}` + - :math:`\require{upgreek}\upmu\mathrm{g}_{\left(\mathsf{As}^\mathrm{V}\right)}~\mathrm{m}^{-2}` + - arsenate adsorption limit + + + .. list-table:: Other terms + :header-rows: 1 + :widths: 3 3 12 3 + + * - Name + - Symbol + - Expression + - Units + * - Ks + - :math:`k_s` + - :math:`{k_1}/{k_2}` + - :math:`\require{upgreek}\upmu\mathrm{g}^{-1}_{\left(\mathsf{As}^\mathrm{V}\right)}` + + + .. list-table:: Pipe reactions [2]_ + :header-rows: 1 + :widths: 3 3 16 + + * - Species + - Type + - Expression + * - AS3 + - Rate + - :math:`-k_a \, {\mathsf{As}^\mathrm{III}} \, {\mathsf{NH_2Cl}}` + * - AS5 + - Rate + - :math:`k_a \, {\mathsf{As}^\mathrm{III}} \, {\mathsf{NH_2Cl}} -Av \left( k_1 \left(S_{\max}-{\mathsf{As}^\mathrm{V}_{s}} \right) {\mathsf{As}^\mathrm{V}} - k_2 \, {\mathsf{As}^\mathrm{V}_{s}} \right)` + * - NH2CL + - Rate + - :math:`-k_b \, {\mathsf{NH_2Cl}}` + * - AStot + - Formula + - :math:`{\mathsf{As}^\mathrm{III}} + {\mathsf{As}^\mathrm{V}}` + * - AS5s + - Equil + - :math:`k_s \, S_{\max} \frac{{\mathsf{As}^\mathrm{V}}}{1 + k_s \, {\mathsf{As}^\mathrm{V}}} - {\mathsf{As}^\mathrm{V}_{s}}` + + + .. list-table:: Tank reactions + :header-rows: 1 + :widths: 3 3 16 + + * - Species + - Type + - Expression + * - AS3 + - Rate + - :math:`-k_a \, {\mathsf{As}^\mathrm{III}} \, {\mathsf{NH_2Cl}}` + * - AS5 + - Rate + - :math:`k_a \, {\mathsf{As}^\mathrm{III}} \, {\mathsf{NH_2Cl}}` + * - NH2CL + - Rate + - :math:`-k_b \, {\mathsf{NH_2Cl}}` + * - AStot + - Formula + - :math:`{\mathsf{As}^\mathrm{III}} + {\mathsf{As}^\mathrm{V}}` + * - AS5s + - Equil + - :math:`0` (`not present in tanks`) + + References + ---------- + This model is described in the EPANET-MSX user manual [SRU23]_ and was simplified from [GSCL94]_. + + .. [GSCL94] + B. Gu, J. Schmitt, Z. Chen, L. Liang, and J.F. McCarthy. "Adsorption and desorption of + natural organic matter on iron oxide: mechanisms and models". Environ. Sci. Technol., 28:38-46, January 1994. + + Notes + ----- + + .. [1] + The volume unit, :math:`\textrm{L}`, is defined by the network model flow units. + .. [2] + The :math:`Av` variable is the surface area per unit volume for the network (by pipe). + In this model, it has units of :math:`\mathrm{m}^{2} / \mathrm{L}` + """ + msx = MultispeciesQualityModel() + msx.title = "Arsenic Oxidation/Adsorption Example" + msx.add_species(name="AS3", species_type="BULK", units="UG", note="Dissolved arsenite") + msx.add_species(name="AS5", species_type="BULK", units="UG", note="Dissolved arsenate") + msx.add_species(name="AStot", species_type="BULK", units="UG", note="Total dissolved arsenic") + msx.add_species(name="AS5s", species_type="WALL", units="UG", note="Adsorbed arsenate") + msx.add_species(name="NH2CL", species_type="BULK", units="MG", note="Monochloramine") + msx.add_constant("Ka", 10.0, units="1 / (MG * HR)", note="Arsenite oxidation rate coefficient") + msx.add_constant("Kb", 0.1, units="1 / HR", note="Monochloramine decay rate coefficient") + msx.add_constant("K1", 5.0, units="M^3 / (UG * HR)", note="Arsenate adsorption coefficient") + msx.add_constant("K2", 1.0, units="1 / HR", note="Arsenate desorption coefficient") + msx.add_constant("Smax", 50.0, units="UG / M^2", note="Arsenate adsorption limit") + msx.add_term(name="Ks", expression="K1/K2", note="Equil. adsorption coeff.") + msx.add_reaction( + species="AS3", location="pipes", dynamics_type="rate", expression="-Ka*AS3*NH2CL", note="Arsenite oxidation" + ) + msx.add_reaction( + "AS5", "pipes", "rate", "Ka*AS3*NH2CL - Av*(K1*(Smax-AS5s)*AS5 - K2*AS5s)", note="Arsenate production less adsorption" + ) + msx.add_reaction( + species="NH2CL", location="pipes", dynamics_type="rate", expression="-Kb*NH2CL", note="Monochloramine decay" + ) + msx.add_reaction("AS5s", "pipe", "equil", "Ks*Smax*AS5/(1+Ks*AS5) - AS5s", note="Arsenate adsorption") + msx.add_reaction(species="AStot", location="pipes", dynamics_type="formula", expression="AS3 + AS5", note="Total arsenic") + msx.add_reaction( + species="AS3", location="tank", dynamics_type="rate", expression="-Ka*AS3*NH2CL", note="Arsenite oxidation" + ) + msx.add_reaction( + species="AS5", location="tank", dynamics_type="rate", expression="Ka*AS3*NH2CL", note="Arsenate production" + ) + msx.add_reaction( + species="NH2CL", location="tank", dynamics_type="rate", expression="-Kb*NH2CL", note="Monochloramine decay" + ) + msx.add_reaction(species="AStot", location="tanks", dynamics_type="formula", expression="AS3 + AS5", note="Total arsenic") + msx.options.area_units = "M2" + msx.options.rate_units = "HR" + msx.options.rtol = 0.001 + msx.options.atol = 0.0001 + msx.references.append(cite_msx()) + return msx + + +def batch_chloramine_decay(wn=None): + msx = MultispeciesQualityModel() + msx.title = "Batch chloramine decay example" + msx.options.area_units = "ft2" + msx.options.rate_units = "hr" + + msx.add_species("HOCL", "bulk", "mol", note="hypochlorous acid") + msx.add_species("NH3", "bulk", "mol", note="ammonia") + msx.add_species("NH2CL", "bulk", "mol", note="monochloramine") + msx.add_species("NHCL2", "bulk", "mol", note="dichloramine") + msx.add_species("I", "bulk", "mol", note="unknown intermediate") + msx.add_species("OCL", "bulk", "mol", note="hypochlorite ion") + msx.add_species("NH4", "bulk", "mol", note="ammonium ion") + msx.add_species("ALK", "bulk", "mol", note="total alkalinity") + msx.add_species("H", "bulk", "mol", note="hydrogen ion") + msx.add_species("OH", "bulk", "mol", note="hydroxide ion") + msx.add_species("CO3", "bulk", "mol", note="carbonate ion") + msx.add_species("HCO3", "bulk", "mol", note="bicarbonate ion") + msx.add_species("H2CO3", "bulk", "mol", note="dissolved carbon dioxide") + msx.add_species("chloramine", "bulk", "mmol", note="monochloramine in mmol/L") + + msx.add_parameter("k1", 1.5e10) + msx.add_parameter("k2", 7.6e-2) + msx.add_parameter("k3", 1.0e6) + msx.add_parameter("k4", 2.3e-3) + msx.add_parameter("k6", 2.2e8) + msx.add_parameter("k7", 4.0e5) + msx.add_parameter("k8", 1.0e8) + msx.add_parameter("k9", 3.0e7) + msx.add_parameter("k10", 55.0) + + msx.add_term("k5", "(2.5e7*H) + (4.0e4*H2CO3) + (800*HCO3)") + msx.add_term("a1", "k1 * HOCL * NH3") + msx.add_term("a2", "k2 * NH2CL") + msx.add_term("a3", "k3 * HOCL * NH2CL") + msx.add_term("a4", "k4 * NHCL2") + msx.add_term("a5", "k5 * NH2CL * NH2CL") + msx.add_term("a6", "k6 * NHCL2 * NH3 * H") + msx.add_term("a7", "k7 * NHCL2 * OH") + msx.add_term("a8", "k8 * I * NHCL2") + msx.add_term("a9", "k9 * I * NH2CL") + msx.add_term("a10", "k10 * NH2CL * NHCL2") + + msx.add_reaction("HOCL", PIPE, RATE, "-a1 + a2 - a3 + a4 + a8") + msx.add_reaction("NH3", PIPE, RATE, "-a1 + a2 + a5 - a6") + msx.add_reaction("NH2CL", PIPE, RATE, "a1 - a2 - a3 + a4 - a5 + a6 - a9 - a10") + msx.add_reaction("NHCL2", PIPE, RATE, "a3 - a4 + a5 - a6 - a7 - a8 - a10") + msx.add_reaction("I", PIPE, RATE, "a7 - a8 - a9") + msx.add_reaction("H", PIPE, RATE, "0") + msx.add_reaction("ALK", PIPE, RATE, "0") + msx.add_reaction("OCL", PIPE, EQUIL, "H * OCL - 3.16E-8 * HOCL") + msx.add_reaction("NH4", PIPE, EQUIL, "H * NH3 - 5.01e-10 * NH4") + msx.add_reaction("CO3", PIPE, EQUIL, "H * CO3 - 5.01e-11 * HCO3") + msx.add_reaction("H2CO3", PIPE, EQUIL, "H * HCO3 - 5.01e-7 * H2CO3") + msx.add_reaction("HCO3", PIPE, EQUIL, "ALK - HC03 - 2*CO3 - OH + H") + msx.add_reaction("OH", PIPE, EQUIL, "H * OH - 1.0e-14") + msx.add_reaction("chloramine", PIPE, FORMULA, "1000 * NH2CL") + return msx diff --git a/wntr/quality/multispecies.py b/wntr/quality/multispecies.py index d9adccdb6..a29e664e3 100644 --- a/wntr/quality/multispecies.py +++ b/wntr/quality/multispecies.py @@ -1,48 +1,37 @@ # -*- coding: utf-8 -*- -""" -Multispecies water quality model and elements. -This module contains concrete instantiations of the abstract classes described in :class:`wntr.quality.base`. +"""Water quality model implementations. """ -import enum + import logging -import warnings -from collections.abc import MutableMapping -from dataclasses import InitVar, asdict, field -from enum import Enum, IntFlag + from typing import ( Any, - ClassVar, + Callable, Dict, - Generator, - Hashable, Iterator, List, - Literal, - Set, Tuple, Union, ) -import wntr.quality.io + from wntr.epanet.util import ENcomment from wntr.network.elements import Source from wntr.network.model import PatternRegistry, SourceRegistry, WaterNetworkModel +from wntr.quality.base import WaterQualityReaction, WaterQualityVariable from wntr.utils.disjoint_mapping import DisjointMapping, KeyExistsError from .base import ( EXPR_TRANSFORMS, HYDRAULIC_VARIABLES, - RESERVED_NAMES, EXPR_FUNCTIONS, - AbstractQualityModel, DynamicsType, LocationType, - AbstractReaction, - AbstractVariable, QualityVarType, SpeciesType, + AnnotatedFloat, ) from .options import MultispeciesOptions @@ -55,9 +44,7 @@ has_sympy = True except ImportError: sympy = None - logging.critical( - "This python installation does not have SymPy installed. Certain functionality will be disabled." - ) + logging.critical("This python installation does not have SymPy installed. Certain functionality will be disabled.") standard_transformations = (None,) convert_xor = None has_sympy = False @@ -65,1802 +52,1362 @@ logger = logging.getLogger(__name__) - -class Species(AbstractVariable): - """A species in a multispecies water quality model. - - .. rubric:: Constructor - - The preferred way to create a new species is to use one of the following - functions from the :class:`MultispeciesQualityModel`: - :meth:`~MultispeciesQualityModel.add_bulk_species()`, - :meth:`~MultispeciesQualityModel.add_wall_species()`, - :meth:`~MultispeciesQualityModel.add_species()`, or - :meth:`~MultispeciesQualityModel.add_variable()`. - """ - - name: str = None - """The name (symbol) for the variable, must be a valid MSX name""" - units: str = None - """The units used for concentration of this species""" - note: Union[str, Dict[str, str]] = None - """A note to go with this species""" - diffusivity: float = None - """A value for diffusivity for this species""" +__all__ = [ + "Species", + "Constant", + "Parameter", + "Term", + "ReservedName", + "HydraulicVariable", + "MathFunction", + "VariableRegistry", + "InitialQuality", + "ParameterValues", + "NetworkSpecificData", + "MultispeciesQualityModel", +] + + +class Species(WaterQualityVariable): + """A biological or chemical species that impacts water quality.""" def __init__( self, - species_type: Union[SpeciesType, str], name: str, + species_type: Union[SpeciesType, str], units: str, atol: float = None, rtol: float = None, - note: Union[str, Dict[str, str]] = None, - diffusivity: float = None, *, - _qm: AbstractQualityModel = None, - ): - """ - Parameters - ---------- - species_type: SpeciesType | str - The type of species, either BULK or WALL + note=None, + diffusivity: float = None, + pipe_reaction: "WaterQualityReaction" = None, + tank_reaction: "WaterQualityReaction" = None, + _vars=None, + _vals=None, + ) -> None: + """A biological or chemical species. + + Arguments + --------- name : str - The name (symbol) for the variable, must be a valid MSX name + The species name + species_type : SpeciesType | str + The species type units : str - The units used for this species + The units of mass for this species, see :attr:`units` property. atol : float, optional - The absolute tolerance to use when solving for this species, by default None + The absolute tolerance when solving this species' equations, by default None [1]_ rtol : float, optional - The relative tolerance to use when solving for this species, by default None - note : str or dict, optional - A note about this species, by default None + The relative tolerance when solving this species' equations, by default None [1]_ + + + Keyword Arguments + ----------------- + note : str | dict | ENcomment, optional + Supplementary information regarding this variable, by default None (see :class:`~wntr.epanet.util.ENcomment` for dict structure) diffusivity : float, optional - The diffusivity value for this species, by default None + Diffusivity of the species in water, by default None + pipe_reaction : dict | MultispeciesReaction, optional + Reaction dynamics of the species in pipes, by default None + tank_reaction : dict | MultispeciesReaction, optional + Reaction dynamics of the species in tanks, by default None + + + Raises + ------ + TypeError + if mandatory arguments are passed as None + TypeError + if a tank reaction is provided for a wall species + TypeError + if an invalid type is passed for a pipe or tank reaction + + + .. [1] + The `atol` and `rtol` arguments must both be None, or both be a float greater than 0. + + + .. rubric:: Developer-use Arguments + + The following function call parameters should only be used by a MultispeciesModel class + or model-building function; the user should not need to pass these arguments. Other Parameters ---------------- - _qm : MultispeciesQualityModel - the model to link with, populated automatically if the :class:`MultispeciesQualityModel` API is used, by default None + _vars : VariablesRegistry, optional + the variables registry object of the model this variable was added to, by default None + _vals : _type_, optional + _description_, by default None """ - if name in RESERVED_NAMES: - raise ValueError("Name cannot be a reserved name") - self._species_type = SpeciesType.get(species_type) - if self._species_type is None: + super().__init__(name, note=note, _vars=_vars) + species_type = SpeciesType.get(species_type) + if species_type is None: raise TypeError("species_type cannot be None") - self.name: str = name - """The name of the variable""" + self._species_type = species_type + self._tolerances = None + self.set_tolerances(atol, rtol) self.units: str = units - """The units used for this species""" - self.note = note - """A note about this species, by default None""" + """The units of mass for this species. + For bulk species, concentration is this unit divided by liters, for wall species, concentration is this unit + divided by the model's area-unit (see options). + """ self.diffusivity: float = diffusivity - """The diffusivity value for this species, by default None""" - if atol is not None: - atol = float(atol) - if rtol is not None: - rtol = float(rtol) - if (atol is None) ^ (rtol is None): - raise TypeError( - "atol and rtol must be the same type, got {} and {}".format(atol, rtol) - ) - self._atol = atol - self._rtol = rtol - self._variable_registry = _qm - - def __repr__(self): - return "{}(name={}, unit={}, atol={}, rtol={}, note={})".format( - self.__class__.__name__, - repr(self.name), - repr(self.units), - self._atol, - self._rtol, - repr( - self.note if not isinstance(self.note, ENcomment) else asdict(self.note) - ), - ) + """The diffusivity of this species in water, if being used, by default None""" + if species_type is SpeciesType.WALL and tank_reaction: + raise TypeError("Wall species tank_reaction must be None") + self.pipe_reaction: WaterQualityReaction = None + """The object that describes how this species reacts in pipes""" + self.tank_reaction: WaterQualityReaction = None + """The object that describes how this species reacts in tanks""" + if isinstance(pipe_reaction, WaterQualityReaction): + pipe_reaction.species = self + self.pipe_reaction = pipe_reaction + elif isinstance(pipe_reaction, dict): + pipe_reaction["location"] = "pipe" + pipe_reaction["species"] = self + self.pipe_reaction = self.add_reaction(**pipe_reaction) + elif pipe_reaction is None: + self.pipe_reaction = None + else: + raise TypeError("The pipe_reaction is invalid") + if isinstance(tank_reaction, WaterQualityReaction): + tank_reaction.species = self + self.tank_reaction = tank_reaction + elif isinstance(tank_reaction, dict): + tank_reaction["location"] = "tank" + tank_reaction["species"] = self + self.tank_reaction = self.add_reaction(**tank_reaction) + elif tank_reaction is None: + self.tank_reaction = None + else: + raise TypeError("The tank_reaction is invalid") + if _vals is not None and isinstance(_vals, InitialQuality): + self._vals = _vals + else: + self._vals = None - def __eq__(self, other): - return ( - isinstance(other, self.__class__) - and self.name == other.name - and self.units == other.units - and self.diffusivity == other.diffusivity - and self._atol == other._atol - and self._rtol == other._rtol - ) + def set_tolerances(self, atol: float, rtol: float): + """Set the absolute and relative tolerance for the solvers. + + The user must set both values, or neither value (None). Values must be + positive. + + Arguments + --------- + atol : float + The absolute tolerance to use + rtol : float + The relative tolerance to use + + Raises + ------ + TypeError + if only one of `atol` or `rtol` is a float + ValueError + if either value is less-than-or-equal-to zero + """ + if (self.atol is None) ^ (self.rtol is None): + raise TypeError("atol and rtol must both be float or both be None") + if self.atol is None: + self._tolerances = None + elif atol <= 0 or rtol <= 0: + raise ValueError("atol and rtol must both be positive, got atol={}, rtol={}".format(atol, rtol)) + else: + self._tolerances = (atol, rtol) + + def get_tolerances(self) -> Union[Tuple[float, float], None]: + """Get the custom solver tolerances for this species. + + Returns + ------- + (float, float) or None + absolute and relative tolerances, respectively, if they are set, otherwise returns None + """ + return self._tolerances + + def clear_tolerances(self): + """Set both tolerances to None, reverting to the global options value.""" + self._tolerances = None @property - def var_type(self): + def atol(self) -> float: + """The absolute tolerance. Must be set using :meth:`set_tolerances`""" + if self._tolerances is not None: + return self._tolerances[0] + return None + + @property + def rtol(self) -> float: + """The relative tolerance. Must be set using :meth:`set_tolerances`""" + if self._tolerances is not None: + return self._tolerances[1] + return None + + @property + def var_type(self) -> QualityVarType: + """This is a species""" return QualityVarType.SPECIES @property def species_type(self) -> SpeciesType: - """Type type of species (bulk or wall)""" + """The type of species""" return self._species_type @property - def is_bulk(self) -> bool: - """Is this a bulk species?""" - return self._species_type is SpeciesType.BULK + def initial_quality(self) -> "NetworkSpecificData": + """If a specific network has been linked, then the initial quality values for the network""" + if self._vals is not None: + return self._vals + else: + raise TypeError("This species is not linked to a NetworkSpecificValues obejct, please `relink` your model") - @property - def is_wall(self) -> bool: - """Is this a wall species?""" - return self._species_type is SpeciesType.WALL + def add_reaction( + self, location: LocationType, dynamics_type: DynamicsType, expression: str, *, note: Any = None + ) -> "WaterQualityReaction": + """Add a reaction object to the species. + + Arguments + --------- + location : LocationType + where the reaction takes place, either PIPE or TANK + dynamics_type : DynamicsType + the type of dynamics described by the expression + expression : str + the reaction dynamics expression - def get_tolerances(self) -> Tuple[float, float]: - """Get the species-specific solver tolerances. + Keyword Arguments + ----------------- + note : str | dict | ENcomment, optional + Supplementary information regarding the reaction, by default None (see :class:`~wntr.epanet.util.ENcomment` for dict structure). Returns ------- - two-tuple or None - the absolute and relative tolerances, or None if the global values should be used + MultispeciesReaction + the new reaction object """ - if self._atol is not None and self._rtol is not None: - return (self._atol, self._rtol) - return None - - def set_tolerances(self, absolute: float, relative: float): - """Set the species-specific solver tolerances. Using ``None`` for both will - clear the tolerances, though using :func:`clear_tolerances` is clearer code. + location = LocationType.get(location, allow_none=False) + dynamics_type = DynamicsType.get(dynamics_type, allow_none=False) + new = WaterQualityReaction( + species=self, + dynamics_type=dynamics_type, + expression=expression, + note=note, + ) + if location is LocationType.PIPE: + self.pipe_reaction = new + else: + self.tank_reaction = new + return new - Parameters - ---------- - absolute : float - the absolute solver tolerance - relative : float - the relative solver tolerance + def to_dict(self) -> Dict[str, Any]: + """Create a dictionary representation of the object + + The species dictionary has the following format, as described using a json schema. + + .. code:: json + + { + "title": "Species", + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "species_type": { + "enum": ["bulk", "wall"] + }, + "units": { + "type": "string" + }, + "atol": { + "type": "number", + "exclusiveMinimum": 0 + }, + "rtol": { + "type": "number", + "exclusiveMinimum": 0 + }, + "note": { + "type": "string" + }, + "diffusivity": { + "type": "number", + "minimum": 0 + }, + "pipe_reaction": { + "type": "object", + "properties": { + "dynamics_type": { + "enum": ["rate", "equil", "formula"] + }, + "expression": { + "type": "string" + } + } + }, + "tank_reaction": { + "type": "object", + "properties": { + "dynamics_type": { + "enum": ["rate", "equil", "formula"] + }, + "expression": { + "type": "string" + } + } + } + }, + "required": ["name", "species_type", "units", "pipe_reaction", "tank_reaction"], + "dependentRequired": {"atol": ["rtol"], "rtol":["atol"]} + } - Raises - ------ - TypeError - if both absolute and relative are not the same type - ValueError - if either value is less-than-or-equal-to zero """ - if absolute is None and relative is None: - self._atol = self._rtol = None - return - try: - if not isinstance(absolute, float): - absolute = float(absolute) - if not isinstance(relative, float): - relative = float(relative) - except Exception as e: - raise TypeError( - "absolute and relative must be the same type, got {} and {}".format( - absolute, relative - ) - ) - if absolute <= 0: - raise ValueError("Absolute tolerance must be greater than 0") - if relative <= 0: - raise ValueError("Relative tolerance must be greater than 0") - self._atol = absolute - self._rtol = relative - - def clear_tolerances(self): - """Resets both tolerances to ``None`` to use the global values.""" - self._atol = self._rtol = None - - def to_dict(self): - rep = dict( - name=self.name, - species_type=self.species_type.name.lower(), - units=self.units, + ret = dict( + name=self.name, species_type=self.species_type.name.lower(), units=self.units, atol=self.atol, rtol=self.rtol ) - tols = self.get_tolerances() - if tols is not None: - rep["atol"] = tols[0] - rep["rtol"] = tols[1] - if self.diffusivity: - rep["diffusivity"] = self.diffusivity - if isinstance(self.note, str): - rep["note"] = self.note - elif isinstance(self.note, ENcomment): - rep["note"] = asdict(self.note) if self.note.pre else self.note.post - else: - rep["note"] = None - return rep + if self.diffusivity: + ret["diffusivity"] = self.diffusivity + + if isinstance(self.note, ENcomment): + ret["note"] = self.note.to_dict() + elif isinstance(self.note, (str, dict, list)): + ret["note"] = self.note + + if self.pipe_reaction is not None: + pr = self.pipe_reaction.to_dict() + if "species" in pr: + del pr["species"] + ret["pipe_reaction"] = pr + if self.tank_reaction is not None: + tr = self.tank_reaction.to_dict() + if "species" in tr: + del tr["species"] + ret["tank_reaction"] = tr + return ret + + +class Constant(WaterQualityVariable): + """A constant coefficient for use in reaction expressions.""" + + def __init__(self, name: str, value: float, *, units: str = None, note=None, _vars=None) -> None: + """A variable representing a constant value. + + Arguments + --------- + name : str + The name of the variable. + value : float + The constant value. -class Constant(AbstractVariable): - """A constant coefficient that is used in reaction expressions. - - .. rubric:: Constructor + Keyword Aguments + ---------------- + units : str, optional + Units for the variable, by default None + note : str | dict | ENcomment, optional + Supplementary information regarding this variable, by default None (see :class:`~wntr.epanet.util.ENcomment` for dict structure). - The preferred way to create a new coefficient is to use one of the following - functions from the :class:`MultispeciesQualityModel`: - :meth:`~MultispeciesQualityModel.add_constant()`, - :meth:`~MultispeciesQualityModel.add_parameter()`, - :meth:`~MultispeciesQualityModel.add_coefficient()`, or - :meth:`~MultispeciesQualityModel.add_variable()`. - """ - name: str = None - """The name (symbol) for the variable, must be a valid MSX name""" - units: str = None - """The units used for this variable""" - note: Union[str, Dict[str, str]] = None - """A note to go with this varibale""" - global_value: float = None - """The global value for the coefficient""" + .. rubric:: Developer-use Arguments - def __init__( - self, - name: str, - global_value: float, - note: Union[str, Dict[str, str]] = None, - units: str = None, - *, - _qm: AbstractQualityModel = None, - ): - """ - Parameters - ---------- - name : str - the name/symbol of the coefficient - global_value : float - the global value for the coefficient - note : Union[str, Dict[str, str]], optional - a note for this variable, by default None - units : str, optional - units for this coefficient, by default None + The following function call parameters should only be used by a MultispeciesModel class + or model-building function; the user should not need to pass these arguments. Other Parameters ---------------- - _qm : MultispeciesQualityModel - the model to link with, populated automatically if the :class:`MultispeciesQualityModel` API is used, by default None + _vars : VariablesRegistry, optional + the variables registry object of the model this variable was added to, by default None """ - if name in RESERVED_NAMES: - raise ValueError("Name cannot be a reserved name") - self.name = name - """The name of the variable""" - self.global_value = float(global_value) - """The global value for the coefficient""" - self.note = note - """A note about this species, by default None""" + super().__init__(name, note=note, _vars=_vars) + self.value = float(value) + """The value of the constant""" self.units = units - """The units used for this species""" - self._variable_registry = _qm - - def __repr__(self): - return "{}(name={}, global_value={}, units={}, note={})".format( - self.__class__.__name__, - repr(self.name), - repr(self.global_value), - repr(self.units), - repr( - self.note if not isinstance(self.note, ENcomment) else asdict(self.note) - ), - ) - - def __eq__(self, other): - return ( - isinstance(other, self.__class__) - and self.name == other.name - and self.global_value == other.global_value - and self.units == other.units - ) - - def get_value(self) -> float: - """Get the value of the coefficient - - Returns - ------- - float - the global value - """ - return self.global_value - - def to_dict(self): - rep = dict(name=self.name, global_value=self.global_value, units=self.units) - if isinstance(self.note, str): - rep["note"] = self.note - elif isinstance(self.note, ENcomment): - rep["note"] = asdict(self.note) if self.note.pre else self.note.post - else: - rep["note"] = None - return rep + """The units of the constant""" @property - def var_type(self): - return QualityVarType.CONST + def var_type(self) -> QualityVarType: + """This is a constant coefficient.""" + return QualityVarType.CONSTANT + def to_dict(self) -> Dict[str, Any]: + ret = dict(name=self.name, value=self.value) + if self.units: + ret["units"] = self.units + if isinstance(self.note, ENcomment): + ret["note"] = self.note.to_dict() + elif isinstance(self.note, (str, dict, list)): + ret["note"] = self.note + return ret -class Parameter(AbstractVariable): - """A variable parameter for reaction expressions. + def __call__(self, *, t=None) -> Any: + return self.value - .. rubric:: Constructor - The preferred way to create a new parameterized coefficient is to use one of the following - functions from the :class:`MultispeciesQualityModel`: - :meth:`~MultispeciesQualityModel.add_parameter()`, - :meth:`~MultispeciesQualityModel.add_coefficient()`, or - :meth:`~MultispeciesQualityModel.add_variable()`. - """ +class Parameter(WaterQualityVariable): + """A coefficient that is parameterized by pipe/tank.""" - name: str = None - """The name (symbol) for the variable, must be a valid MSX name""" - units: str = None - """The units used for this variable""" - global_value: float = None - """The global value for the coefficient""" - note: Union[str, Dict[str, str]] = None - """A note to go with this varibale""" + def __init__(self, name: str, global_value: float, *, units: str = None, note=None, _vars=None, _vals=None) -> None: + """A parameterized variable for use in expressions. - def __init__( - self, - name: str, - global_value: float, - note: Union[str, Dict[str, str]] = None, - units: str = None, - pipe_values: Dict[str, float] = None, - tank_values: Dict[str, float] = None, - *, - _qm: AbstractQualityModel = None, - ): - """ - Parameters - ---------- + Arguments + --------- name : str - the name/symbol of the coefficient + The name of this parameter. global_value : float - the global value for the coefficient - note : Union[str, Dict[str, str]], optional - a note for this variable, by default None + The global value for the parameter if otherwise unspecified. + + Keyword Arguments + ----------------- units : str, optional - units for this coefficient, by default None - pipe_values : dict, optional - the values of the parameter at specific pipes, by default None - tank_values : dict, optional - the values of the parameter at specific tanks, by default None + The units for this parameter, by default None + note : str | dict | ENcomment, optional + Supplementary information regarding this variable, by default None (see :class:`~wntr.epanet.util.ENcomment` for dict structure). + + + .. rubric:: Developer-use Arguments + + The following function call parameters should only be used by a MultispeciesModel class + or model-building function; the user should not need to pass these arguments. Other Parameters ---------------- - _qm : MultispeciesQualityModel - the model to link with, populated automatically if the :class:`MultispeciesQualityModel` API is used, by default None + _vars : VariablesRegistry, optional + the variables registry object of the model this variable was added to, by default None + _vals : ParameterValues, optional + Values for specific tanks or pipes, by default None. This argument should + be passed by the MultispeciesModel during variable creation. """ - if name in RESERVED_NAMES: - raise ValueError("Name cannot be a reserved name") - self.name = name - """The name of the variable""" + super().__init__(name, note=note, _vars=_vars) self.global_value = float(global_value) - """The global value for the coefficient""" - self.note = note - """A note about this species, by default None""" self.units = units - """The units used for this species""" - self._variable_registry = _qm - self._pipe_values = pipe_values if pipe_values is not None else dict() - """A dictionary of parameter values for various pipes""" - self._tank_values = tank_values if tank_values is not None else dict() - """A dictionary of parameter values for various tanks""" - - def __eq__(self, other): - basic = ( - isinstance(other, self.__class__) - and self.name == other.name - and self.global_value == other.global_value - and self.units == other.units - ) - if not basic: - return False - for k, v in self._pipe_values: - if other._pipe_values[k] != v: - return False - for k, v in self._tank_values: - if other._tank_values[k] != v: - return False - return True - - def __repr__(self): - return "{}(name={}, global_value={}, units={}, note={})".format( - self.__class__.__name__, - repr(self.name), - repr(self.global_value), - repr(self.units), - repr( - self.note if not isinstance(self.note, ENcomment) else asdict(self.note) - ), - ) + self._vals = _vals @property - def var_type(self): - return QualityVarType.PARAM - - def get_value(self, pipe: str = None, tank: str = None) -> float: - """Get the value of the parameter, either globally or for a specific pipe or tank. - - Parameters - ---------- - pipe : str, optional - a pipe to get the value for, by default None - tank : str, optional - a tank to get the value for, by default None - - Returns - ------- - float - either a specific parameter value for the specified pipe or tank, or the global value - if nothing is specified OR if the pipe or tank requested does not have a special value. - - Raises - ------ - TypeError - if both pipe and tank are specified - """ + def var_type(self) -> QualityVarType: + """This is a parameterized coefficient.""" + return QualityVarType.PARAMETER + + def to_dict(self) -> Dict[str, Any]: + ret = dict(name=self.name, global_value=self.global_value) + if self.units: + ret["units"] = self.units + if isinstance(self.note, ENcomment): + ret["note"] = self.note.to_dict() + elif isinstance(self.note, (str, dict, list)): + ret["note"] = self.note + return ret + + def __call__(self, *, t=None, pipe: float = None, tank: float = None) -> Any: if pipe is not None and tank is not None: - raise TypeError( - "Cannot get a value for a pipe and tank at the same time - one or both must be None" - ) - if pipe is not None: - return self._pipe_values.get(pipe, self.global_value) - if tank is not None: - return self._tank_values.get(tank, self.global_value) + raise TypeError("Both pipe and tank cannot be specified at the same time") + elif self._vals is None and (pipe is not None or tank is not None): + raise ValueError("No link provided to network-specific parameter values") + if pipe: + return self._vals.pipe_values.get(pipe, self.global_value) + elif tank: + return self._vals.tank_values.get(pipe, self.global_value) return self.global_value - @property - def pipe_values(self) -> Dict[str, float]: - """A dictionary of values, iff different from the global value, for specific pipes""" - return self._pipe_values + def link_values(self, values: "ParameterValues"): + """Link the paraemterized values to a model object. - @property - def tank_values(self) -> Dict[str, float]: - """A dictionary of values, iff different from the global value, for specific tanks""" - return self._tank_values + Note, this should not be necessary if the user uses the MultispeciesModel + add_parameter function. - def to_dict(self): - rep = dict(name=self.name, global_value=self.global_value, units=self.units) - if isinstance(self.note, str): - rep["note"] = self.note - elif isinstance(self.note, ENcomment): - rep["note"] = asdict(self.note) if self.note.pre else self.note.post - else: - rep["note"] = None - rep["pipe_values"] = self._pipe_values.copy() - rep["tank_values"] = self._tank_values.copy() - return rep + Arguments + --------- + values : ParameterValues + The parameter values object. + """ + self._vals = values -class OtherTerm(AbstractVariable): - """An expression term defined as a function of species, coefficients, or other terms. +class Term(WaterQualityVariable): + def __init__(self, name: str, expression: str, *, note=None, _vars=None) -> None: + """A named expression that can be used as a term in other expressions. - .. rubric:: Constructor + Arguments + --------- + name : str + The variable name. + expression : str + The mathematical expression to be aliased - The preferred way to create a new functional term is to use one of the following - functions from the :class:`MultispeciesQualityModel`: - :meth:`~MultispeciesQualityModel.add_other_term()` or - :meth:`~MultispeciesQualityModel.add_variable()`. - """ + Keyword Arguments + ----------------- + note : str | dict | ENcomment, optional + Supplementary information regarding this variable, by default None (see :class:`~wntr.epanet.util.ENcomment` for dict structure). - name: str = None - """The name (symbol) for the variable, must be a valid MSX name""" - expression: str = None - """The mathematical expression this term represents""" - note: Union[str, Dict[str, str]] = None - """A note to go with this term""" - def __init__( - self, - name: str, - expression: str, - note: Union[str, Dict[str, str]] = None, - *, - _qm: AbstractQualityModel = None, - ): - """ - Parameters - ---------- - name : str - the name/symbol of the function (term) - expression : str - the mathematical expression described by this function - note : str, optional - a note for this function, by default None + .. rubric:: Developer-use Arguments + + The following function call parameters should only be used by a MultispeciesModel class + or model-building function; the user should not need to pass these arguments. Other Parameters ---------------- - _qm : MultispeciesQualityModel - the model to link with, populated automatically if the :class:`MultispeciesQualityModel` API is used, by default None + _vars : VariablesRegistry, optional + the variables registry object of the model this variable was added to, by default None """ - if name in RESERVED_NAMES: - raise ValueError("Name cannot be a reserved name") - self.name = name - """The name of the variable""" + super().__init__(name, note=note, _vars=_vars) self.expression = expression - """The expression this named-function is equivalent to""" - self.note = note - """A note about this function/term""" - self._variable_registry = _qm - - def __repr__(self): - return "{}(name={}, expression={}, note={})".format( - self.__class__.__name__, - repr(self.name), - repr(self.expression), - repr( - self.note if not isinstance(self.note, ENcomment) else asdict(self.note) - ), - ) - - def __eq__(self, other): - return ( - isinstance(other, self.__class__) - and self.name == other.name - and self.expression == other.expression - ) + """The expression that is aliased by this term""" @property - def var_type(self): + def var_type(self) -> QualityVarType: + """This is a term (named expression).""" return QualityVarType.TERM - def to_symbolic(self): - return super().to_symbolic() + def to_dict(self) -> Dict[str, Any]: + ret = dict(name=self.name, expression=self.expression) + if isinstance(self.note, ENcomment): + ret["note"] = self.note.to_dict() + elif isinstance(self.note, (str, dict, list)): + ret["note"] = self.note + return ret - def to_dict(self): - rep = dict(name=self.name, expression=self.expression) - if isinstance(self.note, str): - rep["note"] = self.note - elif isinstance(self.note, ENcomment): - rep["note"] = asdict(self.note) if self.note.pre else self.note.post - else: - rep["note"] = None - return rep +class ReservedName(WaterQualityVariable): + def __init__(self, name: str, *, note=None, _vars: dict = None) -> None: + """An object representing a reserved name that should not be used by the user. -class InternalVariable(AbstractVariable): - """A hydraulic variable or a placeholder for a built-in reserved word. + Arguments + --------- + name : str + The reserved name. - For example, "Len" is the EPANET-MSX name for the length of a pipe, and "I" is a sympy - reserved symbol for the imaginary number. + Keyword Arguments + ----------------- + note : str | dict | ENcomment, optional + Supplementary information regarding this variable, by default None (see :class:`~wntr.epanet.util.ENcomment` for dict structure). - .. rubric:: Constructor - Objects of this type are instantiated when creating a new :class:`MultispeciesQualityModel`, - and should not need to be created by hand. - """ + .. rubric:: Developer-use Arguments - name: str = None - """The name (symbol) for the variable, must be a valid MSX name""" - units: str = None - """The units used for this variable""" - note: Union[str, Dict[str, str]] = None - """A note to go with this variable""" + The following function call parameters should only be used by a MultispeciesModel class + or model-building function; the user should not need to pass these arguments. - def __init__( - self, - name: str, - note: Union[str, Dict[str, str]] = "internal variable - not output to MSX", - units: str = None, - ): - """ - Parameters - ---------- - name : str - The name and symbol for the new variable - note : str or dict, optional - A note to go on the object, by default "internal variable - not output to MSX" - units : str, optional - Units used by values stored in this variable, by default None + Other Parameters + ---------------- + _vars : VariablesRegistry, optional + the variables registry object of the model this variable was added to, by default None + + Raises + ------ + KeyExistsError + _description_ """ + if _vars is not None and name in _vars.keys(): + raise KeyExistsError("This variable name is already taken") self.name = name - """The name of the variable""" self.note = note - """A note about this function/term""" - self.units = units - """The units used for this species""" - - def __repr__(self): - return "{}(name={}, units={}, note={})".format( - self.__class__.__name__, - repr(self.name), - repr(self.units), - repr( - self.note if not isinstance(self.note, ENcomment) else asdict(self.note) - ), - ) - - def __eq__(self, other): - return isinstance(other, self.__class__) and self.name == other.name + self._vars = _vars @property - def var_type(self): + def var_type(self) -> QualityVarType: + """Variable name is a reserved word in MSX""" return QualityVarType.RESERVED + def to_dict(self) -> Dict[str, Any]: + raise NotImplementedError("You cannot convert a reserved word to a dictionary representation") -class RateDynamics(AbstractReaction): - r"""A rate-of-change reaction dynamics expression. - - Used to supply the equation that expresses the rate of change of the given species - with respect to time as a function of the other species in the model. - .. math:: +class HydraulicVariable(ReservedName): + def __init__(self, name: str, units: str = None, *, note=None) -> None: + """A variable representing instantaneous hydraulics data. - \frac{d}{dt} C(species) = expression + The user should not need to create any variables using this class, they + are created automatically by the MultispeciesModel object during initialization. - .. rubric:: Constructor + Arguments + --------- + name : str + The name of the variable (predefined by MSX) + units : str, optional + The units for hydraulic variable, by default None - The preferred way to create a new rate reaction expression is to use one of the following - functions from the :class:`MultispeciesQualityModel`: - :meth:`~MultispeciesQualityModel.add_pipe_reaction()`, - :meth:`~MultispeciesQualityModel.add_tank_reaction()`, or - :meth:`~MultispeciesQualityModel.add_reaction()`. - """ - def __init__( - self, - species: str, - dynamics: DynamicsType, - expression: str, - note: Union[str, Dict[str, str]] = None, - *, - _qm: AbstractQualityModel = None, - ): + Keyword Arguments + ----------------- + note : str | dict | ENcomment, optional + Supplementary information regarding this variable, by default None (see :class:`~wntr.epanet.util.ENcomment` for dict structure). """ - Parameters - ---------- - species : str - the name of the species whose reaction dynamics is being described - dynamics : DynamicsType | str | int - the type of dynamics that the expression describes - expression : str - the expression for the reaction dynamics, which should equal to zero - note : str, optional - a note about this reaction + super().__init__(name, note=note) + self.units = units + """The hydraulic variable's units""" - Other Parameters - ---------------- - _qm : MultispeciesQualityModel - the model to link with, populated automatically if the :class:`MultispeciesQualityModel` API is used, by default None - """ - self.species = species - """Name of the species being described""" - self.dynamics = DynamicsType.get(dynamics) - """Type of reaction dynamics described by the expression""" - self.expression = expression - """The expression""" - self.note = note - """A note or comment about this species reaction dynamics""" - self._variable_registry = _qm - - def __eq__(self, other): - return ( - isinstance(other, self.__class__) - and self.species == other.species - and self.dynamics == other.dynamics - and self.expression == other.expression - ) - @property - def dynamics(self) -> DynamicsType: - return DynamicsType.RATE +class MathFunction(ReservedName): + def __init__(self, name: str, func: Callable, *, note=None) -> None: + """A variable that is actually a mathematical function defined by MSX. - def to_symbolic(self): - return super().to_symbolic() + Arguments + --------- + name : str + The function name + func : Callable + The callable function - def to_dict(self) -> dict: - rep = dict( - species=self.species, - dynamics=self.dynamics.name.lower(), - expression=self.expression, - ) - if isinstance(self.note, str): - rep["note"] = self.note - elif isinstance(self.note, ENcomment): - rep["note"] = asdict(self.note) if self.note.pre else self.note.post - else: - rep["note"] = None - return rep + Keyword Arguments + ----------------- + note : str | dict | ENcomment, optional + Supplementary information regarding this variable, by default None (see :class:`~wntr.epanet.util.ENcomment` for dict structure). + """ + super().__init__(name, note=note) + self.func = func + """A callable function or SymPy function""" -class EquilibriumDynamics(AbstractReaction): - """An equilibrium reaction expression. + def __call__(self, *args: Any, **kwds: Any) -> Any: + return self.func(*args, **kwds) - Used for equilibrium expressions where it is assumed that the expression supplied is being equated to zero. - .. math:: +class Reaction(WaterQualityReaction): + def __init__(self, species: Species, dynamics_type: DynamicsType, expression: str, *, note=None) -> None: + """A water quality biochemical reaction dynamics definition for a specific species. - 0 = expression + This object must be attached to a species in the appropriate pipe or tank reaction attribute. - .. rubric:: Constructor + Arguments + --------- + species : Species | str + The species (object or name) this reaction is applicable to. + dynamics_type : DynamicsType + The type of reaction dynamics being described by the expression: one of RATE, FORMULA, or EQUIL. + expression : str + The mathematical expression for the right-hand-side of the reaction equation. - The preferred way to create a new rate reaction expression is to use one of the following - functions from the :class:`MultispeciesQualityModel`: - :meth:`~MultispeciesQualityModel.add_pipe_reaction()`, - :meth:`~MultispeciesQualityModel.add_tank_reaction()`, or - :meth:`~MultispeciesQualityModel.add_reaction()`. - """ - def __init__( - self, - species: str, - location: LocationType, - expression: str, - note: Union[str, Dict[str, str]] = None, - *, - _qm: AbstractQualityModel = None, - ): - """ - Parameters - ---------- - species : str - the name of the species whose reaction dynamics is being described - location : RxnLocationType or str - the location the reaction occurs (pipes or tanks) - expression : str - the expression for the reaction dynamics, which should equal to zero - note : str, optional - a note about this reaction + Keyword Arguments + ----------------- + note : str | dict | ENcomment, optional + Supplementary information regarding this reaction, by default None (see :class:`~wntr.epanet.util.ENcomment` for dict structure). - Other Parameters - ---------------- - _qm : MultispeciesQualityModel - the model to link with, populated automatically if the :class:`MultispeciesQualityModel` API is used, by default None + + Raises + ------ + TypeError + _description_ + TypeError + _description_ + TypeError + _description_ """ - self.species = species - """Name of the species being described""" - self.location = location - """Location this reaction occurs""" + super().__init__(dynamics_type, note=note) + if species is None: + raise TypeError("species cannot be None") + if not expression: + raise TypeError("expression cannot be None") + self._species = species self.expression = expression - """The expression""" - self.note = note - """A note or comment about this species reaction dynamics""" - self._variable_registry = _qm - - def __eq__(self, other): - return ( - isinstance(other, self.__class__) - and self.name == other.name - and self.location == other.location - and self.expression == other.expression - ) + """The mathematical expression (right-hand-side)""" @property - def dynamics(self) -> DynamicsType: - return DynamicsType.EQUIL + def species(self) -> str: + """The name of the species that reaction dynamics is being described.""" + return str(self._species) - def to_symbolic(self): - return super().to_symbolic() + @property + def dynamics_type(self) -> DynamicsType: + """The type of dynamics being described. + See :class:`DynamicsType` for valid values. + """ + return self._dynamics_type + + def __str__(self) -> str: + """Return a string representation of the reaction""" + return "{}({}) = ".format(self.dynamics_type.name, self.species) + self.expression def to_dict(self) -> dict: - rep = dict( - species=self.species, - dynamics=self.dynamics.name.lower(), - expression=self.expression, - ) - if isinstance(self.note, str): - rep["note"] = self.note - elif isinstance(self.note, ENcomment): - rep["note"] = asdict(self.note) if self.note.pre else self.note.post - else: - rep["note"] = None - return rep + ret = dict(species=str(self.species), dynamics_type=self.dynamics_type.name.lower(), expression=self.expression) + if isinstance(self.note, ENcomment): + ret["note"] = self.note.to_dict() + elif isinstance(self.note, (str, dict, list)): + ret["note"] = self.note + return ret -class FormulaDynamics(AbstractReaction): - """A formula-based reaction dynamics expression. +class VariableRegistry: + """A registry for all the variables registered in the multispecies reactions model. - Used when the concentration of the named species is a simple function of the remaining species. + This object can be used like an immutable mapping, with the ``__len__``, ``__getitem__``, + ``__iter__``, ``__contains__``, ``__eq__`` and ``__ne__`` functions being defined. + """ - .. math:: + def __init__(self) -> None: + self._vars = DisjointMapping() + self._vars.add_disjoint_group("reserved") + self._species = self._vars.add_disjoint_group("species") + self._const = self._vars.add_disjoint_group("constant") + self._param = self._vars.add_disjoint_group("parameter") + self._term = self._vars.add_disjoint_group("term") - C(species) = expression + @property + def all_variables(self) -> Dict[str, WaterQualityVariable]: + """The dictionary view onto all variables""" + return self._vars - .. rubric:: Constructor + @property + def species(self) -> Dict[str, Species]: + """The dictionary view onto only species""" + return self._species - The preferred way to create a new rate reaction expression is to use one of the following - functions from the :class:`MultispeciesQualityModel`: - :meth:`~MultispeciesQualityModel.add_pipe_reaction()`, - :meth:`~MultispeciesQualityModel.add_tank_reaction()`, or - :meth:`~MultispeciesQualityModel.add_reaction()`. - """ + @property + def constants(self) -> Dict[str, Constant]: + """The dictionary view onto only constants""" + return self._const - def __init__( - self, - species: str, - location: LocationType, - expression: str, - note: Union[str, Dict[str, str]] = None, - *, - _qm: AbstractQualityModel = None, - ): - """ - Parameters - ---------- - species : str - the name of the species whose reaction dynamics is being described - location : RxnLocationType or str - the location the reaction occurs (pipes or tanks) - expression : str - the expression for the reaction formula, which is used to calculate the concentration of the species - note : str, optional - a note about this reaction + @property + def parameters(self) -> Dict[str, Parameter]: + """The dictionary view onto only parameters""" + return self._param - Other Parameters - ---------------- - _qm : MultispeciesQualityModel - the model to link with, populated automatically if the :class:`MultispeciesQualityModel` API is used, by default None + @property + def terms(self) -> Dict[str, Term]: + """The dictionary view onto only named terms""" + return self._term + + def add_variable(self, obj: WaterQualityVariable) -> None: + """Add a variable object to the registry. + + The appropriate group is determined by querying the object's + var_type attribute. + + Arguments + --------- + obj : WaterQualityVariable + The variable to add. + + Raises + ------ + TypeError + if obj is not a WaterQualityVariable + KeyExistsError + if obj has a name that is already used in the registry """ - self.species = species - """Name of the species being described""" - self.location = location - """Location this reaction occurs""" - self.expression = expression - """The expression""" - self.note = note - """A note or comment about this species reaction dynamics""" - self._variable_registry = _qm - - def __eq__(self, other): - return ( - isinstance(other, self.__class__) - and self.name == other.name - and self.location == other.location - and self.expression == other.expression + if not isinstance(obj, WaterQualityVariable): + raise TypeError("Expected WaterQualityVariable object") + if obj.name in self: + raise KeyExistsError("Variable name {} already exists in model") + obj._vars = self + self._vars.add_item_to_group(obj.var_type.name.lower(), obj.name, obj) + + def __contains__(self, __key: object) -> bool: + return self._vars.__contains__(__key) + + def __eq__(self, __value: object) -> bool: + return self._vars.__eq__(__value) + + def __ne__(self, __value: object) -> bool: + return self._vars.__ne__(__value) + + # def __delitem__(self, __key: str) -> None: + # return self._vars.__delitem__(__key) + + def __getitem__(self, __key: str) -> WaterQualityVariable: + return self._vars.__getitem__(__key) + + # def __setitem__(self, __key: str, __value: MultispeciesVariable) -> None: + # return self._vars.__setitem__(__key, __value) + + def __iter__(self) -> Iterator: + return self._vars.__iter__() + + def __len__(self) -> int: + return self._vars.__len__() + + def to_dict(self): + return dict( + species=[v.to_dict() for v in self._species.values()], + constants=[v.to_dict() for v in self._const.values()], + parameters=[v.to_dict() for v in self._param.values()], + terms=[v.to_dict() for v in self._term.values()], ) + +class InitialQuality: + """A container for initial quality values for a species in a specific network.""" + + def __init__(self, global_value: float = 0.0, node_values: dict = None, link_values: dict = None): + """The initial quality values for a species. + + Arguments + --------- + global_value : float, optional + _description_, by default 0.0 + node_values : dict[str, float], optional + _description_, by default None + link_values : dict[str, float], optional + _description_, by default None + """ + self.global_value = global_value + """The global value for this species, if unspecified""" + self._node_values = node_values if node_values is not None else dict() + self._link_values = link_values if link_values is not None else dict() + @property - def dynamics(self) -> DynamicsType: - return DynamicsType.FORMULA + def node_values(self) -> Dict[str, float]: + """A mapping of node names to initial quality values for this species""" + return self._node_values - def to_symbolic(self): - return super().to_symbolic() + @property + def link_values(self) -> Dict[str, float]: + """A mapping of link names to initial quality values for this species""" + return self._link_values - def to_dict(self) -> dict: - rep = dict( - species=self.species, - dynamics=self.dynamics.name.lower(), - expression=self.expression, + def to_dict(self) -> Dict[str, Dict[str, float]]: + return dict(global_value=self.global_value, node_values=self._node_values.copy(), link_values=self._link_values.copy()) + + def __repr__(self) -> str: + return self.__class__.__name__ + "(global_value={}, node_values=<{} entries>, link_values=<{} entries>)".format( + self.global_value, len(self._node_values), len(self._link_values) ) - if isinstance(self.note, str): - rep["note"] = self.note - elif isinstance(self.note, ENcomment): - rep["note"] = asdict(self.note) if self.note.pre else self.note.post - else: - rep["note"] = None - return rep -class MultispeciesQualityModel(AbstractQualityModel): - """A multispecies water quality reactions model, for use with EPANET-MSX.""" +class ParameterValues: + """A container for pipe and tank specific values of a parameter for a specific network.""" - def __init__(self, msx_file_name=None): - """Create a new multispecies water quality reaction model. + def __init__(self, *, pipe_values: dict = None, tank_values: dict = None) -> None: + """The non-global values for a parameter. - Parameters - ---------- - msx_file_name : str, optional - The name of the MSX input file to read + Arguments + --------- + pipe_values : dict, optional + _description_, by default None + tank_values : dict, optional + _description_, by default None """ - self.name: str = None - """A one-line title for the model""" + self._pipe_values = pipe_values if pipe_values is not None else dict() + self._tank_values = tank_values if tank_values is not None else dict() - self.title: str = None - """The title line from the MSX file""" + @property + def pipe_values(self) -> Dict[str, float]: + """View onto the pipe values dictionary""" + return self._pipe_values - self.desc: str = None - """A longer description, to/from comments in top of MSX file""" + @property + def tank_values(self) -> Dict[str, float]: + """View onto the tank values dictionary""" + return self._tank_values - self._msxfile: str = msx_file_name - """The original filename""" + def to_dict(self) -> Dict[str, Dict[str, float]]: + return dict(pipe_values=self._pipe_values.copy(), tank_values=self._tank_values.copy()) - self._references: List[Union[dict, str]] = list() - """A list of references for the sources of this model's dynamics""" + def __repr__(self) -> str: + return self.__class__.__name__ + "(pipe_values=<{} entries>, tank_values=<{} entries>)".format( + len(self._pipe_values), len(self._tank_values) + ) - self._options: MultispeciesOptions = MultispeciesOptions() - """A link to the options object""" - self._wn: WaterNetworkModel = None - """A link to a water network model""" +class NetworkSpecificData: - self._variables: DisjointMapping = DisjointMapping() - self._species = self._variables.add_disjoint_group("species") - self._constants = self._variables.add_disjoint_group("constants") - self._params = self._variables.add_disjoint_group("parameters") - self._terms = self._variables.add_disjoint_group("terms") + def __init__(self) -> None: + """A container for network-specific values associated with a multispecies water quality model.""" + self._source_dict = dict() + self._initial_quality_dict: Dict[str, InitialQuality] = dict() + self._pattern_dict = dict() + self._parameter_value_dict: Dict[str, ParameterValues] = dict() - self._pipe_rxns = dict() - self._tank_rxns = dict() + @property + def sources(self): + """A dictionary of sources, keyed by species name""" + return self._source_dict - self._usage: Dict[str, Set[str]] = dict() # FIXME: currently no usage tracking + @property + def initial_quality(self) -> Dict[str, InitialQuality]: + """A dictionary of initial quality values, keyed by species name""" + return self._initial_quality_dict - self._source_dict: Dict[str, Dict[str, Source]] = dict() - self._inital_qual_dict: Dict[str, Dict[str, Dict[str, float]]] = dict() - self._pattern_dict: Dict[str, List[float]] = dict() + @property + def patterns(self): + """A dictionary of patterns, specific for the water quality model, keyed by pattern name. - self._report = list() + .. note:: the WaterNetworkModel cannot see these patterns, so names can be reused, so be + careful. Likewise, this model cannot see the WaterNetworkModel patterns, so this could be + a source of some confusion. + """ + return self._pattern_dict - for v in HYDRAULIC_VARIABLES: - self._variables[v["name"]] = InternalVariable(v["name"], note=v["note"]) - for name in EXPR_FUNCTIONS.keys(): - self._variables[name.lower()] = InternalVariable(name, note="MSX function") - self._variables[name.upper()] = InternalVariable(name, note="MSX function") - self._variables[name.capitalize()] = InternalVariable( - name, note="MSX function" - ) - if msx_file_name is not None: - from wntr.epanet.msx.io import MsxFile + @property + def parameter_values(self): + """A dictionary of parameter values, keyed by parameter name""" + return self._parameter_value_dict - inp = MsxFile() - inp.read(msx_file_name, self) + def add_pattern(self, name: str, multipliers: List[float]): + """Add a water-quality-model-specific pattern. - def _is_variable_registered( - self, var_or_name: Union[str, AbstractVariable] - ) -> bool: - name = str(var_or_name) - if name in self._variables.keys(): - return True - return False + Arguments + --------- + name : str + The pattern name + multipliers : List[float] + The pattern multipliers + """ + self._pattern_dict[name] = multipliers - def has_variable(self, name: str) -> bool: - """Check to see if there is a variable by this name. + def new_quality_values(self, species: Species): + """(Re)set the initial quality values for a species to a new container - Parameters - ---------- - name : str - a variable name to check + Arguments + --------- + species : Species + The species to (re) initialized. Returns ------- - bool - ``True`` if there is a variable by this name, ``False`` otherwise + InitialQuality + the new initial quality values container """ - return name in self._variables.keys() - - def variable_dict(self) -> Dict[str, Any]: - vars = dict() - for symb, spec in self._species.items(): - vars[symb] = symbols(symb) - for symb, coeff in self._constants.items(): - vars[symb] = symbols(symb) - for symb, coeff in self._params.items(): - vars[symb] = symbols(symb) - for symb, term in self._terms.items(): - vars[symb] = symbols(symb) - return vars + self._initial_quality_dict[str(species)] = InitialQuality() + if isinstance(species, Species): + species._vals = self._initial_quality_dict[str(species)] + return self._initial_quality_dict[str(species)] + + def remove_species(self, species: Union[Species, str]): + """Remove a species from the network specific model. + + Arguments + --------- + species : Union[Species, str] + _description_ + """ + if isinstance(species, Species): + species._vals = None + try: + self._initial_quality_dict.__delitem__(str(species)) + except KeyError: + pass - @property - def variable_name_list(self) -> List[str]: - """all defined variable names""" - return list(self._variables.keys()) + def new_parameter_values(self, param: Parameter): + """(Re)initialize parameter values for a parameter. - @property - def species_name_list(self) -> List[str]: - """all defined species names""" - return list(self._species.keys()) + Arguments + --------- + param : Parameter + _description_ - @property - def constant_name_list(self) -> List[str]: - """all defined coefficient names""" - return list(self._constants.keys()) + Returns + ------- + _type_ + _description_ + """ + self._parameter_value_dict[str(param)] = ParameterValues() + if isinstance(param, Parameter): + param._vals = self._parameter_value_dict[str(param)] + return self._parameter_value_dict[str(param)] + + def remove_parameter(self, param: Union[Parameter, str]): + """Remove values associated with a specific parameter. + + Arguments + --------- + param : Union[Parameter, str] + _description_ + """ + if isinstance(param, Parameter): + param._vals = None + try: + self._parameter_value_dict.__delitem__(str(param)) + except KeyError: + pass - @property - def parameter_name_list(self) -> List[str]: - """all defined coefficient names""" - return list(self._params.keys()) + def to_dict(self): + ret = dict(initial_quality=dict(), parameter_values=dict(), sources=dict(), patterns=dict()) + for k, v in self._initial_quality_dict.items(): + ret["initial_quality"][k] = v.to_dict() + for k, v in self._parameter_value_dict.items(): + ret["parameter_values"][k] = v.to_dict() + ret["sources"] = self._source_dict.copy() + ret["patterns"] = self._pattern_dict.copy() + return ret - @property - def other_term_name_list(self) -> List[str]: - """all defined function (MSX 'terms') names""" - return list(self._terms.keys()) - def variables(self, var_type: QualityVarType = None): - """A generator to loop over the variables. +class MultispeciesQualityModel: + """A multispecies water quality model for use with WNTR EPANET-MSX simulator.""" - Parameters - ---------- - var_type : QualityVarType, optional - limit results to a specific type, by default None + def __init__(self, msx_file_name=None) -> None: + """A full, multi-species water quality model. - Yields - ------ - RxnVariable - a variable defined within the model + Arguments + --------- + msx_file_name : str, optional + an MSX file to read in, by default None """ - var_type = QualityVarType.get(var_type) - for v in self._variables.values(): - if var_type is not None and v.var_type != var_type: - continue - yield v - - def add_variable( - self, - var_or_type: Union[AbstractVariable, QualityVarType], - name: str = None, - **kwargs, - ): - """Add an new variable to the model, or add an existing, unlinked variable object to the model. + self.name: str = None + """A name for the model, or the MSX model filename (no spaces allowed)""" + self.title: str = None + """The title line from the MSX file, must be a single line""" + self.desc: str = None + """A longer description, converted to comments in the top of an MSX file""" + self._msxfile: str = None + """The original filename""" + self._references: List[Union[str, Dict[str, str]]] = list() + self._options = MultispeciesOptions() + self._vars = VariableRegistry() + self._net = NetworkSpecificData() + self._wn = None - Parameters - ---------- - var_or_type : RxnVariable | QualityVarType - the variable object to add to the model, or the type if creating a new variable object - name : str or None - the name of a new variable, must be None if adding an existing object, by default None - kwargs - any keyword arguments to pass to a new object constructor + for v in HYDRAULIC_VARIABLES: + self._vars.add_variable(HydraulicVariable(**v)) + for k, v in EXPR_FUNCTIONS.items(): + self._vars.add_variable(MathFunction(name=k.lower(), func=v)) + self._vars.add_variable(MathFunction(name=k.capitalize(), func=v)) + self._vars.add_variable(MathFunction(name=k.upper(), func=v)) - Raises - ------ - TypeError - if var_or_type is not a valid object, or if trying to create a new internal/hydraulic variable - ValueError - if var_or_type is an object, but name is supplied, or if var_or_type is a type, but no name is supplied - VariableNameExistsError - if the variable or name uses the same name an existing variable already uses + @property + def references(self) -> List[Union[str, Dict[str, str]]]: + """A list of strings or mappings that provide references for this model. + This property should be modified using append/insert/remove. Members of + the list should be json seriealizable (i.e., strings or dicts of strings). """ - if not isinstance(var_or_type, (AbstractVariable,)): - try: - var_or_type = QualityVarType.get(var_or_type) - except Exception as e: - raise TypeError( - "Cannot add an object that is not a RxnVariable subclass or create a new object without a valid var_type" - ) from e - if name is None: - raise ValueError("When adding a new variable, a name must be supplied") - typ = var_or_type - if typ is QualityVarType.SPECIES: - self.add_species(name, **kwargs) - elif typ is QualityVarType.CONST: - self.add_constant(name, **kwargs) - elif typ is QualityVarType.PARAM: - self.add_parameter(name, **kwargs) - elif typ is QualityVarType.TERM: - self.add_other_term(var_or_type, name, **kwargs) - else: - raise TypeError( - "Cannot create new objects of the EXTERNAL type using this function" - ) + return self._references + + @property + def vars(self) -> VariableRegistry: + """The reaction variables defined for this model.""" + return self._vars + + @property + def net(self) -> NetworkSpecificData: + """The network-specific values added to this model.""" + return self._net + + @property + def options(self) -> MultispeciesOptions: + """The MSX model options""" + return self._options + + @options.setter + def options(self, value): + if isinstance(value, dict): + self._options = MultispeciesOptions.factory(value) + elif not isinstance(value, MultispeciesOptions): + raise TypeError("Expected a MultispeciesOptions object, got {}".format(type(value))) else: - if name is None or len(kwargs) > 0: - raise ValueError( - "When adding an existing variable object, no other arguments may be supplied" - ) - __variable = var_or_type - if self._is_variable_registered(__variable): - raise KeyExistsError( - "A variable with this name already exists in the model" - ) - typ = __variable.var_type - name = __variable.name - if hasattr(__variable, "_variable_registry"): - __variable._variable_registry = self - if typ is QualityVarType.SPECIES: - self._variables.add_item_to_group("species", name, __variable) - self._inital_qual_dict[name] = dict( - global_value=None, nodes=dict(), links=dict() - ) - self._source_dict[name] = dict() - elif typ is QualityVarType.CONST: - self._variables.add_item_to_group("constants", name, __variable) - elif typ is QualityVarType.PARAM: - self._variables.add_item_to_group("parameters", name, __variable) - elif typ is QualityVarType.TERM: - self._variables.add_item_to_group("terms", name, __variable) - else: - self._variables.add_item_to_group(None, name, __variable) + self._options = value def add_species( self, - species_type: Union[str, int, SpeciesType], name: str, + species_type: SpeciesType, units: str, atol: float = None, rtol: float = None, - note: str = None, + *, + note: Any = None, + diffusivity: float = None, + pipe_reaction: dict = None, + tank_reaction: dict = None, ) -> Species: - """Add a new species to the model. - The atol and rtol parameters must either both be omitted or both be provided. + """Add a species to the model - Parameters - ---------- - species_type : BULK | WALL - the type of species + Arguments + --------- name : str - the name/symbol of the species + _description_ + species_type : SpeciesType + _description_ units : str - the unit of concentration used + _description_ atol : float, optional - the absolute tolerance for the solver for this species, by default None (global value) + _description_, by default None rtol : float, optional - the relative tolerance fot the solver for this species, by default None (global value) - note : str, optional - a note or comment about this species, by default None + _description_, by default None + + Keyword Arguments + ----------------- + note : str | dict | ENcomment, optional + Supplementary information regarding this variable, by default None (see :class:`~wntr.epanet.util.ENcomment` for dict structure). + diffusivity : float, optional + Diffusivity in water for this species. + pipe_reaction : dict, optional + A dictionary that can be passed to the species' reaction builder + tank_reaction : dict, optional + A dictionary that can be passed to the species' reaction builder Returns ------- Species - the new species object + _description_ Raises ------ - ValueError - if species_type is invalid - VariableNameExistsError - if a variable with this name already exists in the model - TypeError - if atol and rtol are not both None or both a float + KeyError + _description_ """ - species_type = SpeciesType.get(species_type) - if species_type not in [SpeciesType.BULK, SpeciesType.WALL]: - raise ValueError( - "Species must be BULK or WALL, got {:s}".format(species_type) - ) - if self._is_variable_registered(name): - raise KeyExistsError( - "The variable {} already exists in this model".format(name) + if name in self._vars: + raise KeyError( + "Variable named {} already exists in model as type {}".format(name, self._vars._vars.get_groupname(name)) ) - if (atol is None) ^ (rtol is None): - raise TypeError( - "atol and rtol must be the same type, got {} and {}".format(atol, rtol) - ) - var = Species( - species_type=species_type, + species_type = SpeciesType.get(species_type, allow_none=False) + iq = self.net.new_quality_values(name) + new = Species( name=name, + species_type=species_type, units=units, atol=atol, rtol=rtol, note=note, - _qm=self, + _vars=self._vars, + _vals=iq, + diffusivity=diffusivity, + pipe_reaction=pipe_reaction, + tank_reaction=tank_reaction, ) - self._species[name] = var - self._inital_qual_dict[name] = dict( - [("global", None), ("nodes", dict()), ("links", dict())] - ) - self._source_dict[name] = dict() - return var - - def add_bulk_species( - self, - name: str, - units: str, - atol: float = None, - rtol: float = None, - note: str = None, - ) -> Species: - """Add a new bulk species to the model. - The atol and rtol parameters must either both be omitted or both be provided. - - Parameters - ---------- - name : str - the name/symbol of the species - units : str - the unit of concentration used - atol : float, optional - the absolute tolerance for the solver for this species, by default None (global value) - rtol : float, optional - the relative tolerance fot the solver for this species, by default None (global value) - note : str, optional - a note or comment about this species, by default None + self.vars.add_variable(new) + return new - Returns - ------- - Species - the new species object + def remove_species(self, species): + """Remove a species from the model. - Raises - ------ - VariableNameExistsError - if a variable with this name already exists in the model - TypeError - if atol and rtol are not both None or both a float + Arguments + --------- + species : _type_ + _description_ """ - return self.add_species(SpeciesType.BULK, name, units, atol, rtol, note) + name = str(species) + self.net.remove_species(name) + # FIXME: validate additional items + self.vars.__delitem__(name) - def add_wall_species( - self, - name: str, - units: str, - atol: float = None, - rtol: float = None, - note: str = None, - ) -> Species: - """Add a new wall species to the model. - The atol and rtol parameters must either both be omitted or both be provided. + def add_constant(self, name: str, value: float, *, units: str = None, note: Any = None) -> Constant: + """Add a constant coefficient to the model. - Parameters - ---------- + Arguments + --------- name : str - the name/symbol of the species - units : str - the unit of concentration used - atol : float, optional - the absolute tolerance for the solver for this species, by default None (global value) - rtol : float, optional - the relative tolerance fot the solver for this species, by default None (global value) - note : str, optional - a note or comment about this species, by default None + _description_ + value : float + _description_ - Returns - ------- - Species - the new species object - - Raises - ------ - VariableNameExistsError - if a variable with this name already exists in the model - TypeError - if atol and rtol are not both None or both a float - """ - return self.add_species(SpeciesType.WALL, name, units, atol, rtol, note) - - def add_coefficient( - self, - coeff_type: Union[str, int, QualityVarType], - name: str, - global_value: float, - note: str = None, - units: str = None, - **kwargs, - ) -> Union[Constant, Parameter]: - """Add a new coefficient to the model. - - Parameters - ---------- - coeff_type : CONST or PARAM - the type of coefficient to add - name : str - the name/symbol of the coefficient - global_value : float - the global value for the coefficient - note : str, optional - a note or comment about this coefficient, by default None + Keyword Arguments + ----------------- units : str, optional - a unit for this coefficient, by default None - kwargs : other keyword arguments - certain coefficient classes have additional arguments. If specified, - these will be passed to the constructor for the relevant class. + _description_, by default None + note : str | dict | ENcomment, optional + Supplementary information regarding this variable, by default None (see :class:`~wntr.epanet.util.ENcomment` for dict structure). Returns ------- - Coefficient - the new coefficient object + Constant + _description_ Raises ------ - ValueError - if the coeff_type is invalid - VariableNameExistsError - if a variable with this name already exists in the model + KeyError + _description_ """ - coeff_type = QualityVarType.get(coeff_type) - if coeff_type not in [QualityVarType.CONST, QualityVarType.PARAM]: - raise ValueError( - "coeff_type must be CONST or PARAM, got {:s}".format(coeff_type) + if name in self._vars: + raise KeyError( + "Variable named {} already exists in model as type {}".format(name, self._vars._vars.get_groupname(name)) ) - if self._is_variable_registered(name): - raise KeyExistsError( - "The variable {} already exists in this model".format(name) - ) - if coeff_type is QualityVarType.CONST: - return self.add_constant( - name=name, global_value=global_value, note=note, units=units - ) - else: - return self.add_parameter( - name=name, global_value=global_value, note=note, units=units, **kwargs - ) - - def add_constant( - self, name: str, global_value: float, note: str = None, units: str = None - ) -> Constant: - """Add a new constant coefficient to the model. - - Parameters - ---------- - coeff_type : CONST or PARAM - the type of coefficient to add - name : str - the name/symbol of the coefficient - global_value : float - the global value for the coefficient - note : str, optional - a note or comment about this coefficient, by default None - units : str, optional - units for this coefficient, by default None + new = Constant(name=name, value=value, units=units, note=note, _vars=self._vars) + self.vars.add_variable(new) + return new - Returns - ------- - Coefficient - the new coefficient object + def remove_constant(self, const): + """Remove a constant coefficient from the model. - Raises - ------ - ValueError - if the coeff_type is invalid - VariableNameExistsError - if a variable with this name already exists in the model + Arguments + --------- + const : _type_ + _description_ """ - if self._is_variable_registered(name): - raise KeyExistsError( - "The variable {} already exists in this model".format(name) - ) - var = Constant( - name=name, global_value=global_value, note=note, units=units, _qm=self - ) - self._constants[name] = var - return var + name = str(const) + # FIXME: validate deletion + self.vars.__delitem__(name) - def add_parameter( - self, - name: str, - global_value: float, - note: str = None, - units: str = None, - pipe_values: Dict[str, float] = None, - tank_values: Dict[str, float] = None, - ) -> Parameter: - """Add a new parameterized coefficient (based on pipe/tank name) to the model. + def add_parameter(self, name: str, global_value: float, *, units: str = None, note: Any = None) -> Parameter: + """Add a parameterized coefficient to the model. - Parameters - ---------- - coeff_type : CONST or PARAM - the type of coefficient to add + Arguments + --------- name : str - the name/symbol of the coefficient + _description_ global_value : float - the global value for the coefficient - note : str, optional - a note or comment about this coefficient, by default None - units: str, optional - a unit for this coefficient, by default None - pipe_values : dict, optional - values for this coefficient in specifically named pipes - tank_values : dict, optional - values for this coefficient in specifically named tanks + _description_ - Returns - ------- - Coefficient - the new coefficient object - - Raises - ------ - ValueError - if the coeff_type is invalid - VariableNameExistsError - if a variable with this name already exists in the model - """ - if self._is_variable_registered(name): - raise KeyExistsError( - "The variable {} already exists in this model".format(name) - ) - var = Parameter( - name=name, - global_value=global_value, - note=note, - units=units, - pipe_values=pipe_values, - tank_values=tank_values, - _qm=self, - ) - self._params[name] = var - return var - - def add_other_term(self, name: str, expression: str, note: str = None) -> OtherTerm: - """Add a new user-defined function to the model. - In EPANET-MSX, these variables are called 'TERMS', and serve as shortcut aliases - to simplify reaction expressions that would otherwise become very hard to read/write - on a single line (a requirement in EPANET-MSX input files). Because 'term' is - ambiguous, this will be referred to as a 'other term' or 'simplifying term'. - - Parameters - ---------- - name : str - the name/symbol for this function (an MSX 'term') - expression : str - the symbolic expression for this function - note : str, optional - a note or comment about this function, by default None + Keyword Arguments + ----------------- + units : str, optional + _description_, by default None + note : str | dict | ENcomment, optional + Supplementary information regarding this variable, by default None (see :class:`~wntr.epanet.util.ENcomment` for dict structure). Returns ------- - UserFunction - the new function or simplyifying term object + Parameter + _description_ Raises ------ - VariableNameExistsError - if a variable with this name already exists in the model + KeyError + _description_ """ - if self._is_variable_registered(name): - raise KeyExistsError( - "The variable {} already exists in this model".format(name) + if name in self._vars: + raise KeyError( + "Variable named {} already exists in model as type {}".format(name, self._vars._vars.get_groupname(name)) ) - var = OtherTerm(name=name, expression=expression, note=note, _qm=self) - self._terms[name] = var - return var + pv = self.net.new_parameter_values(name) + new = Parameter(name=name, global_value=global_value, units=units, note=note, _vars=self._vars, _vals=pv) + self.vars.add_variable(new) + return new - def remove_variable(self, name: str): - """Remove a variable from the model. + def remove_parameter(self, param): + """Remove a parameterized coefficient from the model. - Parameters - ---------- - name : str - variable name + Arguments + --------- + param : _type_ + _description_ """ - if name in self._inital_qual_dict.keys(): - self._inital_qual_dict.__delitem__(name) - if name in self._source_dict.keys(): - self._source_dict.__delitem__(name) - return self._variables.__delitem__(name) + name = str(param) + self.net.remove_parameter(name) + # FIXME: validate additional items + self.vars.__delitem__(name) - def get_variable(self, name: str) -> AbstractVariable: - """Get a variable based on its name (symbol). + def add_term(self, name: str, expression: str, *, note: Any = None) -> Term: + """Add a named expression (term) to the model. - Parameters - ---------- + Arguments + --------- name : str - The variable name + _description_ + expression : str + _description_ + + Keyword Arguments + ----------------- + note : str | dict | ENcomment, optional + Supplementary information regarding this variable, by default None (see :class:`~wntr.epanet.util.ENcomment` for dict structure). Returns ------- - ReactionVariable - the variable with the name in question + Term + _description_ Raises ------ KeyError - a variable with that name does not exist + _description_ """ - return self._variables[name] - - def reactions(self, location: LocationType = None): - """A generator for iterating through reactions in the model. + if name in self._vars: + raise KeyError( + "Variable named {} already exists in model as type {}".format(name, self._vars._vars.get_groupname(name)) + ) + new = Term(name=name, expression=expression, note=note, _vars=self._vars) + self.vars.add_variable(new) + return new - Parameters - ---------- - location : RxnLocationType, optional - limit results to reactions within location, by default None + def remove_term(self, term): + """Remove a named expression (term) from the model. - Yields - ------ - ReactionDynamics - a reaction defined within the model + Arguments + --------- + term : _type_ + _description_ """ - location = LocationType.get(location) - if location is None or location is LocationType.PIPE: - for v in self._pipe_rxns.values(): - yield v - if location is None or location is LocationType.TANK: - for v in self._tank_rxns.values(): - yield v + name = str(term) + # FIXME: validate deletion + self.vars.__delitem__(name) def add_reaction( - self, - location: LocationType, - species: Union[str, Species], - dynamics: Union[str, int, DynamicsType], - expression: str, - note: str = None, - ): - """Add a multispecies water quality reaction to the model. + self, species: Species, location: LocationType, dynamics_type: DynamicsType, expression: str, *, note: Any = None + ) -> WaterQualityReaction: + """Add a reaction to a species in the model. - Parameters - ---------- - location : LocationType - where the reaction is taking place - species : Union[str, Species] - the species with the dynamics that are being described - dynamics : Union[str, int, DynamicsType] - the type of reaction dynamics used to describe this species changes through time - expression : str - the right-hand-side of the reaction dynamics equation - note : str, optional - a note about this reaction, by default None + Note that all species need to have both a pipe and tank reaction defined unless all species are bulk species and + the tank reactions are identical to the pipe reactions. However, it is not recommended that users take this approach. - Returns - ------- - ReactionDynamics - the resulting reaction object + Once added, access the reactions from the species' object. - Raises - ------ - ValueError - species does not exist - RuntimeError - species already has reaction defined FIXME: this should be an MSX error - ValueError - invalid dynamics type - ValueError - invalid location type - """ - # TODO: accept a "both" or "all" value for location - location = LocationType.get(location) - species = str(species) - if species not in self._species.keys(): - raise ValueError( - "The species {} does not exist in the model, failed to add reaction.".format( - species - ) - ) - _key = species # = AbstractReaction.to_key(species, location) - if (location is LocationType.PIPE and _key in self._pipe_rxns.keys()) or ( - location is LocationType.TANK and _key in self._tank_rxns.keys() - ): - raise RuntimeError("The species {} already has a {} reaction defined.") - dynamics = DynamicsType.get(dynamics) - new = None - if dynamics is DynamicsType.EQUIL: - new = EquilibriumDynamics( - species=species, - location=location, - expression=expression, - note=note, - _qm=self, - ) - elif dynamics is DynamicsType.RATE: - new = RateDynamics( - species=species, - location=location, - expression=expression, - note=note, - _qm=self, - ) - elif dynamics is DynamicsType.FORMULA: - new = FormulaDynamics( - species=species, - location=location, - expression=expression, - note=note, - _qm=self, - ) - else: - raise ValueError("Invalid dynamics type, {}".format(dynamics)) - if location is LocationType.PIPE: - self._pipe_rxns[str(new)] = new - elif location is LocationType.TANK: - self._tank_rxns[str(new)] = new - else: - raise ValueError("Invalid location type, {}".format(location)) - return new - - def add_pipe_reaction( - self, - species: Union[str, Species], - dynamics: Union[str, int, DynamicsType], - expression: str, - note: str = None, - ) -> AbstractReaction: - """Add a pipe reaction. See also :meth:`add_reaction`. - - Parameters - ---------- - species : Union[str, Species] - the species with the dynamics that are being described - dynamics : Union[str, int, DynamicsType] - the type of reaction dynamics used to describe this species changes through time + Arguments + --------- + species : Species + _description_ + location : LocationType + _description_ + dynamics_type : DynamicsType + _description_ expression : str - the right-hand-side of the reaction dynamics equation - note : str, optional - a note about this reaction, by default None + _description_ - Returns - ------- - ReactionDynamics - the reaction object - """ - return self.add_reaction( - LocationType.PIPE, - species=species, - dynamics=dynamics, - expression=expression, - note=note, - ) - - def add_tank_reaction( - self, - species: Union[str, Species], - dynamics: Union[str, int, DynamicsType], - expression: str, - note: str = None, - ) -> AbstractReaction: - """Add a pipe reaction. See also :meth:`add_reaction`. - - Parameters - ---------- - species : Union[str, Species] - the species with the dynamics that are being described - dynamics : Union[str, int, DynamicsType] - the type of reaction dynamics used to describe this species changes through time - expression : str - the right-hand-side of the reaction dynamics equation - note : str, optional - a note about this reaction, by default None + Keyword Arguments + ----------------- + note : str | dict | ENcomment, optional + Supplementary information regarding this reaction, by default None (see :class:`~wntr.epanet.util.ENcomment` for dict structure). Returns ------- - ReactionDynamics - the reaction object - """ - return self.add_reaction( - LocationType.TANK, - species=species, - dynamics=dynamics, - expression=expression, - note=note, - ) - - def remove_reaction( - self, - species: Union[str, Species], - location: Union[str, int, LocationType, Literal["all"]], - ): - """Remove a reaction for a species from the model - - Parameters - ---------- - species : str or Species - the species to remove a reaction for - location : str, int, LocationType or 'all' - the location of the reaction to delete, with 'all' meaning both wall and pipe reactions + MultispeciesReaction + _description_ Raises ------ - ValueError - if the value for `location` is invalid + TypeError + _description_ """ - if location != "all": - location = LocationType.get(location) species = str(species) - if location is None: - raise TypeError( - 'location cannot be None when removing a reaction. Use "all" for all locations.' - ) - elif location == "all": - name = AbstractReaction.to_key(species, LocationType.PIPE) - try: - self._pipe_rxns.__delitem__(name) - except KeyError: - pass - name = AbstractReaction.to_key(species, LocationType.TANK) - try: - self._tank_rxns.__delitem__(name) - except KeyError: - pass - elif location is LocationType.PIPE: - name = AbstractReaction.to_key(species, LocationType.PIPE) - try: - self._pipe_rxns.__delitem__(name) - except KeyError: - pass - elif location is LocationType.TANK: - name = AbstractReaction.to_key(species, LocationType.TANK) - try: - self._tank_rxns.__delitem__(name) - except KeyError: - pass - else: - raise ValueError("Invalid location, {}".format(location)) - - def get_reaction(self, species, location): - """Get a reaction for a species at either a pipe or tank. + species = self.vars.species[species] + if species.var_type is not QualityVarType.SPECIES: + raise TypeError("Variable {} is not a Species, is a {}".format(species, species.var_type)) + if isinstance(location, str): + location.replace("_reaction", "") + location = LocationType.get(location, allow_none=False) + dynamics_type = DynamicsType.get(dynamics_type, allow_none=False) + return species.add_reaction(location=location, dynamics_type=dynamics_type, expression=expression, note=note) + + def remove_reaction(self, species: str, location: LocationType) -> None: + """Remove a reaction at a specified location from a species. Parameters ---------- - species : str or Species - the species to get a reaction for - location : str, int, or LocationType - the location of the reaction - - Returns - ------- - ReactionDynamics - the requested reaction object + species : str + the species name to remove the reaction from + location : LocationType + the location to remove the reaction from """ - if species is None: - raise TypeError("species must be a string or Species") - if location is None: - raise TypeError("location must be a string, int, or LocationType") + location = LocationType.get(location, allow_none=False) species = str(species) - location = LocationType.get(location) - if location == LocationType.PIPE: - return self._pipe_rxns.get(species) - elif location == LocationType.TANK: - return self._tank_rxns.get(species) + spec_obj = self.vars.species[species] + if location is LocationType.PIPE: + spec_obj.pipe_reaction = None + elif location is LocationType.TANK: + spec_obj.tank_reaction = None + else: + raise ValueError("Unknown location, {}".format(location)) - def init_printing(self, *args, **kwargs): - """Call sympy.init_printing""" - init_printing(*args, **kwargs) + @property + def species_name_list(self) -> List[str]: + """all defined species names""" + return list(self.vars.species.keys()) @property - def references(self) -> List[Union[str, dict]]: - """A list of citation strings or dict objects. - """ - return self._references + def constant_name_list(self) -> List[str]: + """all defined coefficient names""" + return list(self.vars.constants.keys()) @property - def options(self) -> MultispeciesOptions: - """The multispecies reaction model options.""" - return self._options + def parameter_name_list(self) -> List[str]: + """all defined coefficient names""" + return list(self.vars.parameters.keys()) - @options.setter - def options(self, value): - if isinstance(value, dict): - self._options = MultispeciesOptions.factory(value) - elif not isinstance(value, MultispeciesOptions): - raise TypeError( - "Expected a MultispeciesOptions object, got {}".format(type(value)) - ) - else: - self._options = value + @property + def term_name_list(self) -> List[str]: + """all defined function (MSX 'terms') names""" + return list(self.vars.terms.keys()) - def link_water_network_model(self, wn: WaterNetworkModel): - self._wn = wn + def to_dict(self): + from wntr import __version__ - def to_dict(self) -> dict: - """Convert this water quality model to a dictionary""" - return wntr.quality.io.to_dict(self) - - def from_dict(self, d) -> dict: - """Append to this water quality model from a dictionary""" - wntr.quality.io.from_dict(d, append=self) - - def __repr__(self): - if self._msxfile or self.name: - return "{}({})".format( - self.__class__.__name__, - repr(self._msxfile) if self._msxfile else repr(self.name), - ) - return super().__repr__() - - def pycode(self): - lines = list() - lines.append("msx = {}()".format(self.__class__.__qualname__)) - lines.append("msx.title = {}".format(repr(self.title))) - for citation in self.references: - lines.append("msx.references.append({})".format(repr(self.references))) - for v in self._species.values(): - lines.append( - "msx.add_species({})".format( - ", ".join( - ["{}={}".format(k, repr(v1)) for k, v1 in v.to_dict().items()] - ) - ) - ) - for v in self._constants.values(): - lines.append( - "msx.add_constant({})".format( - ", ".join( - ["{}={}".format(k, repr(v1)) for k, v1 in v.to_dict().items()] - ) - ) - ) - for v in self._params.values(): - lines.append( - "msx.add_parameter({})".format( - ", ".join( - ["{}={}".format(k, repr(v1)) for k, v1 in v.to_dict().items()] - ) - ) - ) - for v in self._terms.values(): - lines.append( - "msx.add_other_term({})".format( - ", ".join( - ["{}={}".format(k, repr(v1)) for k, v1 in v.to_dict().items()] - ) - ) - ) - for v in self._pipe_rxns.values(): - lines.append( - "msx.add_pipe_reaction({})".format( - ", ".join( - ["{}={}".format(k, repr(v1)) for k, v1 in v.to_dict().items()] - ) - ) - ) - for v in self._tank_rxns.values(): - lines.append( - "msx.add_tank_reaction({})".format( - ", ".join( - ["{}={}".format(k, repr(v1)) for k, v1 in v.to_dict().items()] - ) - ) - ) - lines.append("msx.options = {}".format(self.options.to_dict())) - return lines + return dict( + version="wntr-{}".format(__version__), + name=self.name, + title=self.title, + desc=self.desc, + references=self.references.copy(), + variables=self.vars.to_dict(), + net_specific=self.net.to_dict(), + options=self.options.to_dict(), + ) diff --git a/wntr/quality/options.py b/wntr/quality/options.py index d17f49846..1814c9fba 100644 --- a/wntr/quality/options.py +++ b/wntr/quality/options.py @@ -2,12 +2,10 @@ """Options for multispecies reaction models. """ -import re import logging -import copy from typing import Dict, List, Literal, Union -from wntr.network.options import _float_or_None, _int_or_None, _OptionsBase +from wntr.network.options import _OptionsBase logger = logging.getLogger(__name__) From 84e92ea91392fe81a2a4f0c0ec52fc1076933da6 Mon Sep 17 00:00:00 2001 From: dbhart Date: Fri, 27 Oct 2023 09:29:25 -0600 Subject: [PATCH 33/75] Tests still broken, but now fully running MSX --- documentation/advancedqual.rst | 408 +++++++ documentation/apidoc/wntr.quality.io.rst | 7 - documentation/apidoc/wntr.quality.rst | 1 - documentation/apidoc/wntr.utils.citations.rst | 7 - documentation/apidoc/wntr.utils.rst | 1 - documentation/conf.py | 2 +- documentation/index.rst | 1 + documentation/reference.rst | 2 + wntr/epanet/__init__.py | 3 + wntr/epanet/exceptions.py | 295 +++-- wntr/epanet/io.py | 20 +- wntr/epanet/msx/__init__.py | 3 +- wntr/epanet/msx/io.py | 269 +++-- wntr/epanet/msx/toolkit.py | 5 +- wntr/epanet/toolkit.py | 10 + wntr/epanet/util.py | 7 +- wntr/network/io.py | 9 +- wntr/network/model.py | 14 +- .../_library_data/arsenic_chloramine.json | 203 ++++ .../_library_data/batch_chloramine_decay.json | 415 +++++++ wntr/quality/_library_data/lead_ppm.json | 98 ++ wntr/quality/_library_data/nicotine.json | 108 ++ wntr/quality/_library_data/nicotine_ri.json | 158 +++ wntr/quality/base.py | 159 ++- wntr/quality/library.py | 1038 ++++++----------- wntr/quality/multispecies.py | 815 +++++++------ wntr/quality/options.py | 110 +- wntr/sim/epanet.py | 24 +- wntr/tests/test_quality_variables.py | 96 +- wntr/utils/citations.py | 337 ------ wntr/utils/enumtools.py | 72 +- 31 files changed, 2812 insertions(+), 1885 deletions(-) create mode 100644 documentation/advancedqual.rst delete mode 100644 documentation/apidoc/wntr.quality.io.rst delete mode 100644 documentation/apidoc/wntr.utils.citations.rst create mode 100644 wntr/quality/_library_data/arsenic_chloramine.json create mode 100644 wntr/quality/_library_data/batch_chloramine_decay.json create mode 100644 wntr/quality/_library_data/lead_ppm.json create mode 100644 wntr/quality/_library_data/nicotine.json create mode 100644 wntr/quality/_library_data/nicotine_ri.json delete mode 100644 wntr/utils/citations.py diff --git a/documentation/advancedqual.rst b/documentation/advancedqual.rst new file mode 100644 index 000000000..54d58149b --- /dev/null +++ b/documentation/advancedqual.rst @@ -0,0 +1,408 @@ +.. raw:: latex + + \clearpage + +.. _advanced_simulation: + +Advanced water quality techniques +================================= + +This section describes several advanced simulation techniques using WNTR with MSX. + + + +.. _msx_example1_lead: + +Example 1: plumbosolvency of lead +--------------------------------- + +This model is described in [BWMS20]_, and represents plumbosolvency of lead in lead pipes +within a dwelling. +In this case, we will not assume that a water network model has been made for the dwelling, yet. + +Model creation +~~~~~~~~~~~~~~ + +We create a new model, give it a name, title, and description, and we add the reference +for the paper this model was described in. + +.. doctest:: + + >>> import wntr.quality + >>> msx = wntr.quality.MultispeciesQualityModel() + >>> msx.name = "lead_ppm" + >>> msx.title = "Lead Plumbosolvency Model (from Burkhardt et al 2020)" + >>> msx.desc = "Parameters for EPA HPS Simulator Model" + >>> msx.references.append( + ... """J. B. Burkhardt, et al. (2020) https://doi.org/10.1061/(asce)wr.1943-5452.0001304""" + ... ) + >>> msx + MultispeciesQualityModel(name='lead_ppm') + +Next, we will update certain options. + +.. doctest:: + + >>> msx.options = { + ... "report": { + ... "species": {"PB2": "YES"}, + ... "species_precision": {"PB2": 5}, + ... "nodes": "all", + ... "links": "all", + ... }, + ... "timestep": 1, + ... "area_units": "M2", + ... "rate_units": "SEC", + ... "rtol": 1e-08, + ... "atol": 1e-08, + ... } + + +Adding variables +~~~~~~~~~~~~~~~~ +The variables that are needed for a multispecies reaction system are: species, coefficients, and terms. +These are used in expressions to define the dynamics of the reaction. All variables have at least two +attributes: their name and a note. The variable name must be a valid EPANET-MSX id, which primarily +means no spaces are permitted. However, it may be useful to ensure that the name is a valid python +variable name, so that it can be used to identify the variable in your code as well. The note can be +a string, a dictionary with the keys "pre" and "post", or an :class:`~wntr.epanet.util.ENcomment` object +(which has a "pre" and "post" attribute). See the ENcomment documentation for details on the meaning; +in this example we will use the string form of the note. + +-------------- + +There is only one species defined in this model, which is dissolved lead. + +======================== =============== ================================= ======================== +Name Type Units Note +------------------------ --------------- --------------------------------- ------------------------ +:math:`Pb` bulk species :math:`\mathrm{μg}_\mathrm{(Pb)}` dissolved lead +======================== =============== ================================= ======================== + +To add this species to the model, we can use the model's :meth:`~wntr.quality.multispecies.MultispeciesQualityModel.add_species` +method. +The method arguments are the name, the species_type (which can either be "bulk" or "wall"), the units, +and an optional note. +This method will add the new species to the model and also return a copy of the new species object. + +.. doctest:: + + >>> msx.add_species(name="PB2", species_type='bulk', units="ug", note="dissolved lead (Pb)") + Species(name='PB2', species_type=, units='ug', atol=None, rtol=None, note='dissolved lead (Pb)') + +The new species can be accessed by using the item's name and indexing on the model's +:attr:`~wntr.quality.multispecies.MultispeciesQualityModel.reaction_system` attribute. + + >>> PB2 = msx.reaction_system['PB2'] + >>> PB2 + Species(name='PB2', species_type=, units='ug', atol=None, rtol=None, note='dissolved lead (Pb)') + +-------------- + +There are two different types of coefficients that can be used in reaction expressions: constants +and parameters. Constants have a single value in every expression. Parameters have a global value +that is used by default, but which can be modified on a per-pipe or per-tank basis. This model +has two constants and one parameter. + +=============== =============== =============== ================================= ======================== +Type Name Value Units Note +--------------- --------------- --------------- --------------------------------- ------------------------ +constant :math:`M` 0.117 :math:`\mathrm{μg~m^{-2}~s^{-1}}` desorption rate +constant :math:`E` 140.0 :math:`\mathrm{μg~L^{-1}}` saturation level +parameter :math:`F` 0 `n/a` is pipe made of lead? +=============== =============== =============== ================================= ======================== + +We can add these to the model as follows: + +.. doctest:: + + >>> msx.add_constant("M", value=0.117, note="Desorption rate (ug/m^2/s)", units="ug * m^(-2) * s^(-1)") + >>> msx.add_constant("E", value=140.0, note="saturation/plumbosolvency level (ug/L)", units="ug/L") + >>> msx.add_parameter("F", global_value=0, note="determines which pipes have reactions") + + +Adding reactions +~~~~~~~~~~~~~~~~ + +All species must have two reactions defined for the model to be run successfully in EPANET-MSX by WNTR. +One is a pipe reaction, the other is a tank reaction. In this case, we only have a reactions within +pipes, so we need to set the tank reaction to be unchanging. The system of equations is: + +.. math:: + + \frac{d}{dt}Pb_p &= F_p \, Av_p \, M \frac{\left( E - Pb_p \right)}{E}, &\quad\text{for all pipes}~p~\text{in network} \\ + \frac{d}{dt}Pb_t &= 0, & \quad\text{for all tanks}~t~\text{in network} + +Note that the pipe reaction has a variable that we have not defined, :math:`Av`, in its expression; +this variable is a pre-defined hydraulic variable. The list of these variables can be found in +the EPANET-MSX documentation, and also in the :attr:`~wntr.quality.base.HYDRAULIC_VARIABLES` +documentation. The reactions can be described in WNTR as + +================ ============== ========================================================================== +Reaction type Dynamics type Reaction expression +---------------- -------------- -------------------------------------------------------------------------- +pipe rate :math:`F \cdot Av \cdot M \cdot \left( E - Pb \right) / E` +tank rate :math:`0` +================ ============== ========================================================================== + +and then added to the reaction model using the :meth:`~wntr.quality.multispecies.MultispeciesQualityModel.add_reaction` +method. + +.. doctest:: + + >>> msx.add_reaction("PB2", "pipe", "RATE", expression="F * Av * M * (E - PB2) / E") + >>> msx.add_reaction(PB2, "tank", "rate", expression="0") + + + +Example 2: arsenic oxidation and adsorption +------------------------------------------- + +This example models monochloramine oxidation of arsenite/arsenate and wall +adsorption/desorption, as given in section 3 of the EPANET-MSX user manual [SRU23]_. +First, the model +will be restated here and then the code to create the model in wntr will be shown. + +Model Description +~~~~~~~~~~~~~~~~~ + +The system of equations for the reaction in pipes is given in Eq. (2.4) through (2.7) +in [SRU23]_. This is a simplified model, taken from [GSCL94]_. + +.. math:: + + \frac{d}{dt}{(\mathsf{As}^\mathrm{III})} &= -k_a ~ {(\mathsf{As}^\mathrm{III})} ~ {(\mathsf{NH_2Cl})} \\ + \frac{d}{dt}{(\mathsf{As}^\mathrm{V})} &= k_a ~ {(\mathsf{As}^\mathrm{III})} ~ {(\mathsf{NH_2CL})} - Av \left( k_1 \left(S_\max - {(\mathsf{As}^\mathrm{V}_s)} \right) {(\mathsf{As}^\mathrm{V})} - k_2 ~ {(\mathsf{As}^\mathrm{V}_s)} \right) \\ + \frac{d}{dt}{(\mathsf{NH_2Cl})} &= -k_b ~ {(\mathsf{NH_2Cl})} \\ + {(\mathsf{As}^\mathrm{V}_s)} &= \frac{k_s ~ S_\max ~ {(\mathsf{As}^\mathrm{V})}}{1 + k_s {(\mathsf{As}^\mathrm{V})}} + + +where the various species, coefficients, and expressions are described in the tables below. + + +.. list-table:: Options + :header-rows: 1 + :widths: 3 3 10 + + * - Option + - Code + - Description + * - Rate units + - "HR" + - :math:`\mathrm{h}^{-1}` + * - Area units + - "M2" + - :math:`\mathrm{m}^2` + + +.. list-table:: Species + :header-rows: 1 + :widths: 2 2 2 3 4 6 + + * - Name + - Type + - Value + - Symbol + - Units + - Note + * - AS3 + - Bulk + - "UG" + - :math:`{\mathsf{As}^\mathrm{III}}` + - :math:`\require{upgreek}\upmu\mathrm{g~L^{-1}}` + - dissolved arsenite + * - AS5 + - Bulk + - "UG" + - :math:`{\mathsf{As}^\mathrm{V}}` + - :math:`\require{upgreek}\upmu\mathrm{g~L^{-1}}` + - dissolved arsenate + * - AStot + - Bulk + - "UG" + - :math:`{\mathsf{As}^\mathrm{tot}}` + - :math:`\require{upgreek}\upmu\mathrm{g~L^{-1}}` + - dissolved arsenic (total) + * - NH2CL + - Bulk + - "MG" + - :math:`{\mathsf{NH_2Cl}}` + - :math:`\mathrm{mg~L^{-1}}` + - dissolved monochloramine + * - AS5s + - Wall + - "UG" + - :math:`{\mathsf{As}^\mathrm{V}_{s}}` + - :math:`\require{upgreek}\upmu\mathrm{g}~\mathrm{m}^{-2}` + - adsorped arsenate (surface) + + +.. list-table:: Coefficients + :header-rows: 1 + :widths: 2 2 2 3 4 6 + + * - Name + - Type + - Value + - Symbol + - Units + - Note + * - Ka + - Const + - :math:`10` + - :math:`k_a` + - :math:`\mathrm{mg}^{-1}_{\left(\mathsf{NH_2Cl}\right)}~\mathrm{h}^{-1}` + - arsenite oxidation + * - Kb + - Const + - :math:`0.1` + - :math:`k_b` + - :math:`\mathrm{h}^{-1}` + - chloromine decay + * - K1 + - Const + - :math:`5.0` + - :math:`k_1` + - :math:`\require{upgreek}\textrm{L}~\upmu\mathrm{g}^{-1}_{\left(\mathsf{As}^\mathrm{V}\right)}~\mathrm{h}^{-1}` + - arsenate adsorption + * - K2 + - Const + - :math:`1.0` + - :math:`k_2` + - :math:`\textrm{L}~\mathrm{h}^{-1}` + - arsenate desorption + * - Smax + - Const + - :math:`50.0` + - :math:`S_{\max}` + - :math:`\require{upgreek}\upmu\mathrm{g}_{\left(\mathsf{As}^\mathrm{V}\right)}~\mathrm{m}^{-2}` + - arsenate adsorption limit + + +.. list-table:: Other terms + :header-rows: 1 + :widths: 3 3 2 3 10 + + * - Name + - Symbol + - Expression + - Units + - Note + * - Ks + - :math:`k_s` + - :math:`{k_1}/{k_2}` + - :math:`\require{upgreek}\upmu\mathrm{g}^{-1}_{\left(\mathsf{As}^\mathrm{V}\right)}` + - equilibrium adsorption coefficient + + +.. list-table:: Pipe reactions + :header-rows: 1 + :widths: 3 3 16 + + * - Species + - Type + - Expression + * - AS3 + - Rate + - :math:`-k_a \, {\mathsf{As}^\mathrm{III}} \, {\mathsf{NH_2Cl}}` + * - AS5 + - Rate + - :math:`k_a \, {\mathsf{As}^\mathrm{III}} \, {\mathsf{NH_2Cl}} -Av \left( k_1 \left(S_{\max}-{\mathsf{As}^\mathrm{V}_{s}} \right) {\mathsf{As}^\mathrm{V}} - k_2 \, {\mathsf{As}^\mathrm{V}_{s}} \right)` + * - NH2CL + - Rate + - :math:`-k_b \, {\mathsf{NH_2Cl}}` + * - AStot + - Formula + - :math:`{\mathsf{As}^\mathrm{III}} + {\mathsf{As}^\mathrm{V}}` + * - AS5s + - Equil + - :math:`k_s \, S_{\max} \frac{{\mathsf{As}^\mathrm{V}}}{1 + k_s \, {\mathsf{As}^\mathrm{V}}} - {\mathsf{As}^\mathrm{V}_{s}}` + + +.. list-table:: Tank reactions + :header-rows: 1 + :widths: 3 3 16 + + * - Species + - Type + - Expression + * - AS3 + - Rate + - :math:`-k_a \, {\mathsf{As}^\mathrm{III}} \, {\mathsf{NH_2Cl}}` + * - AS5 + - Rate + - :math:`k_a \, {\mathsf{As}^\mathrm{III}} \, {\mathsf{NH_2Cl}}` + * - NH2CL + - Rate + - :math:`-k_b \, {\mathsf{NH_2Cl}}` + * - AStot + - Formula + - :math:`{\mathsf{As}^\mathrm{III}} + {\mathsf{As}^\mathrm{V}}` + * - AS5s + - Equil + - :math:`0` (`not present in tanks`) + + +Creation in WNTR +~~~~~~~~~~~~~~~~ + +.. doctest:: + + >>> msx = wntr.quality.MultispeciesQualityModel() + >>> msx.name = "arsenic_chloramine" + >>> msx.title = "Arsenic Oxidation/Adsorption Example" + >>> msx.references.append(wntr.quality.library.cite_msx()) + >>> AS3 = msx.add_species(name="AS3", species_type="BULK", units="UG", note="Dissolved arsenite") + >>> AS5 = msx.add_species(name="AS5", species_type="BULK", units="UG", note="Dissolved arsenate") + >>> AStot = msx.add_species(name="AStot", species_type="BULK", units="UG", note="Total dissolved arsenic") + >>> AS5s = msx.add_species(name="AS5s", species_type="WALL", units="UG", note="Adsorbed arsenate") + >>> NH2CL = msx.add_species(name="NH2CL", species_type="BULK", units="MG", note="Monochloramine") + >>> Ka = msx.add_constant("Ka", 10.0, units="1 / (MG * HR)", note="Arsenite oxidation rate coefficient") + >>> Kb = msx.add_constant("Kb", 0.1, units="1 / HR", note="Monochloramine decay rate coefficient") + >>> K1 = msx.add_constant("K1", 5.0, units="M^3 / (UG * HR)", note="Arsenate adsorption coefficient") + >>> K2 = msx.add_constant("K2", 1.0, units="1 / HR", note="Arsenate desorption coefficient") + >>> Smax = msx.add_constant("Smax", 50.0, units="UG / M^2", note="Arsenate adsorption limit") + >>> Ks = msx.add_term(name="Ks", expression="K1/K2", note="Equil. adsorption coeff.") + >>> _ = msx.add_reaction( + ... species_name="AS3", reaction_type="pipes", dynamics_type="rate", expression="-Ka*AS3*NH2CL", note="Arsenite oxidation" + ... ) + >>> _ = msx.add_reaction( + ... "AS5", "pipes", "rate", "Ka*AS3*NH2CL - Av*(K1*(Smax-AS5s)*AS5 - K2*AS5s)", note="Arsenate production less adsorption" + ... ) + >>> _ = msx.add_reaction( + ... species_name="NH2CL", reaction_type="pipes", dynamics_type="rate", expression="-Kb*NH2CL", note="Monochloramine decay" + ... ) + >>> _ = msx.add_reaction("AS5s", "pipe", "equil", "Ks*Smax*AS5/(1+Ks*AS5) - AS5s", note="Arsenate adsorption") + >>> _ = msx.add_reaction( + ... species_name="AStot", reaction_type="pipes", dynamics_type="formula", expression="AS3 + AS5", note="Total arsenic" + ... ) + >>> _ = msx.add_reaction( + ... species_name="AS3", reaction_type="tank", dynamics_type="rate", expression="-Ka*AS3*NH2CL", note="Arsenite oxidation" + ... ) + >>> _ = msx.add_reaction( + ... species_name="AS5", reaction_type="tank", dynamics_type="rate", expression="Ka*AS3*NH2CL", note="Arsenate production" + ... ) + >>> _ = msx.add_reaction( + ... species_name="NH2CL", reaction_type="tank", dynamics_type="rate", expression="-Kb*NH2CL", note="Monochloramine decay" + ... ) + >>> _ = msx.add_reaction( + ... species_name="AStot", reaction_type="tanks", dynamics_type="formula", expression="AS3 + AS5", note="Total arsenic" + ... ) + >>> msx.options.area_units = "M2" + >>> msx.options.rate_units = "HR" + >>> msx.options.rtol = 0.001 + >>> msx.options.atol = 0.0001 + + +References +---------- + +.. [BWMS20] + J. B. Burkhardt, et al. (2020) + "Framework for Modeling Lead in Premise Plumbing Systems Using EPANET". + `Journal of Water Resources Planning and Management`. + **146** (12). https://doi.org/10.1061/(asce)wr.1943-5452.0001304. PMID:33627937. + +.. [GSCL94] + B. Gu, J. Schmitt, Z. Chen, L. Liang, and J.F. McCarthy. "Adsorption and desorption of + natural organic matter on iron oxide: mechanisms and models". Environ. Sci. Technol., 28:38-46, January 1994. diff --git a/documentation/apidoc/wntr.quality.io.rst b/documentation/apidoc/wntr.quality.io.rst deleted file mode 100644 index 117eedad9..000000000 --- a/documentation/apidoc/wntr.quality.io.rst +++ /dev/null @@ -1,7 +0,0 @@ -wntr.quality.io module -====================== - -.. automodule:: wntr.quality.io - :members: - :undoc-members: - :show-inheritance: diff --git a/documentation/apidoc/wntr.quality.rst b/documentation/apidoc/wntr.quality.rst index db0dbbb19..01d0bdb23 100644 --- a/documentation/apidoc/wntr.quality.rst +++ b/documentation/apidoc/wntr.quality.rst @@ -14,7 +14,6 @@ Submodules :maxdepth: 1 wntr.quality.base - wntr.quality.io wntr.quality.library wntr.quality.multispecies wntr.quality.options diff --git a/documentation/apidoc/wntr.utils.citations.rst b/documentation/apidoc/wntr.utils.citations.rst deleted file mode 100644 index c7de4e437..000000000 --- a/documentation/apidoc/wntr.utils.citations.rst +++ /dev/null @@ -1,7 +0,0 @@ -wntr.utils.citations module -=========================== - -.. automodule:: wntr.utils.citations - :members: - :no-undoc-members: - :show-inheritance: diff --git a/documentation/apidoc/wntr.utils.rst b/documentation/apidoc/wntr.utils.rst index 14eef2793..f66334b01 100644 --- a/documentation/apidoc/wntr.utils.rst +++ b/documentation/apidoc/wntr.utils.rst @@ -12,7 +12,6 @@ Submodules .. toctree:: - wntr.utils.citations wntr.utils.disjoint_mapping wntr.utils.enumtools wntr.utils.logger diff --git a/documentation/conf.py b/documentation/conf.py index ae2d52802..6520b0233 100644 --- a/documentation/conf.py +++ b/documentation/conf.py @@ -129,7 +129,7 @@ # If true, `todo` and `todoList` produce output, else they produce nothing. todo_include_todos = True - +html_extra_path = ['extra'] # -- Options for HTML output ---------------------------------------------- diff --git a/documentation/index.rst b/documentation/index.rst index 5ef2fdd51..f7d9e1c42 100644 --- a/documentation/index.rst +++ b/documentation/index.rst @@ -30,6 +30,7 @@ designed to simulate and analyze resilience of water distribution networks. graphics gis advancedsim + advancedqual license whatsnew developers diff --git a/documentation/reference.rst b/documentation/reference.rst index 15f12a23d..6d74bce38 100644 --- a/documentation/reference.rst +++ b/documentation/reference.rst @@ -58,6 +58,8 @@ References .. [SPHC16] Sievert, C., Parmer, C., Hocking, T., Chamberlain, S., Ram, K., Corvellec, M., and Despouy, P. (2016). plotly: Create interactive web graphics via Plotly’s JavaScript graphing library [Software]. +.. [SRU23] Shang, F., Rossman, L. A., Uber, J.G. (2023). EPANET-MSX 2.0 User Manual. U.S. Environmental Protection Agency, Cincinnati, OH. EPA/600/R-22/199. + .. [Todi00] Todini, E. (2000). Looped water distribution networks design using a resilience index based heuristic approach. Urban Water, 2(2), 115-122. .. [USEPA14] United States Environmental Protection Agency. (2014). Systems Measures of Water Distribution System Resilience. Washington DC: U.S. Environmental Protection Agency. U.S. Environmental Protection Agency Technical Report, EPA 600/R--14/383, 58p. diff --git a/wntr/epanet/__init__.py b/wntr/epanet/__init__.py index bcab06872..daea1f9c1 100644 --- a/wntr/epanet/__init__.py +++ b/wntr/epanet/__init__.py @@ -3,3 +3,6 @@ """ from .io import InpFile #, BinFile, HydFile, RptFile from .util import FlowUnits, MassUnits, HydParam, QualParam, EN +import wntr.epanet.toolkit as toolkit +import wntr.epanet.exceptions as exceptions +import wntr.epanet.msx as msx \ No newline at end of file diff --git a/wntr/epanet/exceptions.py b/wntr/epanet/exceptions.py index 68a2c3e6d..ede847c16 100644 --- a/wntr/epanet/exceptions.py +++ b/wntr/epanet/exceptions.py @@ -1,18 +1,15 @@ # coding: utf-8 """Exceptions for EPANET toolkit and IO operations.""" -from enum import IntEnum from typing import List -from wntr.utils.enumtools import add_get - EN_ERROR_CODES = { # Runtime errors 1: "At %s, system hydraulically unbalanced - convergence to a hydraulic solution was not achieved in the allowed number of trials", 2: "At %s, system may be hydraulically unstable - hydraulic convergence was only achieved after the status of all links was held fixed", 3: "At %s, system disconnected - one or more nodes with positive demands were disconnected for all supply sources", 4: "At %s, pumps cannot deliver enough flow or head - one or more pumps were forced to either shut down (due to insufficient head) or operate beyond the maximum rated flow", - 5: "At %s, vavles cannot deliver enough flow - one or more flow control valves could not deliver the required flow even when fully open", + 5: "At %s, valves cannot deliver enough flow - one or more flow control valves could not deliver the required flow even when fully open", 6: "At %s, system has negative pressures - negative pressures occurred at one or more junctions with positive demand", 101: "insufficient memory available", 102: "no network data available", @@ -85,157 +82,133 @@ 309: "cannot save results to report file %s", } """A dictionary of the error codes and their meanings from the EPANET toolkit. -See :class:`EpanetErrorEnum` for the documentation of each code number. + +.. table:: EPANET warnings + + =========== ============================================================================================================================================================================== + *Err No.* *Description* + ----------- ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ + **1-6** **Simulation warnings** + ----------- ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ + 1 At `time`, system hydraulically unbalanced - convergence to a hydraulic solution was not achieved in the allowed number of trials + 2 At `time`, system may be hydraulically unstable - hydraulic convergence was only achieved after the status of all links was held fixed + 3 At `time`, system disconnected - one or more nodes with positive demands were disconnected for all supply sources + 4 At `time`, pumps cannot deliver enough flow or head - one or more pumps were forced to either shut down (due to insufficient head) or operate beyond the maximum rated flow + 5 At `time`, valves cannot deliver enough flow - one or more flow control valves could not deliver the required flow even when fully open + 6 At `time`, system has negative pressures - negative pressures occurred at one or more junctions with positive demand + =========== ============================================================================================================================================================================== + +.. table:: EPANET runtime errors + + =========== ================================================================= + *Err No.* *Description* + ----------- ----------------------------------------------------------------- + **101-120** **Runtime and simulation errors** + ----------- ----------------------------------------------------------------- + 101 insufficient memory available + 102 no network data available + 103 hydraulics not initialized + 104 no hydraulics for water quality analysis + 105 water quality not initialized + 106 no results saved to report on + 107 hydraulics supplied from external file + 108 cannot use external file while hydraulics solver is active + 109 cannot change time parameter when solver is active + 110 cannot solve network hydraulic equations + 120 cannot solve water quality transport equations + =========== ================================================================= + +.. table:: EPANET network errors + + =========== ================================================================= + *Err No.* *Description* + ----------- ----------------------------------------------------------------- + **200-201** **Input file errors (exclusively for input files)** + ----------- ----------------------------------------------------------------- + 200 one or more errors in input file + 201 syntax error + ----------- ----------------------------------------------------------------- + **202-222** **Input file and toolkit errors** + ----------- ----------------------------------------------------------------- + 202 illegal numeric value + 203 undefined node + 204 undefined link + 205 undefined time pattern + 206 undefined curve + 207 attempt to control a CV/GPV link + 208 illegal PDA pressure limits + 209 illegal node property value + 211 illegal link property value + 212 undefined trace node + 213 invalid option value + 214 too many characters in input line + 215 duplicate ID label + 216 reference to undefined pump + 217 pump has no head curve or power defined + 218 `note: error number 218 is undefined in the EPANET 2.2 toolkit` + 219 illegal valve connection to tank node + 220 illegal valve connection to another valve + 221 misplaced rule clause in rule-based control + 222 link assigned same start and end nodes + ----------- ----------------------------------------------------------------- + **223-234** **Network consistency errors (INP-file and/or toolkit)** + ----------- ----------------------------------------------------------------- + 223 not enough nodes in network + 224 no tanks or reservoirs in network + 225 invalid lower/upper levels for tank + 226 no head curve or power rating for pump + 227 invalid head curve for pump + 230 nonincreasing x-values for curve + 233 network has unconnected node + 234 network has an unconnected node with ID `id` + ----------- ----------------------------------------------------------------- + **240-263** **Toolkit-only errors** + ----------- ----------------------------------------------------------------- + 240 nonexistent water quality source + 241 nonexistent control + 250 invalid format (e.g. too long an ID name) + 251 invalid parameter code + 252 invalid ID name + 253 nonexistent demand category + 254 node with no coordinates + 255 invalid link vertex + 257 nonexistent rule + 258 nonexistent rule clause + 259 attempt to delete a node that still has links connected to it + 260 attempt to delete node assigned as a Trace Node + 261 attempt to delete a node or link contained in a control + 262 attempt to modify network structure while a solver is open + 263 node is not a tank + =========== ================================================================= + +.. table:: EPANET file/system errors + + =========== ================================================================= + *Err No.* *Description* + ----------- ----------------------------------------------------------------- + **301-305** **Filename errors** + ----------- ----------------------------------------------------------------- + 301 identical file names used for different types of files + 302 cannot open input file + 303 cannot open report file + 304 cannot open binary output file + 305 cannot open hydraulics file + ----------- ----------------------------------------------------------------- + **306-307** **File structure errors** + ----------- ----------------------------------------------------------------- + 306 hydraulics file does not match network data + 307 cannot read hydraulics file + ----------- ----------------------------------------------------------------- + **308-309** **Filesystem errors** + ----------- ----------------------------------------------------------------- + 308 cannot save results to binary file + 309 cannot save results to report file + =========== ================================================================= + :meta hide-value: """ -@add_get(prefix='ERR_') -class EpanetErrorEnum(IntEnum): - """A list of short phrases that can be used in place of the error code numbers.""" - WARN_UNBALANCED = 1 - """system hydraulically unbalanced - convergence to a hydraulic solution was not achieved in the allowed number of trials""" - WARN_UNSTABLE = 2 - """system may be hydraulically unstable - hydraulic convergence was only achieved after the status of all links was held fixed""" - WARN_DISCONNECTED = 3 - """system disconnected - one or more nodes with positive demands were disconnected for all supply sources""" - WARN_PUMPS = 4 - """pumps cannot deliver enough flow or head - one or more pumps were forced to either shut down (due to insufficient head) or operate beyond the maximum rated flow""" - WARN_VALVES = 5 - """vavles cannot deliver enough flow - one or more flow control valves could not deliver the required flow even when fully open""" - WARN_PRESSURES = 6 - """system has negative pressures - negative pressures occurred at one or more junctions with positive demand""" - INSUFFICIENT_MEMORY = 101 - """insufficient memory available""" - NO_NETWORK = 102 - """no network data available""" - INIT_HYD = 103 - """hydraulics not initialized""" - NO_HYD = 104 - """no hydraulics for water quality analysis""" - NO_INITQ = 105 - """water quality not initialized""" - NO_RESULTS = 106 - """no results saved to report on""" - HYD_FILE = 107 - """hydraulics supplied from external file""" - HYD_INIT_FILE = 108 - """cannot use external file while hydraulics solver is active""" - MODIFY_TIME = 109 - """cannot change time parameter when solver is active""" - SOLVE_HYD = 110 - """cannot solve network hydraulic equations""" - SOLVE_QUAL = 120 - """cannot solve water quality transport equations""" - INPUT_FILE = 200 - """one or more errors in input file""" - SYNTAX_ERROR = 201 - """syntax error""" - ILLEGAL_NUMBER = 202 - """illegal numeric value""" - UNDEFINED_NODE = 203 - """undefined node""" - UNDEFINED_LINK = 204 - """undefined link""" - UNDEFINED_PATTERN = 205 - """undefined time pattern""" - UNDEFINED_CURVE = 206 - """undefined curve""" - CV_GPV_CONTROL = 207 - """attempt to control a CV/GPV link""" - ILLEGAL_PDA_LIMITS = 208 - """illegal PDA pressure limits""" - ILLEGAL_NODE_PROPERTY = 209 - """illegal node property value""" - ILLEGAL_LINK_PROPERTY = 211 - """illegal link property value""" - UNDEFINED_TRACE = 212 - """undefined trace node""" - INVALID_OPTION_VALUE = 213 - """invalid option value""" - TOO_MANY_CHARS = 214 - """too many characters in input line""" - DUPLICATE_ID = 215 - """duplicate ID label""" - UNDEFINED_PUMP = 216 - """reference to undefined pump""" - INVALID_ENERGY = 217 - """pump has no head curve or power defined""" - ILLEGAL_VALVE_TANK = 219 - """illegal valve connection to tank node""" - ILLEGAL_TANK_VALVE = 219 - """illegal valve connection to tank node""" - ILLEGAL_VALVE_VALVE = 220 - """illegal valve connection to another valve""" - MISPLACED_RULE = 221 - """misplaced rule clause in rule-based control""" - SAME_START_END = 222 - """link assigned same start and end nodes""" - NUM_NODES = 223 - """not enough nodes in network""" - NO_TANKS = 224 - """no tanks or reservoirs in network""" - INVALID_TANK_LEVELS = 225 - """invalid lower/upper levels for tank""" - MISSING_PUMP_OPTION = 226 - """no head curve or power rating for pump""" - INVALID_HEAD_CURVE = 227 - """invalid head curve for pump""" - CURVE_X_NONINCREASING = 230 - """nonincreasing x-values for curve""" - UNCONNECTED_NODE = 233 - """network has unconnected node""" - UNCONNECTED_NODE_ID = 234 - """network has an unconnected node with ID""" - NONEXISTENT_SOURCE = 240 - """nonexistent water quality source""" - NONEXISTENT_CONTROL = 241 - """nonexistent control""" - INVLAID_NAME_FORMAT = 250 - """invalid format (e.g. too long an ID name)""" - INVALID_PARAMETER = 251 - """invalid parameter code""" - INVALID_ID = 252 - """invalid ID name""" - NONEXISTENT_CATEGORY = 253 - """nonexistent demand category""" - MISSING_COORDS = 254 - """node with no coordinates""" - INVALID_VERTEX = 255 - """invalid link vertex""" - NONEXISTENT_RULE = 257 - """nonexistent rule""" - NONEXISTENT_RULE_CLAUSE = 258 - """nonexistent rule clause""" - NODE_STILL_LINKED = 259 - """attempt to delete a node that still has links connected to it""" - NODE_IS_TRACE = 260 - """attempt to delete node assigned as a Trace Node""" - NODE_IN_CONTROL = 261 - """attempt to delete a node or link contained in a control""" - MODIFY_NETWORK = 262 - """attempt to modify network structure while a solver is open""" - NOT_A_TANK = 263 - """node is not a tank""" - SAME_FILENAMES = 301 - """identical file names used for different types of files""" - OPEN_INP_FILE = 302 - """cannot open input file""" - OPEN_RPT_FILE = 303 - """cannot open report file""" - OPEN_BIN_FILE = 304 - """cannot open binary output file""" - OPEN_HYD_FILE = 305 - """cannot open hydraulics file""" - WRONG_HYD_FILE = 306 - """hydraulics file does not match network data""" - READ_HYDRAULICS = 307 - """cannot read hydraulics file""" - SAVE_HYDRAULICS = 308 - """cannot save results to binary file""" - SAVE_REPORT = 309 - """cannot save results to report file""" - class EpanetException(Exception): @@ -244,8 +217,8 @@ def __init__(self, code: int, *args: List[object], line_num=None, line=None) -> Parameters ---------- - code : int or str or EpanetErrors - The EPANET error code (int) or a string mapping to the EpanetErrors enum members + code : int + The EPANET error code args : additional non-keyword arguments, optional If there is a string-format within the error code's text, these will be used to replace the format, otherwise they will be output at the end of the Exception message. @@ -254,10 +227,6 @@ def __init__(self, code: int, *args: List[object], line_num=None, line=None) -> line : str, optional The contents of the line, by default None """ - try: - code = int(EpanetErrorEnum.get(code)) - except KeyError: - return super().__init__('unknown error code: {}'.format(repr(code)), *args) msg = EN_ERROR_CODES.get(code, 'unknown error') if args is not None: args = [*args] @@ -278,8 +247,8 @@ def __init__(self, code, *args, line_num=None, line=None) -> None: Parameters ---------- - code : int or str or EpanetErrors - The EPANET error code (int) or a string mapping to the EpanetErrors enum members + code : int + The EPANET error code args : additional non-keyword arguments, optional If there is a string-format within the error code's text, these will be used to replace the format, otherwise they will be output at the end of the Exception message. @@ -296,8 +265,8 @@ def __init__(self, code, name, *args, line_num=None, line=None) -> None: Parameters ---------- - code : int or str or EpanetErrors - The EPANET error code (int) or a string mapping to the EpanetErrors enum members + code : int + The EPANET error code name : str The key/name/id that is missing args : additional non-keyword arguments, optional @@ -317,8 +286,8 @@ def __init__(self, code, value, *args, line_num=None, line=None) -> None: Parameters ---------- - code : int or str or EpanetErrors - The EPANET error code (int) or a string mapping to the EpanetErrors enum members + code : int + The EPANET error code value : Any The value that is invalid args : additional non-keyword arguments, optional diff --git a/wntr/epanet/io.py b/wntr/epanet/io.py index 49132efda..1769191de 100644 --- a/wntr/epanet/io.py +++ b/wntr/epanet/io.py @@ -1,5 +1,13 @@ """ The wntr.epanet.io module contains methods for reading/writing EPANET input and output files. + +.. rubric:: Contents + +.. autosummary:: + + InpFile + BinFile + """ from __future__ import absolute_import @@ -140,7 +148,7 @@ def _str_time_to_sec(s): if bool(time_tuple): return int(time_tuple.groups()[0])*60*60 else: - raise ENValueError('invalid-option-value', s) + raise ENValueError(213, s) def _clock_time_to_sec(s, am_pm): @@ -168,7 +176,7 @@ def _clock_time_to_sec(s, am_pm): elif am_pm.upper() == 'PM': am = False else: - raise ENValueError('invalid-option-value', s, 'Ambiguous time of day') + raise ENValueError(213, s, 'Ambiguous time of day') pattern1 = re.compile(r'^(\d+):(\d+):(\d+)$') time_tuple = pattern1.search(s) @@ -180,7 +188,7 @@ def _clock_time_to_sec(s, am_pm): time_sec -= 3600*12 if not am: if time_sec >= 3600*12: - raise ENValueError('invalid-option-value', s, 'Cannot specify am/pm for times greater than 12:00:00') + raise ENValueError(213, s, 'Cannot specify am/pm for times greater than 12:00:00') time_sec += 3600*12 return time_sec else: @@ -193,7 +201,7 @@ def _clock_time_to_sec(s, am_pm): time_sec -= 3600*12 if not am: if time_sec >= 3600 * 12: - raise ENValueError('invalid-option-value', s, 'Cannot specify am/pm for times greater than 12:00:00') + raise ENValueError(213, s, 'Cannot specify am/pm for times greater than 12:00:00') time_sec += 3600*12 return time_sec else: @@ -205,11 +213,11 @@ def _clock_time_to_sec(s, am_pm): time_sec -= 3600*12 if not am: if time_sec >= 3600 * 12: - raise ENValueError('invalid-option-value', s, 'Cannot specify am/pm for times greater than 12:00:00') + raise ENValueError(213, s, 'Cannot specify am/pm for times greater than 12:00:00') time_sec += 3600*12 return time_sec else: - raise ENValueError('invalid-option-value', s, 'Cannot parse time') + raise ENValueError(213, s, 'Cannot parse time') def _sec_to_string(sec): diff --git a/wntr/epanet/msx/__init__.py b/wntr/epanet/msx/__init__.py index 37d0a4a2d..4144ddbcc 100644 --- a/wntr/epanet/msx/__init__.py +++ b/wntr/epanet/msx/__init__.py @@ -1,3 +1,4 @@ """The wntr.epanet.msx package provides EPANET-MSX compatibility functions for WNTR. """ -from .io import MsxFile +from .io import MsxFile, MsxBinFile +from .toolkit import MSXepanet \ No newline at end of file diff --git a/wntr/epanet/msx/io.py b/wntr/epanet/msx/io.py index 0f25ab925..1bf2d78a9 100644 --- a/wntr/epanet/msx/io.py +++ b/wntr/epanet/msx/io.py @@ -4,18 +4,17 @@ import datetime import logging import sys -from io import FileIO, TextIOWrapper +from typing import Union import numpy as np import pandas as pd import wntr.network -from wntr.epanet.msx.exceptions import EpanetMsxException +from wntr.epanet.msx.exceptions import EpanetMsxException, MSXValueError from wntr.epanet.util import ENcomment from wntr.network.elements import Source -from wntr.quality.base import LocationType, VariableType -from wntr.quality.multispecies import MultispeciesQualityModel, Parameter, Species -from wntr.utils.citations import Citation +from wntr.quality.base import ReactionType, QualityVarType, SpeciesType +from wntr.quality.multispecies import Constant, MultispeciesQualityModel, Parameter, Species, Term sys_default_enc = sys.getdefaultencoding() @@ -37,7 +36,6 @@ "[DIFFUSIVITY]", "[PATTERNS]", "[REPORT]", - "[END]", ] @@ -101,7 +99,7 @@ def read(cls, msx_filename: str, rxn_model: MultispeciesQualityModel = None): obj.rxn = rxn_model # if not isinstance(msx_file, list): # msx_file = [msx_file] - rxn_model.filename = msx_filename + rxn_model._orig_file = msx_filename obj.patterns = dict() obj.top_comments = [] @@ -170,7 +168,6 @@ def _read(): obj._read_diffusivity() obj._read_patterns() obj._read_report() - obj._read_end() return obj.rxn except Exception as e: raise EpanetMsxException(200) from e @@ -189,7 +186,6 @@ def write(cls, filename: str, msx: MultispeciesQualityModel): obj = cls() obj.rxn = msx with open(filename, "w") as fout: - fout.write("; WNTR-reactions MSX file generated {}\n".format(datetime.datetime.now())) fout.write("\n") obj._write_title(fout) @@ -205,17 +201,8 @@ def write(cls, filename: str, msx: MultispeciesQualityModel): obj._write_parameters(fout) obj._write_patterns(fout) obj._write_report(fout) - obj._write_end(fout) fout.write("; END of MSX file generated by WNTR\n") - def _read_end(self): - pass - - def _write_end(self, fout): - fout.write("[END]\n") - pass - - def _read_title(self): lines = [] title = None @@ -234,8 +221,6 @@ def _read_title(self): self.rxn.desc = comments def _read_options(self): - lines = [] - note = ENcomment() for lnum, line in self.sections["[OPTIONS]"]: vals, comment = _split_line(line) try: @@ -272,7 +257,6 @@ def _read_options(self): raise EpanetMsxException(201, note="at line {} of [OPTIONS] section:\n{}".format(lnum, line)) from e def _read_species(self): - lines = [] note = ENcomment() for lnum, line in self.sections["[SPECIES]"]: vals, comment = _split_line(line) @@ -285,10 +269,14 @@ def _read_species(self): note.post = comment if len(vals) < 3: raise EpanetMsxException(402, note="at line {} of [SPECIES] section:\n{}".format(lnum, line)) + try: + typ = SpeciesType.get(vals[0], allow_none=False) + except ValueError as e: + raise MSXValueError(403, vals[0], note="at line {} of [SPECIES] section:\n{}".format(lnum, line)) from e if len(vals) == 3: - species = self.rxn.add_species(vals[0], vals[1], vals[2], note=note) + self.rxn.add_species(vals[1], typ, vals[2], note=note) elif len(vals) == 5: - species = self.rxn.add_species(vals[0], vals[1], vals[2], float(vals[3]), float(vals[4]), note=note) + self.rxn.add_species(vals[1], typ, vals[2], float(vals[3]), float(vals[4]), note=note) else: raise EpanetMsxException(201, note="at line {} of [SPECIES] section:\n{}".format(lnum, line)) except EpanetMsxException: @@ -299,7 +287,6 @@ def _read_species(self): note = ENcomment() def _read_coefficients(self): - lines = [] note = ENcomment() for lnum, line in self.sections["[COEFFICIENTS]"]: vals, comment = _split_line(line) @@ -312,7 +299,13 @@ def _read_coefficients(self): note.post = comment if len(vals) < 3: raise EpanetMsxException(402, note="at line {} of [COEFFICIENTS] section:\n{}".format(lnum, line)) - coeff = self.rxn.add_coefficient(vals[0], vals[1], float(vals[2]), note=note) + typ = QualityVarType.get(vals[0], allow_none=False) + if typ is QualityVarType.CONSTANT: + self.rxn.add_constant(vals[1], float(vals[2]), note=note) + elif typ is QualityVarType.PARAMETER: + self.rxn.add_parameter(vals[1], float(vals[2]), note=note) + else: + raise MSXValueError(403, vals[0], note="at line {} of [COEFFICIENTS] section:\n{}".format(lnum, line)) except EpanetMsxException: raise except Exception as e: @@ -321,7 +314,6 @@ def _read_coefficients(self): note = ENcomment() def _read_terms(self): - lines = [] note = ENcomment() for lnum, line in self.sections["[TERMS]"]: vals, comment = _split_line(line) @@ -334,7 +326,7 @@ def _read_terms(self): note.post = comment if len(vals) < 2: raise SyntaxError("Invalid [TERMS] entry") - term = self.rxn.add_other_term(vals[0], " ".join(vals[1:]), note=note) + self.rxn.add_term(vals[0], " ".join(vals[1:]), note=note) except EpanetMsxException: raise except Exception as e: @@ -343,7 +335,6 @@ def _read_terms(self): note = ENcomment() def _read_pipes(self): - lines = [] note = ENcomment() for lnum, line in self.sections["[PIPES]"]: vals, comment = _split_line(line) @@ -356,7 +347,7 @@ def _read_pipes(self): note.post = comment if len(vals) < 3: raise SyntaxError("Invalid [PIPES] entry") - reaction = self.rxn.add_pipe_reaction(vals[1], vals[0], " ".join(vals[2:]), note=note) + reaction = self.rxn.add_reaction(vals[1], "pipe", vals[0], " ".join(vals[2:]), note=note) except EpanetMsxException: raise except Exception as e: @@ -365,7 +356,6 @@ def _read_pipes(self): note = ENcomment() def _read_tanks(self): - lines = [] note = ENcomment() for lnum, line in self.sections["[TANKS]"]: vals, comment = _split_line(line) @@ -378,7 +368,7 @@ def _read_tanks(self): note.post = comment if len(vals) < 3: raise SyntaxError("Invalid [TANKS] entry") - reaction = self.rxn.add_tank_reaction(vals[1], vals[0], " ".join(vals[2:]), note=note) + self.rxn.add_reaction(vals[1], "tank", vals[0], " ".join(vals[2:]), note=note) except EpanetMsxException: raise except Exception as e: @@ -387,7 +377,6 @@ def _read_tanks(self): note = ENcomment() def _read_source_dict(self): - lines = [] note = ENcomment() for lnum, line in self.sections["[SOURCES]"]: vals, comment = _split_line(line) @@ -403,12 +392,12 @@ def _read_source_dict(self): pat = None else: typ, node, spec, strength, pat = vals - if not self.rxn.has_variable(spec): + if spec not in self.rxn.reaction_system: raise ValueError("Undefined species in [SOURCES] section: {}".format(spec)) - if spec not in self.rxn._source_dict.keys(): - self.rxn._source_dict[spec] = dict() + if spec not in self.rxn.network_data.sources.keys(): + self.rxn.network_data.sources[spec] = dict() source = dict(source_type=typ, strength=strength, pattern=pat, note=note) - self.rxn._source_dict[spec][node] = source + self.rxn.network_data.sources[spec][node] = source except EpanetMsxException: raise except Exception as e: @@ -417,7 +406,6 @@ def _read_source_dict(self): note = ENcomment() def _read_quality(self): - lines = [] note = ENcomment() for lnum, line in self.sections["[QUALITY]"]: vals, comment = _split_line(line) @@ -434,16 +422,20 @@ def _read_quality(self): cmd, spec, concen = vals if cmd[0].lower() not in ["g", "n", "l"]: raise SyntaxError("Unknown first word in [QUALITY] section") - if not self.rxn.has_variable(spec): + if spec not in self.rxn.reaction_system.species: raise ValueError("Undefined species in [QUALITY] section: {}".format(spec)) - if spec not in self.rxn._inital_qual_dict.keys(): - self.rxn._inital_qual_dict[spec] = dict(global_value=None, nodes=dict(), links=dict()) + # FIXME: check for existence + # if spec not in self.rxn.net.initial_quality: + # self.rxn.net.new_quality_values(spec) + # self.rxn._inital_qual_dict[spec]["global"] = None + # self.rxn._inital_qual_dict[spec]["nodes"] = dict() + # self.rxn._inital_qual_dict[spec]["links"] = dict() if cmd[0].lower() == "g": - self.rxn._species[spec].initial_quality = float(concen) + self.rxn.network_data.initial_quality[spec].global_value = float(concen) elif cmd[0].lower() == "n": - self.rxn._inital_qual_dict[spec]["nodes"][netid] = float(concen) + self.rxn.network_data.initial_quality[spec].node_values[netid] = float(concen) elif cmd[1].lower() == "l": - self.rxn._inital_qual_dict[spec]["links"][netid] = float(concen) + self.rxn.network_data.initial_quality[spec].link_values[netid] = float(concen) except EpanetMsxException: raise except Exception as e: @@ -452,7 +444,6 @@ def _read_quality(self): note = ENcomment() def _read_parameters(self): - lines = [] note = ENcomment() for lnum, line in self.sections["[PARAMETERS]"]: vals, comment = _split_line(line) @@ -464,14 +455,13 @@ def _read_parameters(self): if comment is not None: note.post = comment typ, netid, paramid, value = vals - coeff = self.rxn.get_variable(paramid) - if not isinstance(coeff, Parameter): + if paramid not in self.rxn.reaction_system.parameters: raise ValueError("Invalid parameter {}".format(paramid)) value = float(value) if typ.lower()[0] == "p": - coeff.pipe_values[netid] = value + self.rxn.network_data.parameter_values[paramid].pipe_values[netid] = value elif typ.lower()[0] == "t": - coeff.tank_values[netid] = value + self.rxn.network_data.parameter_values[paramid].tank_values[netid] = value else: raise ValueError("Invalid parameter type {}".format(typ)) except EpanetMsxException: @@ -482,7 +472,6 @@ def _read_parameters(self): note = ENcomment() def _read_diffusivity(self): - lines = [] note = ENcomment() for lnum, line in self.sections["[DIFFUSIVITY]"]: vals, comment = _split_line(line) @@ -495,9 +484,7 @@ def _read_diffusivity(self): note.post = comment if len(vals) != 2: raise SyntaxError("Invalid [DIFFUSIVITIES] entry") - species = self.rxn.get_variable(vals[0]) - if not isinstance(species, Species): - raise RuntimeError("Invalid species {} in diffusivity".format(vals[0])) + species = self.rxn.reaction_system.species[vals[0]] species.diffusivity = float(vals[1]) except EpanetMsxException: raise @@ -524,10 +511,9 @@ def _read_patterns(self): _patterns[pattern_name].append(float(i)) for pattern_name, pattern in _patterns.items(): # add the patterns to the water newtork model - self.rxn.add_pattern(pattern_name, pattern) + self.rxn.network_data.add_pattern(pattern_name, pattern) def _read_report(self): - lines = [] note = ENcomment() for lnum, line in self.sections["[REPORT]"]: vals, comment = _split_line(line) @@ -572,7 +558,7 @@ def _read_report(self): elif cmd == "p": self.rxn._options.report.pagesize = vals[1] elif cmd == "s": - if not self.rxn.has_variable(vals[1]): + if vals[1] not in self.rxn.reaction_system.species: raise ValueError("Undefined species in [REPORT] section: {}".format(vals[1])) self.rxn._options.report.species[vals[1]] = True if vals[2].lower().startswith("y") else False if len(vals) == 4: @@ -609,27 +595,20 @@ def _write_options(self, fout): def _write_species(self, fout): fout.write("[SPECIES]\n") - def to_msx_string(self) -> str: - tols = self.get_tolerances() + def to_msx_string(spec: Species) -> str: + tols = spec.get_tolerances() if tols is None: tolstr = "" else: tolstr = " {:12.6g} {:12.6g}".format(*tols) return "{:<12s} {:<8s} {:<8s}{:s}".format( - self.var_type.name.upper(), - self.name, - self.units, + spec.species_type.name.upper(), + spec.name, + spec.units, tolstr, ) - for var in self.rxn.variables(var_type=VariableType.BULK): - if isinstance(var.note, ENcomment): - fout.write("{}\n".format(var.note.wrap_msx_string(to_msx_string(var)))) - elif isinstance(var.note, str): - fout.write(" {} ; {}\n".format(to_msx_string(var), var.note)) - else: - fout.write(" {}\n".format(to_msx_string(var))) - for var in self.rxn.variables(var_type=VariableType.WALL): + for var in self.rxn.reaction_system.species.values(): if isinstance(var.note, ENcomment): fout.write("{}\n".format(var.note.wrap_msx_string(to_msx_string(var)))) elif isinstance(var.note, str): @@ -641,21 +620,26 @@ def to_msx_string(self) -> str: def _write_coefficients(self, fout): fout.write("[COEFFICIENTS]\n") - def to_msx_string(self) -> str: + def to_msx_string(coeff: Union[Constant, Parameter]) -> str: # if self.units is not None: # post = r' ; {"units"="' + str(self.units) + r'"}' # else: post = "" - return "{:<12s} {:<8s} {:<16s}{}".format(self.var_type.name.upper(), self.name, str(self.global_value), post) + return "{:<12s} {:<8s} {:<16s}{}".format( + coeff.var_type.name.upper(), + coeff.name, + str(coeff.global_value if isinstance(coeff, Parameter) else coeff.value), + post, + ) - for var in self.rxn.variables(var_type=VariableType.CONST): + for var in self.rxn.reaction_system.constants.values(): if isinstance(var.note, ENcomment): fout.write("{}\n".format(var.note.wrap_msx_string(to_msx_string(var)))) elif isinstance(var.note, str): fout.write(" {} ; {}\n".format(to_msx_string(var), var.note)) else: fout.write(" {}\n".format(to_msx_string(var))) - for var in self.rxn.variables(var_type=VariableType.PARAM): + for var in self.rxn.reaction_system.parameters.values(): if isinstance(var.note, ENcomment): fout.write("{}\n".format(var.note.wrap_msx_string(to_msx_string(var)))) elif isinstance(var.note, str): @@ -667,10 +651,10 @@ def to_msx_string(self) -> str: def _write_terms(self, fout): fout.write("[TERMS]\n") - def to_msx_string(self) -> str: - return "{:<8s} {:<64s}".format(self.name, self.expression) + def to_msx_string(term: Term) -> str: + return "{:<8s} {:<64s}".format(term.name, term.expression) - for var in self.rxn.variables(var_type=VariableType.TERM): + for var in self.rxn.reaction_system.terms.values(): if isinstance(var.note, ENcomment): fout.write("{}\n".format(var.note.wrap_msx_string(to_msx_string(var)))) elif isinstance(var.note, str): @@ -681,45 +665,103 @@ def to_msx_string(self) -> str: def _write_pipes(self, fout): fout.write("[PIPES]\n") - for var in self.rxn.reactions(location=LocationType.PIPE): + for spec in self.rxn.reaction_system.species.values(): + var = spec.pipe_reaction + if var is None: + raise MSXValueError(507, note=" species {}".format(str(spec))) if isinstance(var.note, ENcomment): - fout.write("{}\n".format(var.note.wrap_msx_string("{:<12s} {:<8s} {:<32s}".format(var.expr_type.name.upper(), str(var.species), var.expression)))) + fout.write( + "{}\n".format( + var.note.wrap_msx_string( + "{:<12s} {:<8s} {:<32s}".format(var.dynamics_type.name.upper(), str(var.species_name), var.expression) + ) + ) + ) elif isinstance(var.note, str): - fout.write(" {} ; {}\n".format("{:<12s} {:<8s} {:<32s}".format(var.expr_type.name.upper(), str(var.species), var.expression), var.note)) + fout.write( + " {} ; {}\n".format( + "{:<12s} {:<8s} {:<32s}".format(var.dynamics_type.name.upper(), str(var.species_name), var.expression), + var.note, + ) + ) else: - fout.write(" {}\n".format("{:<12s} {:<8s} {:<32s}".format(var.expr_type.name.upper(), str(var.species), var.expression))) + fout.write( + " {}\n".format( + "{:<12s} {:<8s} {:<32s}".format(var.dynamics_type.name.upper(), str(var.species_name), var.expression) + ) + ) fout.write("\n") def _write_tanks(self, fout): fout.write("[TANKS]\n") - for var in self.rxn.reactions(location=LocationType.TANK): + for spec in self.rxn.reaction_system.species.values(): + if spec.species_type.name == 'WALL': + continue + try: + var = spec.tank_reaction + except KeyError: + logger.warn('Species {} does not have a tank reaction - this may be a problem'.format(str(spec))) + if var is None: + raise MSXValueError(508, note=" species {}".format(str(spec))) if isinstance(var.note, ENcomment): - fout.write("{}\n".format(var.note.wrap_msx_string("{:<12s} {:<8s} {:<32s}".format(var.expr_type.name.upper(), str(var.species), var.expression)))) + fout.write( + "{}\n".format( + var.note.wrap_msx_string( + "{:<12s} {:<8s} {:<32s}".format(var.dynamics_type.name.upper(), str(var.species_name), var.expression) + ) + ) + ) elif isinstance(var.note, str): - fout.write(" {} ; {}\n".format("{:<12s} {:<8s} {:<32s}".format(var.expr_type.name.upper(), str(var.species), var.expression), var.note)) + fout.write( + " {} ; {}\n".format( + "{:<12s} {:<8s} {:<32s}".format(var.dynamics_type.name.upper(), str(var.species_name), var.expression), + var.note, + ) + ) else: - fout.write(" {}\n".format("{:<12s} {:<8s} {:<32s}".format(var.expr_type.name.upper(), str(var.species), var.expression))) + fout.write( + " {}\n".format( + "{:<12s} {:<8s} {:<32s}".format(var.dynamics_type.name.upper(), str(var.species_name), var.expression) + ) + ) fout.write("\n") def _write_source_dict(self, fout): fout.write("[SOURCES]\n") - for species in self.rxn._source_dict.keys(): - for node, src in self.rxn._source_dict[species].items(): + for species in self.rxn.network_data.sources.keys(): + for node, src in self.rxn.network_data.sources[species].items(): if isinstance(src["note"], ENcomment): fout.write( src["note"].wrap_msx_string( - "{:<10s} {:<8s} {:<8s} {:12s} {:<12s}".format(src["source_type"], node, species, src["strength"], src["pattern"] if src["pattern"] is not None else "") + "{:<10s} {:<8s} {:<8s} {:12s} {:<12s}".format( + src["source_type"], + node, + species, + src["strength"], + src["pattern"] if src["pattern"] is not None else "", + ) ) ) elif isinstance(src["note"], str): fout.write( " {:<10s} {:<8s} {:<8s} {} {:<12s} ; {}\n".format( - src["source_type"], node, species, src["strength"], src["pattern"] if src["pattern"] is not None else "", src["note"] + src["source_type"], + node, + species, + src["strength"], + src["pattern"] if src["pattern"] is not None else "", + src["note"], ) ) else: fout.write( - " {:<10s} {:<8s} {:<8s} {} {:<12s}\n".format(src["source_type"], node, species, src["strength"], src["pattern"] if src["pattern"] is not None else "") + " {:<10s} {:<8s} {:<8s} {} {:<12s}\n".format( + src["source_type"], + node, + species, + src["strength"], + src["pattern"] if src["pattern"] is not None else "", + ) ) if src["note"] is not None: fout.write("\n") @@ -727,28 +769,23 @@ def _write_source_dict(self, fout): def _write_quality(self, fout): fout.write("[QUALITY]\n") - for spec, species in self.rxn._species.items(): - if species.initial_quality is not None: - fout.write(" {:<8s} {:<8s} {}\n".format("GLOBAL", species.name, species.initial_quality)) - for species in self.rxn._inital_qual_dict.keys(): - for typ, val in self.rxn._inital_qual_dict[species].items(): - if typ in ["nodes", "links"]: - for node, conc in val.items(): - fout.write(" {:<8s} {:<8s} {:<8s} {}\n".format(typ.upper()[0:4], node, species, conc)) + for species, val in self.rxn.network_data.initial_quality.items(): + for typ in ["node_values", "link_values"]: + for node, conc in getattr(val, typ).items(): + fout.write(" {:<8s} {:<8s} {:<8s} {}\n".format(typ.upper()[0:4], node, species, conc)) + if val.global_value: + fout.write(" {:<8s} {:<8s} {}\n".format("GLOBAL", species, val)) fout.write("\n") def _write_parameters(self, fout): fout.write("[PARAMETERS]\n") - for var in self.rxn.variables(var_type=VariableType.PARAM): + for name, var in self.rxn.network_data.parameter_values.items(): had_entries = False - if not isinstance(var, Parameter): - pass - paramID = var.name for pipeID, value in var.pipe_values.items(): - fout.write(" PIPE {:<8s} {:<8s} {}\n".format(pipeID, paramID, value)) + fout.write(" PIPE {:<8s} {:<8s} {}\n".format(pipeID, name, value)) had_entries = True for tankID, value in var.tank_values.items(): - fout.write(" PIPE {:<8s} {:<8s} {}\n".format(tankID, paramID, value)) + fout.write(" PIPE {:<8s} {:<8s} {}\n".format(tankID, name, value)) had_entries = True if had_entries: fout.write("\n") @@ -756,7 +793,7 @@ def _write_parameters(self, fout): def _write_patterns(self, fout): fout.write("[PATTERNS]\n") - for pattern_name, pattern in self.rxn._pattern_dict.items(): + for pattern_name, pattern in self.rxn.network_data.patterns.items(): num_columns = 10 count = 0 for i in pattern: # .multipliers: @@ -771,7 +808,7 @@ def _write_patterns(self, fout): def _write_diffusivity(self, fout): fout.write("[DIFFUSIVITY]\n") for name in self.rxn.species_name_list: - spec: Species = self.rxn.get_variable(name) + spec: Species = self.rxn.reaction_system.species[name] if spec.diffusivity is not None: fout.write(" {:<8s} {}\n".format(name, spec.diffusivity)) fout.write("\n") @@ -793,7 +830,9 @@ def _write_report(self, fout): " SPECIES {:<8s} {:<3s} {}\n".format( spec, "YES" if val else "NO", - self.rxn._options.report.species_precision[spec] if spec in self.rxn._options.report.species_precision.keys() else "", + self.rxn._options.report.species_precision[spec] + if spec in self.rxn._options.report.species_precision.keys() + else "", ) ) if self.rxn._options.report.report_filename: @@ -803,9 +842,11 @@ def _write_report(self, fout): fout.write("\n") -def MsxBinFile(filename, wn: wntr.network.WaterNetworkModel): +def MsxBinFile(filename, wn: wntr.network.WaterNetworkModel, res = None): duration = int(wn.options.time.duration) - + if res is None: + from wntr.sim.results import SimulationResults + res = SimulationResults() with open(filename, "rb") as fin: ftype = "=f4" idlen = 32 @@ -819,14 +860,17 @@ def MsxBinFile(filename, wn: wntr.network.WaterNetworkModel): species_list = [] node_list = wn.node_name_list link_list = wn.link_name_list + print(magic1, version, nnodes, nlinks, nspecies, reportstep) + species_mass = [] for i in range(nspecies): - species_len = int(np.fromfile(fin, dtype=np.int32, count=1)) + species_len = np.fromfile(fin, dtype=np.int32, count=1)[0] + print(species_len) species_name = "".join(chr(f) for f in np.fromfile(fin, dtype=np.uint8, count=species_len) if f != 0) + print(species_name) species_list.append(species_name) - species_mass = [] - for i in range(nspecies): species_mass.append("".join(chr(f) for f in np.fromfile(fin, dtype=np.uint8, count=16) if f != 0)) + timerange = range(0, duration + 1, reportstep) tr = len(timerange) @@ -867,4 +911,7 @@ def MsxBinFile(filename, wn: wntr.network.WaterNetworkModel): else: print("Magic#s do not match!") - return df_fin + for species in species_list: + res.node[species] = df_fin['node'][species] + res.link[species] = df_fin['link'][species] + return res diff --git a/wntr/epanet/msx/toolkit.py b/wntr/epanet/msx/toolkit.py index 599131aa3..69140c4f2 100644 --- a/wntr/epanet/msx/toolkit.py +++ b/wntr/epanet/msx/toolkit.py @@ -57,6 +57,7 @@ def __init__(self, inpfile="", rptfile="", binfile="", msxfile=""): self.inpfile = inpfile self.rptfile = rptfile self.binfile = binfile + self.msxfile = msxfile libnames = ["epanetmsx", "epanetmsx_win32"] if "64" in platform.machine(): @@ -97,7 +98,7 @@ def _error(self, *args): return # ----------running the simulation----------------------------------------------------- - def MSXopen(self, msxfile): + def MSXopen(self, msxfile=None): """Opens the MSX Toolkit to analyze a particular distribution system. Parameters @@ -105,6 +106,8 @@ def MSXopen(self, msxfile): msxfile : str name of the MSX input file """ + if msxfile is None: + msxfile = self.msxfile ierr = self.ENlib.MSXopen(ctypes.c_char_p(msxfile.encode())) if ierr != 0: raise EpanetMsxException(ierr, msxfile) diff --git a/wntr/epanet/toolkit.py b/wntr/epanet/toolkit.py index 38b1fd14d..21ffb67a5 100644 --- a/wntr/epanet/toolkit.py +++ b/wntr/epanet/toolkit.py @@ -1,6 +1,16 @@ """ The wntr.epanet.toolkit module is a Python extension for the EPANET Programmers Toolkit DLLs. + +.. rubric:: Contents + +.. autosummary:: + + runepanet + ENepanet + EpanetException + ENgetwarning + """ import ctypes import os diff --git a/wntr/epanet/util.py b/wntr/epanet/util.py index ae97a8f56..ab6038276 100644 --- a/wntr/epanet/util.py +++ b/wntr/epanet/util.py @@ -1,11 +1,11 @@ """ The wntr.epanet.util module contains unit conversion utilities based on EPANET units. """ -from dataclasses import dataclass, field +import dataclasses import enum import logging +from dataclasses import dataclass, field from typing import List - import numpy as np import pandas as pd @@ -1400,3 +1400,6 @@ def wrap_msx_string(self, string) -> str: return '\n; ' + '\n\n; '.join(self.pre) + '\n\n ' + string else: return '\n; ' + '\n\n; '.join(self.pre) + '\n\n ' + string + ' ; ' + self.post + + def to_dict(self): + return dataclasses.asdict(self) \ No newline at end of file diff --git a/wntr/network/io.py b/wntr/network/io.py index bde165583..289e30d16 100644 --- a/wntr/network/io.py +++ b/wntr/network/io.py @@ -31,7 +31,6 @@ import wntr.epanet from wntr.epanet.util import FlowUnits import wntr.network.model -import wntr.utils.citations from wntr.gis.network import WaterNetworkGIS try: import geopandas as gpd @@ -70,7 +69,7 @@ def to_dict(wn) -> dict: version="wntr-{}".format(__version__), comment="WaterNetworkModel - all values given in SI units", name=wn.name, - citations=wntr.utils.citations.to_jsontypes(wn._citations), + references=wn._references.copy(), options=wn._options.to_dict(), curves=wn._curve_reg.to_list(), patterns=wn._pattern_reg.to_list(), @@ -105,7 +104,7 @@ def from_dict(d: dict, append=None): "version", "comment", "name", - "citations", + "references", "options", "curves", "patterns", @@ -123,8 +122,8 @@ def from_dict(d: dict, append=None): wn = append if "name" in d: wn.name = d["name"] - if "citations" in d: - wn._citations = wntr.utils.citations.from_jsontypes(d["citations"]) + if "references" in d: + wn._references = d["references"] if "options" in d: wn.options.__init__(**d["options"]) if "curves" in d: diff --git a/wntr/network/model.py b/wntr/network/model.py index 5fee95248..47919dd09 100644 --- a/wntr/network/model.py +++ b/wntr/network/model.py @@ -25,7 +25,6 @@ import six import wntr.epanet import wntr.network.io -from wntr.utils.citations import Citation from wntr.utils.ordered_set import OrderedSet from .base import AbstractModel, Link, LinkStatus, Registry @@ -73,8 +72,8 @@ def __init__(self, inp_file_name=None): # Network name self.name = None - self._citations: Union[str,Citation, List[Union[str,Citation]]] = list() - """A list of citations that document the source of this model. See also :class:`~wntr.utils.citations.Citation`.""" + self._references: List[Union[str, dict]] = list() + """A list of references that document the source of this model.""" self._options = Options() self._node_reg = NodeRegistry(self) @@ -341,6 +340,15 @@ def msx(self, msx): if not isinstance(msx, AbstractQualityModel): raise TypeError('Expected AbstractQualityModel (or derived), got {}'.format(type(msx))) + def add_msx_model(self, msx_filename=None): + """Add an msx model from a MSX input file (.msx extension)""" + from wntr.quality.multispecies import MultispeciesQualityModel + self._msx = MultispeciesQualityModel(msx_file_name=msx_filename) + + def remove_msx_model(self): + """Remove an msx model from the network""" + self._msx = None + """ ### # ### Create blank, unregistered objects (for direct assignment) diff --git a/wntr/quality/_library_data/arsenic_chloramine.json b/wntr/quality/_library_data/arsenic_chloramine.json new file mode 100644 index 000000000..3e6c5d3d9 --- /dev/null +++ b/wntr/quality/_library_data/arsenic_chloramine.json @@ -0,0 +1,203 @@ +{ + "wntr-version": "1.0.0", + "name": "arsenic_chloramine", + "title": "Arsenic Oxidation/Adsorption Example", + "desc": "This example models monochloramine oxidation of arsenite/arsenate and wall adsoption/desorption, as given in section 3 of the EPANET-MSX user manual", + "references": [ + "Shang, F. and Rossman, L.A. and Uber, J.G. (2023) \"EPANET-MSX 2.0 User Manual\". (Cincinnati, OH: Water Infrastructure Division (CESER), U.S. Environmental Protection Agency). EPA/600/R-22/199." + ], + "reaction_system": { + "species": [ + { + "name": "AS3", + "species_type": "bulk", + "units": "UG", + "atol": null, + "rtol": null, + "note": "Dissolved arsenite" + }, + { + "name": "AS5", + "species_type": "bulk", + "units": "UG", + "atol": null, + "rtol": null, + "note": "Dissolved arsenate" + }, + { + "name": "AStot", + "species_type": "bulk", + "units": "UG", + "atol": null, + "rtol": null, + "note": "Total dissolved arsenic" + }, + { + "name": "AS5s", + "species_type": "wall", + "units": "UG", + "atol": null, + "rtol": null, + "note": "Adsorbed arsenate" + }, + { + "name": "NH2CL", + "species_type": "bulk", + "units": "MG", + "atol": null, + "rtol": null, + "note": "Monochloramine" + } + ], + "constants": [ + { + "name": "Ka", + "value": 10.0, + "units": "1 / (MG * HR)", + "note": "Arsenite oxidation rate coefficient" + }, + { + "name": "Kb", + "value": 0.1, + "units": "1 / HR", + "note": "Monochloramine decay rate coefficient" + }, + { + "name": "K1", + "value": 5.0, + "units": "M^3 / (UG * HR)", + "note": "Arsenate adsorption coefficient" + }, + { + "name": "K2", + "value": 1.0, + "units": "1 / HR", + "note": "Arsenate desorption coefficient" + }, + { + "name": "Smax", + "value": 50.0, + "units": "UG / M^2", + "note": "Arsenate adsorption limit" + } + ], + "parameters": [], + "terms": [ + { + "name": "Ks", + "expression": "K1/K2", + "note": "Equil. adsorption coeff." + } + ], + "pipe_reactions": [ + { + "species_name": "AS3", + "dynamics_type": "rate", + "expression": "-Ka*AS3*NH2CL", + "note": "Arsenite oxidation" + }, + { + "species_name": "AS5", + "dynamics_type": "rate", + "expression": "Ka*AS3*NH2CL - Av*(K1*(Smax-AS5s)*AS5 - K2*AS5s)", + "note": "Arsenate production less adsorption" + }, + { + "species_name": "NH2CL", + "dynamics_type": "rate", + "expression": "-Kb*NH2CL", + "note": "Monochloramine decay" + }, + { + "species_name": "AS5s", + "dynamics_type": "equil", + "expression": "Ks*Smax*AS5/(1+Ks*AS5) - AS5s", + "note": "Arsenate adsorption" + }, + { + "species_name": "AStot", + "dynamics_type": "formula", + "expression": "AS3 + AS5", + "note": "Total arsenic" + } + ], + "tank_reactions": [ + { + "species_name": "AS3", + "dynamics_type": "rate", + "expression": "-Ka*AS3*NH2CL", + "note": "Arsenite oxidation" + }, + { + "species_name": "AS5", + "dynamics_type": "rate", + "expression": "Ka*AS3*NH2CL", + "note": "Arsenate production" + }, + { + "species_name": "NH2CL", + "dynamics_type": "rate", + "expression": "-Kb*NH2CL", + "note": "Monochloramine decay" + }, + { + "species_name": "AStot", + "dynamics_type": "formula", + "expression": "AS3 + AS5", + "note": "Total arsenic" + } + ] + }, + "network_data": { + "initial_quality": { + "AS3": { + "global_value": 0.0, + "node_values": {}, + "link_values": {} + }, + "AS5": { + "global_value": 0.0, + "node_values": {}, + "link_values": {} + }, + "AStot": { + "global_value": 0.0, + "node_values": {}, + "link_values": {} + }, + "AS5s": { + "global_value": 0.0, + "node_values": {}, + "link_values": {} + }, + "NH2CL": { + "global_value": 0.0, + "node_values": {}, + "link_values": {} + } + }, + "parameter_values": {}, + "sources": {}, + "patterns": {} + }, + "options": { + "timestep": 360, + "area_units": "M2", + "rate_units": "HR", + "solver": "RK5", + "coupling": "NONE", + "rtol": 0.001, + "atol": 0.0001, + "compiler": "NONE", + "segments": 5000, + "peclet": 1000, + "report": { + "pagesize": null, + "report_filename": null, + "species": {}, + "species_precision": {}, + "nodes": null, + "links": null + } + } +} \ No newline at end of file diff --git a/wntr/quality/_library_data/batch_chloramine_decay.json b/wntr/quality/_library_data/batch_chloramine_decay.json new file mode 100644 index 000000000..2d0e5f9f2 --- /dev/null +++ b/wntr/quality/_library_data/batch_chloramine_decay.json @@ -0,0 +1,415 @@ +{ + "wntr-version": "1.0.0", + "name": "batch_chloramine_decay", + "title": "Batch chloramine decay example", + "desc": null, + "references": [], + "reaction_system": { + "species": [ + { + "name": "HOCL", + "species_type": "bulk", + "units": "mol", + "atol": null, + "rtol": null, + "note": "hypochlorous acid" + }, + { + "name": "NH3", + "species_type": "bulk", + "units": "mol", + "atol": null, + "rtol": null, + "note": "ammonia" + }, + { + "name": "NH2CL", + "species_type": "bulk", + "units": "mol", + "atol": null, + "rtol": null, + "note": "monochloramine" + }, + { + "name": "NHCL2", + "species_type": "bulk", + "units": "mol", + "atol": null, + "rtol": null, + "note": "dichloramine" + }, + { + "name": "I", + "species_type": "bulk", + "units": "mol", + "atol": null, + "rtol": null, + "note": "unknown intermediate" + }, + { + "name": "OCL", + "species_type": "bulk", + "units": "mol", + "atol": null, + "rtol": null, + "note": "hypochlorite ion" + }, + { + "name": "NH4", + "species_type": "bulk", + "units": "mol", + "atol": null, + "rtol": null, + "note": "ammonium ion" + }, + { + "name": "ALK", + "species_type": "bulk", + "units": "mol", + "atol": null, + "rtol": null, + "note": "total alkalinity" + }, + { + "name": "H", + "species_type": "bulk", + "units": "mol", + "atol": null, + "rtol": null, + "note": "hydrogen ion" + }, + { + "name": "OH", + "species_type": "bulk", + "units": "mol", + "atol": null, + "rtol": null, + "note": "hydroxide ion" + }, + { + "name": "CO3", + "species_type": "bulk", + "units": "mol", + "atol": null, + "rtol": null, + "note": "carbonate ion" + }, + { + "name": "HCO3", + "species_type": "bulk", + "units": "mol", + "atol": null, + "rtol": null, + "note": "bicarbonate ion" + }, + { + "name": "H2CO3", + "species_type": "bulk", + "units": "mol", + "atol": null, + "rtol": null, + "note": "dissolved carbon dioxide" + }, + { + "name": "chloramine", + "species_type": "bulk", + "units": "mmol", + "atol": null, + "rtol": null, + "note": "monochloramine in mmol/L" + } + ], + "constants": [], + "parameters": [ + { + "name": "k1", + "global_value": 15000000000.0 + }, + { + "name": "k2", + "global_value": 0.076 + }, + { + "name": "k3", + "global_value": 1000000.0 + }, + { + "name": "k4", + "global_value": 0.0023 + }, + { + "name": "k6", + "global_value": 220000000.0 + }, + { + "name": "k7", + "global_value": 400000.0 + }, + { + "name": "k8", + "global_value": 100000000.0 + }, + { + "name": "k9", + "global_value": 30000000.0 + }, + { + "name": "k10", + "global_value": 55.0 + } + ], + "terms": [ + { + "name": "k5", + "expression": "(2.5e7*H) + (4.0e4*H2CO3) + (800*HCO3)" + }, + { + "name": "a1", + "expression": "k1 * HOCL * NH3" + }, + { + "name": "a2", + "expression": "k2 * NH2CL" + }, + { + "name": "a3", + "expression": "k3 * HOCL * NH2CL" + }, + { + "name": "a4", + "expression": "k4 * NHCL2" + }, + { + "name": "a5", + "expression": "k5 * NH2CL * NH2CL" + }, + { + "name": "a6", + "expression": "k6 * NHCL2 * NH3 * H" + }, + { + "name": "a7", + "expression": "k7 * NHCL2 * OH" + }, + { + "name": "a8", + "expression": "k8 * I * NHCL2" + }, + { + "name": "a9", + "expression": "k9 * I * NH2CL" + }, + { + "name": "a10", + "expression": "k10 * NH2CL * NHCL2" + } + ], + "pipe_reactions": [ + { + "species_name": "HOCL", + "dynamics_type": "rate", + "expression": "-a1 + a2 - a3 + a4 + a8" + }, + { + "species_name": "NH3", + "dynamics_type": "rate", + "expression": "-a1 + a2 + a5 - a6" + }, + { + "species_name": "NH2CL", + "dynamics_type": "rate", + "expression": "a1 - a2 - a3 + a4 - a5 + a6 - a9 - a10" + }, + { + "species_name": "NHCL2", + "dynamics_type": "rate", + "expression": "a3 - a4 + a5 - a6 - a7 - a8 - a10" + }, + { + "species_name": "I", + "dynamics_type": "rate", + "expression": "a7 - a8 - a9" + }, + { + "species_name": "H", + "dynamics_type": "rate", + "expression": "0" + }, + { + "species_name": "ALK", + "dynamics_type": "rate", + "expression": "0" + }, + { + "species_name": "OCL", + "dynamics_type": "equil", + "expression": "H * OCL - 3.16E-8 * HOCL" + }, + { + "species_name": "NH4", + "dynamics_type": "equil", + "expression": "H * NH3 - 5.01e-10 * NH4" + }, + { + "species_name": "CO3", + "dynamics_type": "equil", + "expression": "H * CO3 - 5.01e-11 * HCO3" + }, + { + "species_name": "H2CO3", + "dynamics_type": "equil", + "expression": "H * HCO3 - 5.01e-7 * H2CO3" + }, + { + "species_name": "HCO3", + "dynamics_type": "equil", + "expression": "ALK - HC03 - 2*CO3 - OH + H" + }, + { + "species_name": "OH", + "dynamics_type": "equil", + "expression": "H * OH - 1.0e-14" + }, + { + "species_name": "chloramine", + "dynamics_type": "formula", + "expression": "1000 * NH2CL" + } + ], + "tank_reactions": [] + }, + "network_data": { + "initial_quality": { + "HOCL": { + "global_value": 0.0, + "node_values": {}, + "link_values": {} + }, + "NH3": { + "global_value": 0.0, + "node_values": {}, + "link_values": {} + }, + "NH2CL": { + "global_value": 0.0, + "node_values": {}, + "link_values": {} + }, + "NHCL2": { + "global_value": 0.0, + "node_values": {}, + "link_values": {} + }, + "I": { + "global_value": 0.0, + "node_values": {}, + "link_values": {} + }, + "OCL": { + "global_value": 0.0, + "node_values": {}, + "link_values": {} + }, + "NH4": { + "global_value": 0.0, + "node_values": {}, + "link_values": {} + }, + "ALK": { + "global_value": 0.0, + "node_values": {}, + "link_values": {} + }, + "H": { + "global_value": 0.0, + "node_values": {}, + "link_values": {} + }, + "OH": { + "global_value": 0.0, + "node_values": {}, + "link_values": {} + }, + "CO3": { + "global_value": 0.0, + "node_values": {}, + "link_values": {} + }, + "HCO3": { + "global_value": 0.0, + "node_values": {}, + "link_values": {} + }, + "H2CO3": { + "global_value": 0.0, + "node_values": {}, + "link_values": {} + }, + "chloramine": { + "global_value": 0.0, + "node_values": {}, + "link_values": {} + } + }, + "parameter_values": { + "k1": { + "pipe_values": {}, + "tank_values": {} + }, + "k2": { + "pipe_values": {}, + "tank_values": {} + }, + "k3": { + "pipe_values": {}, + "tank_values": {} + }, + "k4": { + "pipe_values": {}, + "tank_values": {} + }, + "k6": { + "pipe_values": {}, + "tank_values": {} + }, + "k7": { + "pipe_values": {}, + "tank_values": {} + }, + "k8": { + "pipe_values": {}, + "tank_values": {} + }, + "k9": { + "pipe_values": {}, + "tank_values": {} + }, + "k10": { + "pipe_values": {}, + "tank_values": {} + } + }, + "sources": {}, + "patterns": {} + }, + "options": { + "timestep": 360, + "area_units": "ft2", + "rate_units": "hr", + "solver": "RK5", + "coupling": "NONE", + "rtol": 0.0001, + "atol": 0.0001, + "compiler": "NONE", + "segments": 5000, + "peclet": 1000, + "report": { + "pagesize": null, + "report_filename": null, + "species": {}, + "species_precision": {}, + "nodes": null, + "links": null + } + } +} \ No newline at end of file diff --git a/wntr/quality/_library_data/lead_ppm.json b/wntr/quality/_library_data/lead_ppm.json new file mode 100644 index 000000000..129140c45 --- /dev/null +++ b/wntr/quality/_library_data/lead_ppm.json @@ -0,0 +1,98 @@ +{ + "wntr-version": "1.0.0", + "name": "lead_ppm", + "title": "Lead Plumbosolvency Model (from Burkhardt et al 2020)", + "desc": "Parameters for EPA HPS Simulator Model", + "references": [ + "J. B. Burkhardt, et al. (2020) \"Framework for Modeling Lead in Premise Plumbing Systems Using EPANET\". J Water Resour Plan Manag. 146(12). https://doi.org/10.1061/(asce)wr.1943-5452.0001304 PMID:33627937" + ], + "reaction_system": { + "species": [ + { + "name": "PB2", + "species_type": "bulk", + "units": "ug", + "atol": null, + "rtol": null, + "note": "dissolved lead (Pb)" + } + ], + "constants": [ + { + "name": "M", + "value": 0.117, + "units": "ug * m^(-2) * s^(-1)", + "note": "Desorption rate (ug/m^2/s)" + }, + { + "name": "E", + "value": 140.0, + "units": "ug/L", + "note": "saturation/plumbosolvency level (ug/L)" + } + ], + "parameters": [ + { + "name": "F", + "global_value": 0.0, + "note": "determines which pipes have reactions" + } + ], + "terms": [], + "pipe_reactions": [ + { + "species_name": "PB2", + "dynamics_type": "rate", + "expression": "F * Av * M * (E - PB2) / E" + } + ], + "tank_reactions": [ + { + "species_name": "PB2", + "dynamics_type": "rate", + "expression": "0" + } + ] + }, + "network_data": { + "initial_quality": { + "PB2": { + "global_value": 0.0, + "node_values": {}, + "link_values": {} + } + }, + "parameter_values": { + "F": { + "pipe_values": {}, + "tank_values": {} + } + }, + "sources": {}, + "patterns": {} + }, + "options": { + "timestep": 1, + "area_units": "M2", + "rate_units": "SEC", + "solver": "RK5", + "coupling": "NONE", + "rtol": 1e-08, + "atol": 1e-08, + "compiler": "NONE", + "segments": 5000, + "peclet": 1000, + "report": { + "pagesize": null, + "report_filename": null, + "species": { + "PB2": "YES" + }, + "species_precision": { + "PB2": 5 + }, + "nodes": "all", + "links": "all" + } + } +} \ No newline at end of file diff --git a/wntr/quality/_library_data/nicotine.json b/wntr/quality/_library_data/nicotine.json new file mode 100644 index 000000000..5ab62fc9d --- /dev/null +++ b/wntr/quality/_library_data/nicotine.json @@ -0,0 +1,108 @@ +{ + "wntr-version": "1.0.0", + "name": "nicotine", + "title": "Nicotine - Chlorine reaction", + "desc": null, + "references": [], + "reaction_system": { + "species": [ + { + "name": "Nx", + "species_type": "bulk", + "units": "mg", + "atol": null, + "rtol": null, + "note": "Nicotine" + }, + { + "name": "HOCL", + "species_type": "bulk", + "units": "mg", + "atol": null, + "rtol": null, + "note": "Free chlorine" + } + ], + "constants": [ + { + "name": "kd", + "value": 0.00233, + "units": "min^(-1)", + "note": "decay rate" + }, + { + "name": "K1", + "value": 0.0592, + "units": "L * min^(-1) * mg^(-1)", + "note": "decay constant for chlorine as function of mass(Nic)" + }, + { + "name": "K2", + "value": 0.184, + "units": "L * min^(-1) * mg^(-1)", + "note": "decay constant for nicotine as function of mass(Cl)" + } + ], + "parameters": [], + "terms": [ + { + "name": "RxCl", + "expression": "kd * HOCL + K1 * Nx * HOCL" + }, + { + "name": "RxN", + "expression": "K2 * Nx * HOCL" + } + ], + "pipe_reactions": [ + { + "species_name": "Nx", + "dynamics_type": "rate", + "expression": "-RxN" + }, + { + "species_name": "HOCL", + "dynamics_type": "rate", + "expression": "-RxCl" + } + ], + "tank_reactions": [] + }, + "network_data": { + "initial_quality": { + "Nx": { + "global_value": 0.0, + "node_values": {}, + "link_values": {} + }, + "HOCL": { + "global_value": 0.0, + "node_values": {}, + "link_values": {} + } + }, + "parameter_values": {}, + "sources": {}, + "patterns": {} + }, + "options": { + "timestep": 1, + "area_units": "m2", + "rate_units": "min", + "solver": "RK5", + "coupling": "NONE", + "rtol": 0.0001, + "atol": 0.0001, + "compiler": "NONE", + "segments": 5000, + "peclet": 1000, + "report": { + "pagesize": null, + "report_filename": null, + "species": {}, + "species_precision": {}, + "nodes": null, + "links": null + } + } +} \ No newline at end of file diff --git a/wntr/quality/_library_data/nicotine_ri.json b/wntr/quality/_library_data/nicotine_ri.json new file mode 100644 index 000000000..3e9a2d981 --- /dev/null +++ b/wntr/quality/_library_data/nicotine_ri.json @@ -0,0 +1,158 @@ +{ + "wntr-version": "1.0.0", + "name": "nicotine_ri", + "title": "Nicotine - Chlorine reaction with reactive intermediate", + "desc": null, + "references": [], + "reaction_system": { + "species": [ + { + "name": "Nx", + "species_type": "bulk", + "units": "mg", + "atol": null, + "rtol": null, + "note": "Nicotine" + }, + { + "name": "HOCL", + "species_type": "bulk", + "units": "mg", + "atol": null, + "rtol": null, + "note": "Free Chlorine" + }, + { + "name": "NX2", + "species_type": "bulk", + "units": "mg", + "atol": null, + "rtol": null, + "note": "Intermediate Nicotine Reactive" + } + ], + "constants": [ + { + "name": "kd", + "value": 3e-05, + "units": "1/min", + "note": "decay constant for chlorine over time" + }, + { + "name": "K1", + "value": 0.0975, + "units": "L * min^(-1) * mg^(-1)", + "note": "decay constant for chlorine as function of mass(Nic)" + }, + { + "name": "K2", + "value": 0.573, + "units": "L * min^(-1) * mg^(-1)", + "note": "decay constant for nicotine as function of mass(Cl)" + }, + { + "name": "K3", + "value": 0.0134, + "units": "L * min^(-1) * mg^(-1)", + "note": "decay constant for nicotine as function of mass(Nic2)" + }, + { + "name": "K4", + "value": 0.0219, + "units": "L * min^(-1) * mg^(-1)", + "note": "decay constant for nicotine as function of mass(Cl)" + } + ], + "parameters": [], + "terms": [ + { + "name": "RXCL", + "expression": "kd * HOCL + K1 * Nx * HOCL + K3 * NX2 * HOCL" + }, + { + "name": "RXN", + "expression": "K2 * Nx * HOCL" + }, + { + "name": "RXNX2", + "expression": "K2 * Nx * HOCL - K4 * NX2 * HOCL" + } + ], + "pipe_reactions": [ + { + "species_name": "Nx", + "dynamics_type": "rate", + "expression": "-RXN" + }, + { + "species_name": "HOCL", + "dynamics_type": "rate", + "expression": "-RXCL" + }, + { + "species_name": "NX2", + "dynamics_type": "rate", + "expression": "RXNX2" + } + ], + "tank_reactions": [ + { + "species_name": "Nx", + "dynamics_type": "rate", + "expression": "-RXN" + }, + { + "species_name": "HOCL", + "dynamics_type": "rate", + "expression": "-RXCL" + }, + { + "species_name": "NX2", + "dynamics_type": "rate", + "expression": "RXNX2" + } + ] + }, + "network_data": { + "initial_quality": { + "Nx": { + "global_value": 0.0, + "node_values": {}, + "link_values": {} + }, + "HOCL": { + "global_value": 0.0, + "node_values": {}, + "link_values": {} + }, + "NX2": { + "global_value": 0.0, + "node_values": {}, + "link_values": {} + } + }, + "parameter_values": {}, + "sources": {}, + "patterns": {} + }, + "options": { + "timestep": 1, + "area_units": "m2", + "rate_units": "min", + "solver": "RK5", + "coupling": "NONE", + "rtol": 1e-10, + "atol": 1e-10, + "compiler": "NONE", + "segments": 5000, + "peclet": 1000, + "report": { + "pagesize": null, + "report_filename": null, + "species": {}, + "species_precision": {}, + "nodes": null, + "links": null + } + } +} \ No newline at end of file diff --git a/wntr/quality/base.py b/wntr/quality/base.py index 43e67e955..8e05f1a49 100644 --- a/wntr/quality/base.py +++ b/wntr/quality/base.py @@ -8,11 +8,8 @@ from abc import ABC, abstractmethod, abstractproperty import logging from enum import Enum, IntEnum -from typing import Any, Dict -from wntr.epanet.util import ENcomment -from wntr.quality.multispecies import Species -from wntr.utils.disjoint_mapping import KeyExistsError, VariablesRegistry - +from typing import Any, Dict, Iterator +from wntr.utils.disjoint_mapping import DisjointMapping from wntr.utils.enumtools import add_get @@ -66,9 +63,7 @@ def eval(cls, x): except ImportError: sympy = None has_sympy = False - logging.critical( - "This python installation does not have SymPy installed. Certain functionality will be disabled." - ) + logging.critical("This python installation does not have SymPy installed. Certain functionality will be disabled.") standard_transformations = (None,) convert_xor = None if not has_sympy: @@ -91,15 +86,23 @@ def eval(cls, x): log10, ) - def _cot(x): return 1 / tan(x) + def _cot(x): + return 1 / tan(x) + cot = _cot Abs = abs asin = arcsin acos = arccos atan = arctan - def _acot(x): return 1 / arctan(1 / x) + + def _acot(x): + return 1 / arctan(1 / x) + acot = _acot - def _coth(x): return 1 / tanh(x) + + def _coth(x): + return 1 / tanh(x) + coth = _coth Heaviside = heaviside _log10 = log10 @@ -268,10 +271,11 @@ def _coth(x): return 1 / tanh(x) :meta hide-value: """ + class AnnotatedFloat(float): def __new__(self, value, note=None): return float.__new__(self, value) - + def __init__(self, value, note=None): float.__init__(value) self.note = note @@ -344,10 +348,10 @@ class SpeciesType(IntEnum): """wall species""" B = BULK W = WALL - + @add_get(abbrev=True) -class LocationType(Enum): +class ReactionType(Enum): """What type of network component does this reaction occur in The following types are defined, and aliases of just the first character @@ -407,30 +411,31 @@ class DynamicsType(Enum): R = RATE F = FORMULA + __all__ = [ - 'HYDRAULIC_VARIABLES', - 'EXPR_FUNCTIONS', - 'RESERVED_NAMES', - 'EXPR_TRANSFORMS', - 'QualityVarType', - 'SpeciesType', - 'LocationType', - 'DynamicsType', - 'WaterQualityVariable', - 'WaterQualityReaction', + "HYDRAULIC_VARIABLES", + "EXPR_FUNCTIONS", + "RESERVED_NAMES", + "EXPR_TRANSFORMS", + "QualityVarType", + "SpeciesType", + "ReactionType", + "DynamicsType", + "WaterQualityVariable", + "WaterQualityReaction", ] class WaterQualityReaction(ABC): - def __init__(self, dynamics_type: DynamicsType, *, note=None) -> None: + def __init__(self, species_name: str, *, note=None) -> None: """A water quality reaction definition. This abstract class must be subclassed. Arguments --------- - dynamics_type : DynamicsType - The type of reaction dynamics being described by the expression: one of RATE, FORMULA, or EQUIL. + species_name : str + The name of the chemical or biological species being modeled using this reaction. Keyword Arguments @@ -444,26 +449,27 @@ def __init__(self, dynamics_type: DynamicsType, *, note=None) -> None: TypeError if dynamics_type is invalid """ - dynamics_type = DynamicsType.get(dynamics_type) - if dynamics_type is None: - raise TypeError("dynamics cannot be None") - self._dynamics_type = dynamics_type + if species_name is None: + raise TypeError("The species_name cannot be None") + self._species_name = species_name self.note = note - def dynamics_type(self) -> DynamicsType: - """The type of dynamics being described. - See :class:`DynamicsType` for valid values. - """ - raise NotImplementedError + @property + def species_name(self) -> str: + return self._species_name + @abstractproperty + def reaction_type(self) -> Enum: + """The type of reaction or where this reaction occurs.""" + raise NotImplementedError + def __str__(self) -> str: - """Return a string representation of the reaction""" - return "{}({}) = ".format(self.__class__.__name__, self._dynamics_type.name) + return "{}->{}".format(self.species_name, self.reaction_type.name) def __repr__(self) -> str: return ( "{}(".format(self.__class__.__name__) - + ", ".join(["{}={}".format(k, repr(v)) for k, v in self.to_dict().items()]) + + ", ".join(["{}={}".format(k, repr(getattr(self, k))) for k, v in self.to_dict().items()]) + ")" ) @@ -485,7 +491,7 @@ class WaterQualityVariable(ABC): required to create these variables and define reactions. """ - def __init__(self, name: str, *, note=None, _vars=None) -> None: + def __init__(self, name: str, *, note=None) -> None: """Multi-species variable constructor arguments. Arguments @@ -516,15 +522,12 @@ def __init__(self, name: str, *, note=None, _vars=None) -> None: _vars : VariablesRegistry, optional the variables registry object of the model this variable was added to, by default None """ - if _vars is not None and name in _vars: - raise KeyExistsError("This variable name is already taken") - elif name in RESERVED_NAMES: + if name in RESERVED_NAMES: raise ValueError("Name cannot be a reserved name") self.name: str = name """The name/ID of this variable, must be a valid EPANET/MSX ID""" self.note = note """A note related to this variable""" - self._vars: VariablesRegistry = _vars @abstractproperty def var_type(self) -> QualityVarType: @@ -534,4 +537,70 @@ def var_type(self) -> QualityVarType: @abstractmethod def to_dict(self) -> Dict[str, Any]: """Represent the object as a dictionary""" - raise NotImplementedError \ No newline at end of file + raise NotImplementedError + + def __str__(self) -> str: + return self.name + + def __repr__(self) -> str: + return ( + "{}(".format(self.__class__.__name__) + + ", ".join(["{}={}".format(k, repr(getattr(self, k))) for k, v in self.to_dict().items()]) + + ")" + ) + + +class WaterQualityReactionSystem(ABC): + """Abstract class for reaction systems, which contains variables and reaction expressions. + + This class contains the functions necessary to perform as a mapping view onto the + **variables** defined, by their name. + """ + + def __init__(self) -> None: + self._vars = DisjointMapping() + self._rxns = dict() + + @abstractmethod + def add_variable(self, obj: WaterQualityVariable) -> None: + """Add a variable to the system""" + raise NotImplementedError + + @abstractmethod + def add_reaction(self, obj: WaterQualityReaction) -> None: + """Add a reaction to the system""" + raise NotImplementedError + + @abstractmethod + def all_variables(self): + """A generator looping through all variables""" + raise NotImplementedError + + @abstractmethod + def all_reactions(self): + """A generator looping through all reactions""" + raise NotImplementedError + + @abstractmethod + def to_dict(self): + """Represent the reaction system as a dictionary""" + raise NotImplementedError + + def __contains__(self, __key: object) -> bool: + return self._vars.__contains__(__key) + + def __eq__(self, __value: object) -> bool: + return self._vars.__eq__(__value) + + def __ne__(self, __value: object) -> bool: + return self._vars.__ne__(__value) + + def __getitem__(self, __key: str) -> WaterQualityVariable: + return self._vars.__getitem__(__key) + + def __iter__(self) -> Iterator: + return self._vars.__iter__() + + def __len__(self) -> int: + return self._vars.__len__() + \ No newline at end of file diff --git a/wntr/quality/library.py b/wntr/quality/library.py index db2dea20a..482523877 100644 --- a/wntr/quality/library.py +++ b/wntr/quality/library.py @@ -4,54 +4,39 @@ r"""A library of common multispecies reactions. -Values in libarary are currently for test purposes only. These highlight the -reaction form/relationships but do not provide the specific system kinetics. -In all cases, updates will be necessary to use a specific model with a specific -network; that is, sources, pipes, nodes are for a given network, and must be -updated for different water network models. Citations are provided for the -reaction values and models. -Notes ------ -.. important:: +.. rubric:: Environment Variable - The docstrings you will write will likely use mathematics, as with the - models already provided. You will need to make them "raw" strings - e.g., - ``r'''docstring'''``. This is because most LaTeX commands will use ``\`` - characters in the commands, which can mess up documentation unless the docstrings - are specified as raw, not interpreted, text. +.. envvar:: WNTR_RXN_LIBRARY_PATH -.. important:: - - Make sure to provide all appropriate references to the model in your creation - function. - -.. _msx_library_note: - -.. rubric:: Note regarding functions within the library that accept a water network model - -If a water network is provided that does not have an ``msx`` attribute, then a new model will be -created and added to the network. The new model will also be returned as an object. - -If a water network is provided that already has an ``msx`` attribute, then this function will: -first check to see if there are variables that are in conflict with the existing reaction -model. If there are conflicts, an exception will be raised. The :attr:`~MultispeciesOptions.area_units` -and :attr:`~MultispeciesOptions.rate_units` will also be checked for conflicts, and an exception raised -if they differ from the already-existing units. -If there are no conflicts, then the variables and reactions for this model will be added to the -existing model. If there are conflicts, then the user must resolve them and try again. + This environment variable, if set, will add additional folder(s) to the + path to search for quality model files, (files with an ".msx", ".yaml", + or ".json" file extension). + Multiple folders should be separated using the "``;``" character. + See :class:`~wntr.quality.library.ReactionLibrary` for more details. """ import logging +import os +from typing import Any, ItemsView, Iterator, KeysView, List, Tuple, Union, ValuesView +from pkg_resources import resource_filename -from wntr.quality.multispecies import MultispeciesQualityModel -from wntr.network.model import WaterNetworkModel from .multispecies import MultispeciesQualityModel -from .base import LocationType, SpeciesType, DynamicsType +from .base import ReactionType, SpeciesType, DynamicsType -PIPE = LocationType.PIPE -TANK = LocationType.TANK +import json + +try: + import yaml + + yaml_err = None +except ImportError as e: + yaml = None + yaml_err = e + +PIPE = ReactionType.PIPE +TANK = ReactionType.TANK BULK = SpeciesType.BULK WALL = SpeciesType.WALL RATE = DynamicsType.RATE @@ -60,25 +45,6 @@ logger = logging.getLogger(__name__) -__all__ = [ - "cite_msx", - "nicotine", - "nicotine_ri", - "lead_ppm", - "arsenic_chloramine", - "batch_chloramine_decay", -] - -########################################## -## -## IMPORTANT NOTE FOR CONTRIBUTORS -## -## The docstrings you write will likely use mathematics, as with the models already provided. -## you will need to make them "raw" strings -- i.e., r"""adocstring""" -## This is because most latex/mathjax formats use \ characters, which mess up docscrape -## unless you mark the string as raw, not interpreted, text. -## - def cite_msx() -> dict: """A citation generator for the EPANET-MSX user guide. @@ -103,626 +69,350 @@ def cite_msx() -> dict: # ) -# FIXME: Need to actually do the checks and adding to the wn - - -# ===================== Nicotine-chlorine model -# -def nicotine(wn: WaterNetworkModel = None) -> MultispeciesQualityModel: - r"""Create a new nicotine-chlorine reaction model, and optionally attach it to a water network model. - - Parameters - ---------- - wn : WaterNetworkModel, optional - the water network to use to hold the new or updated reaction model, by default None - - Returns - ------- - MultispeciesQualityModel - the new or updated reaction/quality model - - Model Description - ----------------- - This model defines a simple nicotine-chlorine reaction. The model only defines bulk species - and does not specify any tank reactions. There is no reactive intermediate species in this - implementation, see :func:`nicotine_ri` for a model with a reactive intermediary. - - Bulk species - .. math:: - - Nx &:= \mathrm{mg}_\mathrm{(Nic)}~\text{[nicotine]} \\ - HOCL &:= \mathrm{mg}_\mathrm{(Cl)}~\text{[chlorine]} +class ReactionLibrary: + """A library of multispecies reaction definitions. - Coefficients - .. math:: + This object can be accessed and treated like a dictionary, where keys are the model + names and the values are the model objects. - k_d &= 2.33 \times 10^{-3}~\mathrm{min}^{-1} \\ - k_1 &= 5.92 \times 10^{-2}~\mathrm{L}\,\mathrm{min}^{-1}\,\mathrm{mg}_{\mathrm{(Nic)}}^{-1} \\ - k_2 &= 1.83 \times 10^{-1}~\mathrm{L}\,\mathrm{min}^{-1}\,\mathrm{mg}_{\mathrm{(Cl)}}^{-1} + The initialization sets up a list of paths, but *will not* + automatically read the files in them (use :meth:`load_all` for this). + The paths are added in the following order: - Other terms - .. math:: + 1. the builtin directory of reactions, + 2. any paths specified in the environment variable described below, with directories listed + first having the highest priority, + 3. any extra paths specified in the constructor, searched in the order provided. - RxCl &= k_d \, HOCL + k_1 \, Nx \, HOCL \\ - RxN &= k_2 \, Nx \, HOCL - - Pipe reactions - .. math:: - - \frac{d}{dt}Nx &= -RxN \\ - \frac{d}{dt}HOCL &= -RxCl - - The tank reactions are not explicitly defined in this model. - - - Notes - ----- - Please see `msx_library_note`_ for information on how a model that is passed in should be handled. - - """ - msx = MultispeciesQualityModel() - msx.name = "nicotine" - msx.title = ("Nicotine - Chlorine reaction",) - msx.options.area_units = "m2" - msx.options.rate_units = "min" - msx.options.timestep = 1 - msx.add_species("Nx", "bulk", units="mg", note="Nicotine") - msx.add_species(name="HOCL", species_type=BULK, units="mg", note="Free chlorine") - msx.add_constant("kd", value=2.33e-3, units="min^(-1)", note="decay rate") - msx.add_constant( - "K1", - value=5.92e-2, - units="L * min^(-1) * mg^(-1)", - note="decay constant for chlorine as function of mass(Nic)", - ) - msx.add_constant( - "K2", - value=1.84e-1, - units="L * min^(-1) * mg^(-1)", - note="decay constant for nicotine as function of mass(Cl)", - ) - msx.add_term("RxCl", expression="kd * HOCL + K1 * Nx * HOCL") - msx.add_term("RxN", expression="K2 * Nx * HOCL") - msx.add_reaction(species="Nx", location="pipe", dynamics_type="rate", expression="-RxN") - msx.add_reaction("HOCL", PIPE, dynamics_type=RATE, expression="-RxCl") - return msx - - -# ===================== Nicotine-chlorine reactive intermediate species -# -def nicotine_ri(wn: WaterNetworkModel = None) -> MultispeciesQualityModel: - r"""A nicotine-chlorine reaction with a reactive intermediate. - - Parameters - ---------- - wn : WaterNetworkModel, optional - the water network to use to hold the new or updated reaction model, by default None - - Returns - ------- - MultispeciesQualityModel - the new or updated reaction/quality model - - Model Description - ----------------- - This model defines a simple nicotine-chlorine reaction with a reactive intermediate species. - The model only defines bulk species, and the pipe and tank reactions use the same expressions. - For a simpler model, see :func:`nicotine`. - - Bulk species - .. math:: - Nx &:= \mathrm{mg}_\mathrm{(Nic)}~\text{[nicotine]} \\ - HOCL &:= \mathrm{mg}_\mathrm{(Cl)}~\text{[chlorine]} \\ - NX2 &:= \mathrm{mg}_\mathrm{(Nic_2)}~\text{[reaction~intermediary]} - - Coefficients - .. math:: - k_d &= 3.0 \times 10^{-5}~\mathrm{min}^{-1} \\ - k_1 &= 9.75 \times 10^{-2}~\mathrm{L}\,\mathrm{min}^{-1}\,\mathrm{mg}_{\mathrm{(Nic)}}^{-1}\\ - k_2 &= 5.73 \times 10^{-1}~\mathrm{L}\,\mathrm{min}^{-1}\,\mathrm{mg}_{\mathrm{(Cl)}}^{-1}\\ - K_3 &= 1.34 \times 10^{-2}~\mathrm{L}\,\mathrm{min}^{-1}\,\mathrm{mg}_{\mathrm{(Nic_2)}}^{-1}\\ - K_4 &= 2.19 \times 10^{-2}~\mathrm{L}\,\mathrm{min}^{-1}\,\mathrm{mg}_{\mathrm{(Cl)}}^{-1} - - Other terms - .. math:: - RXCL &= k_d \, HOCL + k_1 \, Nx \, HOCL + K_3 \, NX2 \, HOCL\\ - RXN &= k_2 \, Nx \, HOCL\\ - RXNX2 &= k_2 \, Nx \, HOCL - K_4 \, NX2 \, HOCL - - Pipe reactions and tank reactions *(defined separately for pipe and tank)* - .. math:: - \frac{d}{dt}Nx &= -RXN\\ - \frac{d}{dt}HOCL &= -RXCL\\ - \frac{d}{dt}HOCL &= RXNX2 - - Notes - ----- - If a water network is provided that does not have an ``msx`` attribute, then a new model will be - created and added to the network. The new model will also be returned as an object. - - If a water network is provided that already has an ``msx`` attribute, then this function will: - first check to see if there are variables that are in conflict with the existing reaction - model. If there are conflicts, an exception will be raised. The :attr:`~MultispeciesOptions.area_units` - and :attr:`~MultispeciesOptions.rate_units` will also be checked for conflicts, and an exception raised - if they differ. - If there are no conflicts, then the variables and reactions for this model will be added to the - existing model. If there are conflicts, then the user must resolve them and try again. + Once created, the library paths cannot be modified. However, a model can be added + to the library using the :meth:`add_model_from_file` or :meth:`add_models_from_dir` + methods. The precedence of the directories can be reversed based on the ``duplicates`` + argument passed to these functions. """ - msx = MultispeciesQualityModel() - msx.name = "nicotine_ri" - msx.title = ("Nicotine - Chlorine reaction with reactive intermediate",) - - # Set the options - msx.options.area_units = "m2" - msx.options.rate_units = "min" - msx.options.timestep = 1 - msx.options.atol = 1.0e-10 - msx.options.rtol = 1.0e-10 - - # Add species - msx.add_species("Nx", "bulk", units="mg", note="Nicotine") - msx.add_species("HOCL", BULK, units="mg", note="Free Chlorine") - msx.add_species("NX2", "b", units="mg", note="Intermediate Nicotine Reactive") - - # Add coefficients - msx.add_constant("kd", 3.0e-5, units="1/min", note="decay constant for chlorine over time") - msx.add_constant( - "K1", 9.75e-2, units="L * min^(-1) * mg^(-1)", note="decay constant for chlorine as function of mass(Nic)" - ) - msx.add_constant("K2", 5.73e-1, units="L * min^(-1) * mg^(-1)", note="decay constant for nicotine as function of mass(Cl)") - msx.add_constant( - "K3", 1.34e-2, units="L * min^(-1) * mg^(-1)", note="decay constant for nicotine as function of mass(Nic2)" - ) - msx.add_constant("K4", 2.19e-2, units="L * min^(-1) * mg^(-1)", note="decay constant for nicotine as function of mass(Cl)") - - # Add terms (named subexpressions) - msx.add_term("RXCL", "kd * HOCL + K1 * Nx * HOCL + K3 * NX2 * HOCL") - msx.add_term("RXN", "K2 * Nx * HOCL") - msx.add_term("RXNX2", "K2 * Nx * HOCL - K4 * NX2 * HOCL") - - # Add pipe reactions, one per species - msx.add_reaction("Nx", "pipe", "RATE", "-RXN") - msx.add_reaction("HOCL", PIPE, RATE, "-RXCL") - msx.add_reaction("NX2", "p", "r", "RXNX2") - - # Tank reactions actually aren't necessary since there aren't any wall species - # but it is good form to add them anyway - msx.add_reaction("Nx", "tank", "rate", "-RXN") - msx.add_reaction("HOCL", TANK, RATE, "-RXCL") - msx.add_reaction("NX2", "t", "r", "RXNX2") - return msx - - -# ===================== Lead plumbosolvency model -# -def lead_ppm(wn: WaterNetworkModel = None) -> MultispeciesQualityModel: - r"""A lead plumbosolvency model; please cite [BWMS20]_ if you use this model. - - Parameters - ---------- - wn : WaterNetworkModel, optional - the water network to use to hold the new or updated reaction model, by default None - - - Returns - ------- - MultispeciesQualityModel - the new or updated reaction/quality model - - - Model Description - ----------------- - This model is described in [BWMS20]_, and represents plumbosolvency of lead in lead pipes - within a dwelling. - - Bulk species - .. math:: - PB2 := \mathrm{μg}_\mathrm{(Pb)}~\text{[lead]} - - Coefficients - .. math:: - M &= 0.117~\mathrm{μg}_{\mathrm{(Pb)}} \, \mathrm{m}^{-2} \, \mathrm{s}^{-1} \\ - E &= 140.0~\mathrm{μg}_{\mathrm{(Pb)}} \, \mathrm{L}^{-1} - - Parameters [1]_ - .. math:: - F\langle pipe\rangle = \left\{\begin{matrix}1&\mathrm{if}~pipe~\mathrm{is~lead},\\0&\mathrm{otherwise}\end{matrix}\right. - - Pipe reactions [2]_ - .. math:: - \frac{d}{dt}PB2 = F \, Av \, M \frac{\left( E - PB2 \right)}{E} - - Tank reactions - .. math:: - \frac{d}{dt}PB2 = 0 - - - References - ---------- - If this model is used, please cite the following paper(s). - - .. [BWMS20] - J. B. Burkhardt, et al. (2020) - "Framework for Modeling Lead in Premise Plumbing Systems Using EPANET". - `Journal of water resources planning and management`. - **146** (12). https://doi.org/10.1061/(asce)wr.1943-5452.0001304 - - Notes - ----- - - .. [1] - The default value of a parameter is specified by "otherwise" in its mathematical definition. Because - the values of a parameter are network dependent, the non-global values will need to be added to any - parameter after the model is added to a network. - .. [2] - The hydraulic variable, :math:`Av`, is the surface area per unit volume (area units/L) of the pipe - where the reaction is taking place. See :numref:`table-msx-hyd-vars` for a list of valid names - for hydraulic variables that can be used in quality expressions. - """ - msx = MultispeciesQualityModel() - msx.name = "lead_ppm" - msx.title = "Lead Plumbosolvency Model (from Burkhardt et al 2020)" - msx.desc = "Parameters for EPA HPS Simulator Model" - msx.references.append( - """J. B. Burkhardt, et al. (2020) "Framework for Modeling Lead in Premise Plumbing Systems Using EPANET". `Journal of water resources planning and management`. 146(12). https://doi.org/10.1061/(asce)wr.1943-5452.0001304""" - # dict( - # entry_type="article", - # key="BWMS20", - # fields=dict( - # title="Framework for Modeling Lead in Premise Plumbing Systems Using EPANET", - # year=2020, - # author=[ - # "Jonathan B. Burkhardt", - # "Hyoungmin Woo", - # "James Mason", - # "Feng Shang", - # "Simoni Triantafyllidou", - # "Michael R. Schock", - # "Darren Lytle", - # "Regan Murray", - # ], - # journaltitle="J Water Resour Plan Manag", - # volume=146, - # number=12, - # date="2020-12-01", - # doi="10.1061/(asce)wr.1943-5452.0001304", - # eprint=[ - # "PMID:33627937", - # "PMCID:PMC7898126", - # "NIHMSID:NIHMS1664627", - # ], - # ), - # ) - ) - msx.options = { - "report": { - "species": {"PB2": "YES"}, - "species_precision": {"PB2": 5}, - "nodes": "all", - "links": "all", - }, - "timestep": 1, - "area_units": "M2", - "rate_units": "SEC", - "rtol": 1e-08, - "atol": 1e-08, - } - PB2 = msx.add_species(name="PB2", species_type=BULK, units="ug", note="dissolved lead (Pb)") - msx.add_constant("M", 0.117, note="Desorption rate (ug/m^2/s)", units="ug * m^(-2) * s^(-1)") - msx.add_constant("E", 140.0, note="saturation/plumbosolvency level (ug/L)", units="ug/L") - msx.add_parameter("F", global_value=0, note="determines which pipes have reactions") - PB2.add_reaction("pipes", "RATE", expression="F * Av * M * (E - PB2) / E") - PB2.add_reaction("tanks", RATE, expression="0") - return msx - - -def arsenic_chloramine(wn: WaterNetworkModel = None) -> MultispeciesQualityModel: - r"""Model monochloramine-arsenite-arsenate adsorption/desorption with fast equilibrium. - - Parameters - ---------- - wn : WaterNetworkModel, optional - the water network to use to hold the new or updated reaction model, by default None - - Returns - ------- - MultispeciesQualityModel - the new or updated reaction/quality model - - Model Description - ----------------- - This example models monochloramine oxidation of arsenite/arsenate and wall - adsorption/desorption, as given in section 3 of the EPANET-MSX user manual. - - The system of equations for the reaction in pipes is given in Eq. (2.4) through (2.7) - in [SRU23]_. - - .. math:: - - \frac{d}{dt}{(\mathsf{As}^\mathrm{III})} &= -k_a ~ {(\mathsf{As}^\mathrm{III})} ~ {(\mathsf{NH_2Cl})} \\ - \frac{d}{dt}{(\mathsf{As}^\mathrm{V})} &= k_a ~ {(\mathsf{As}^\mathrm{III})} ~ {(\mathsf{NH_2CL})} - Av \left( k_1 \left(S_\max - {(\mathsf{As}^\mathrm{V}_s)} \right) {(\mathsf{As}^\mathrm{V})} - k_2 ~ {(\mathsf{As}^\mathrm{V}_s)} \right) \\ - \frac{d}{dt}{(\mathsf{NH_2Cl})} &= -k_b ~ {(\mathsf{NH_2Cl})} \\ - {(\mathsf{As}^\mathrm{V}_s)} &= \frac{k_s ~ S_\max ~ {(\mathsf{As}^\mathrm{V})}}{1 + k_s {(\mathsf{As}^\mathrm{V})}} - - - where the various species, coefficients, and expressions are described in the tables below. - - - .. list-table:: Options - :header-rows: 1 - :widths: 3 3 10 - - * - Option - - Code - - Description - * - Rate units - - "HR" - - :math:`\mathrm{h}^{-1}` - * - Area units - - "M2" - - :math:`\mathrm{m}^2` - - - .. list-table:: Species - :header-rows: 1 - :widths: 2 2 2 3 4 6 - - * - Name - - Type - - Value - - Symbol - - Units - - Note - * - AS3 - - Bulk - - "UG" - - :math:`{\mathsf{As}^\mathrm{III}}` - - :math:`\require{upgreek}\upmu\mathrm{g~L^{-1}}` - - dissolved arsenite - * - AS5 - - Bulk - - "UG" - - :math:`{\mathsf{As}^\mathrm{V}}` - - :math:`\require{upgreek}\upmu\mathrm{g~L^{-1}}` - - dissolved arsenate - * - AStot - - Bulk - - "UG" - - :math:`{\mathsf{As}^\mathrm{tot}}` - - :math:`\require{upgreek}\upmu\mathrm{g~L^{-1}}` - - dissolved arsenic (total) - * - NH2CL - - Bulk - - "MG" - - :math:`{\mathsf{NH_2Cl}}` - - :math:`\mathrm{mg~L^{-1}}` - - dissolved monochloramine - * - AS5s - - Wall - - "UG" - - :math:`{\mathsf{As}^\mathrm{V}_{s}}` - - :math:`\require{upgreek}\upmu\mathrm{g}~\mathrm{m}^{-2}` - - adsorped arsenate (surface) - - - .. list-table:: Coefficients [1]_ - :header-rows: 1 - :widths: 2 2 2 3 4 6 - - * - Name - - Type - - Value - - Symbol - - Units - - Note - * - Ka - - Const - - :math:`10` - - :math:`k_a` - - :math:`\mathrm{mg}^{-1}_{\left(\mathsf{NH_2Cl}\right)}~\mathrm{h}^{-1}` - - arsenite oxidation - * - Kb - - Const - - :math:`0.1` - - :math:`k_b` - - :math:`\mathrm{h}^{-1}` - - chloromine decay - * - K1 - - Const - - :math:`5.0` - - :math:`k_1` - - :math:`\require{upgreek}\textrm{L}~\upmu\mathrm{g}^{-1}_{\left(\mathsf{As}^\mathrm{V}\right)}~\mathrm{h}^{-1}` - - arsenate adsorption - * - K2 - - Const - - :math:`1.0` - - :math:`k_2` - - :math:`\textrm{L}~\mathrm{h}^{-1}` - - arsenate desporbtion - * - Smax - - Const - - :math:`50.0` - - :math:`S_{\max}` - - :math:`\require{upgreek}\upmu\mathrm{g}_{\left(\mathsf{As}^\mathrm{V}\right)}~\mathrm{m}^{-2}` - - arsenate adsorption limit - - - .. list-table:: Other terms - :header-rows: 1 - :widths: 3 3 12 3 - - * - Name - - Symbol - - Expression - - Units - * - Ks - - :math:`k_s` - - :math:`{k_1}/{k_2}` - - :math:`\require{upgreek}\upmu\mathrm{g}^{-1}_{\left(\mathsf{As}^\mathrm{V}\right)}` - - - .. list-table:: Pipe reactions [2]_ - :header-rows: 1 - :widths: 3 3 16 - - * - Species - - Type - - Expression - * - AS3 - - Rate - - :math:`-k_a \, {\mathsf{As}^\mathrm{III}} \, {\mathsf{NH_2Cl}}` - * - AS5 - - Rate - - :math:`k_a \, {\mathsf{As}^\mathrm{III}} \, {\mathsf{NH_2Cl}} -Av \left( k_1 \left(S_{\max}-{\mathsf{As}^\mathrm{V}_{s}} \right) {\mathsf{As}^\mathrm{V}} - k_2 \, {\mathsf{As}^\mathrm{V}_{s}} \right)` - * - NH2CL - - Rate - - :math:`-k_b \, {\mathsf{NH_2Cl}}` - * - AStot - - Formula - - :math:`{\mathsf{As}^\mathrm{III}} + {\mathsf{As}^\mathrm{V}}` - * - AS5s - - Equil - - :math:`k_s \, S_{\max} \frac{{\mathsf{As}^\mathrm{V}}}{1 + k_s \, {\mathsf{As}^\mathrm{V}}} - {\mathsf{As}^\mathrm{V}_{s}}` - - - .. list-table:: Tank reactions - :header-rows: 1 - :widths: 3 3 16 - - * - Species - - Type - - Expression - * - AS3 - - Rate - - :math:`-k_a \, {\mathsf{As}^\mathrm{III}} \, {\mathsf{NH_2Cl}}` - * - AS5 - - Rate - - :math:`k_a \, {\mathsf{As}^\mathrm{III}} \, {\mathsf{NH_2Cl}}` - * - NH2CL - - Rate - - :math:`-k_b \, {\mathsf{NH_2Cl}}` - * - AStot - - Formula - - :math:`{\mathsf{As}^\mathrm{III}} + {\mathsf{As}^\mathrm{V}}` - * - AS5s - - Equil - - :math:`0` (`not present in tanks`) - References - ---------- - This model is described in the EPANET-MSX user manual [SRU23]_ and was simplified from [GSCL94]_. - - .. [GSCL94] - B. Gu, J. Schmitt, Z. Chen, L. Liang, and J.F. McCarthy. "Adsorption and desorption of - natural organic matter on iron oxide: mechanisms and models". Environ. Sci. Technol., 28:38-46, January 1994. - - Notes - ----- - - .. [1] - The volume unit, :math:`\textrm{L}`, is defined by the network model flow units. - .. [2] - The :math:`Av` variable is the surface area per unit volume for the network (by pipe). - In this model, it has units of :math:`\mathrm{m}^{2} / \mathrm{L}` - """ - msx = MultispeciesQualityModel() - msx.title = "Arsenic Oxidation/Adsorption Example" - msx.add_species(name="AS3", species_type="BULK", units="UG", note="Dissolved arsenite") - msx.add_species(name="AS5", species_type="BULK", units="UG", note="Dissolved arsenate") - msx.add_species(name="AStot", species_type="BULK", units="UG", note="Total dissolved arsenic") - msx.add_species(name="AS5s", species_type="WALL", units="UG", note="Adsorbed arsenate") - msx.add_species(name="NH2CL", species_type="BULK", units="MG", note="Monochloramine") - msx.add_constant("Ka", 10.0, units="1 / (MG * HR)", note="Arsenite oxidation rate coefficient") - msx.add_constant("Kb", 0.1, units="1 / HR", note="Monochloramine decay rate coefficient") - msx.add_constant("K1", 5.0, units="M^3 / (UG * HR)", note="Arsenate adsorption coefficient") - msx.add_constant("K2", 1.0, units="1 / HR", note="Arsenate desorption coefficient") - msx.add_constant("Smax", 50.0, units="UG / M^2", note="Arsenate adsorption limit") - msx.add_term(name="Ks", expression="K1/K2", note="Equil. adsorption coeff.") - msx.add_reaction( - species="AS3", location="pipes", dynamics_type="rate", expression="-Ka*AS3*NH2CL", note="Arsenite oxidation" - ) - msx.add_reaction( - "AS5", "pipes", "rate", "Ka*AS3*NH2CL - Av*(K1*(Smax-AS5s)*AS5 - K2*AS5s)", note="Arsenate production less adsorption" - ) - msx.add_reaction( - species="NH2CL", location="pipes", dynamics_type="rate", expression="-Kb*NH2CL", note="Monochloramine decay" - ) - msx.add_reaction("AS5s", "pipe", "equil", "Ks*Smax*AS5/(1+Ks*AS5) - AS5s", note="Arsenate adsorption") - msx.add_reaction(species="AStot", location="pipes", dynamics_type="formula", expression="AS3 + AS5", note="Total arsenic") - msx.add_reaction( - species="AS3", location="tank", dynamics_type="rate", expression="-Ka*AS3*NH2CL", note="Arsenite oxidation" - ) - msx.add_reaction( - species="AS5", location="tank", dynamics_type="rate", expression="Ka*AS3*NH2CL", note="Arsenate production" - ) - msx.add_reaction( - species="NH2CL", location="tank", dynamics_type="rate", expression="-Kb*NH2CL", note="Monochloramine decay" - ) - msx.add_reaction(species="AStot", location="tanks", dynamics_type="formula", expression="AS3 + AS5", note="Total arsenic") - msx.options.area_units = "M2" - msx.options.rate_units = "HR" - msx.options.rtol = 0.001 - msx.options.atol = 0.0001 - msx.references.append(cite_msx()) - return msx - - -def batch_chloramine_decay(wn=None): - msx = MultispeciesQualityModel() - msx.title = "Batch chloramine decay example" - msx.options.area_units = "ft2" - msx.options.rate_units = "hr" - - msx.add_species("HOCL", "bulk", "mol", note="hypochlorous acid") - msx.add_species("NH3", "bulk", "mol", note="ammonia") - msx.add_species("NH2CL", "bulk", "mol", note="monochloramine") - msx.add_species("NHCL2", "bulk", "mol", note="dichloramine") - msx.add_species("I", "bulk", "mol", note="unknown intermediate") - msx.add_species("OCL", "bulk", "mol", note="hypochlorite ion") - msx.add_species("NH4", "bulk", "mol", note="ammonium ion") - msx.add_species("ALK", "bulk", "mol", note="total alkalinity") - msx.add_species("H", "bulk", "mol", note="hydrogen ion") - msx.add_species("OH", "bulk", "mol", note="hydroxide ion") - msx.add_species("CO3", "bulk", "mol", note="carbonate ion") - msx.add_species("HCO3", "bulk", "mol", note="bicarbonate ion") - msx.add_species("H2CO3", "bulk", "mol", note="dissolved carbon dioxide") - msx.add_species("chloramine", "bulk", "mmol", note="monochloramine in mmol/L") - - msx.add_parameter("k1", 1.5e10) - msx.add_parameter("k2", 7.6e-2) - msx.add_parameter("k3", 1.0e6) - msx.add_parameter("k4", 2.3e-3) - msx.add_parameter("k6", 2.2e8) - msx.add_parameter("k7", 4.0e5) - msx.add_parameter("k8", 1.0e8) - msx.add_parameter("k9", 3.0e7) - msx.add_parameter("k10", 55.0) - - msx.add_term("k5", "(2.5e7*H) + (4.0e4*H2CO3) + (800*HCO3)") - msx.add_term("a1", "k1 * HOCL * NH3") - msx.add_term("a2", "k2 * NH2CL") - msx.add_term("a3", "k3 * HOCL * NH2CL") - msx.add_term("a4", "k4 * NHCL2") - msx.add_term("a5", "k5 * NH2CL * NH2CL") - msx.add_term("a6", "k6 * NHCL2 * NH3 * H") - msx.add_term("a7", "k7 * NHCL2 * OH") - msx.add_term("a8", "k8 * I * NHCL2") - msx.add_term("a9", "k9 * I * NH2CL") - msx.add_term("a10", "k10 * NH2CL * NHCL2") - - msx.add_reaction("HOCL", PIPE, RATE, "-a1 + a2 - a3 + a4 + a8") - msx.add_reaction("NH3", PIPE, RATE, "-a1 + a2 + a5 - a6") - msx.add_reaction("NH2CL", PIPE, RATE, "a1 - a2 - a3 + a4 - a5 + a6 - a9 - a10") - msx.add_reaction("NHCL2", PIPE, RATE, "a3 - a4 + a5 - a6 - a7 - a8 - a10") - msx.add_reaction("I", PIPE, RATE, "a7 - a8 - a9") - msx.add_reaction("H", PIPE, RATE, "0") - msx.add_reaction("ALK", PIPE, RATE, "0") - msx.add_reaction("OCL", PIPE, EQUIL, "H * OCL - 3.16E-8 * HOCL") - msx.add_reaction("NH4", PIPE, EQUIL, "H * NH3 - 5.01e-10 * NH4") - msx.add_reaction("CO3", PIPE, EQUIL, "H * CO3 - 5.01e-11 * HCO3") - msx.add_reaction("H2CO3", PIPE, EQUIL, "H * HCO3 - 5.01e-7 * H2CO3") - msx.add_reaction("HCO3", PIPE, EQUIL, "ALK - HC03 - 2*CO3 - OH + H") - msx.add_reaction("OH", PIPE, EQUIL, "H * OH - 1.0e-14") - msx.add_reaction("chloramine", PIPE, FORMULA, "1000 * NH2CL") - - return msx + def __init__(self, extra_paths: List[str] = None, include_builtins=True, include_envvar_paths=True, load=True) -> None: + """A library of multispecies reaction definitions. + + Parameters + ---------- + extra_paths : List[str], optional + _description_, by default None + include_builtins : bool, optional + load files built-in with wntr, by default True + include_envvar_paths : bool, optional + load files from the paths specified in :envvar:`WNTR_RXN_LIBRARY_PATH`, by default True + load : bool, optional + load the files immediately on creation, by default True + + If this is a string, then it will be passed as the `duplicates` argument + to the load function. See :meth:`reset_and_reload` for more details. + + Raises + ------ + TypeError + if `extra_paths` is not a list + """ + if extra_paths is None: + extra_paths = list() + elif not isinstance(extra_paths, (list, tuple)): + raise TypeError("Expected a list or tuple, got {}".format(type(extra_paths))) + + self.__library_paths = list() + + self.__data = dict() + + if include_builtins: + default_path = os.path.abspath(resource_filename(__name__, "_library_data")) + if default_path not in self.__library_paths: + self.__library_paths.append(default_path) + + if include_envvar_paths: + environ_path = os.environ.get("WNTR_RXN_LIBRARY_PATH", None) + if environ_path: + lib_folders = environ_path.split(";") + for folder in lib_folders: + if folder not in self.__library_paths: + self.__library_paths.append(os.path.abspath(folder)) + + for folder in extra_paths: + self.__library_paths.append(os.path.abspath(folder)) + if load: + if isinstance(load, str): + self.reset_and_reload(duplicates=load) + else: + self.reset_and_reload() + + def __repr__(self) -> str: + if len(self.__library_paths > 3): + return "{}(initial_paths=[{}, ..., {}])".format( + self.__class__.__name__, repr(self.__library_paths[0]), repr(self.__library_paths[-1]) + ) + return "{}({})".format(self.__class__.__name__, repr(self.__library_paths)) + + def path_list(self) -> List[str]: + """Get the original list of paths used for this library. + + Returns + ------- + List[str] + a copy of the paths used to **initially** populate this library + """ + return self.__library_paths.copy() + + def reset_and_reload(self, duplicates: str = "error") -> List[Tuple[str, str, Any]]: + """Load data from the configured directories into a library of models. + + Note, this function is not recursive and does not 'walk' any of the library's + directories to look for subfolders. + + The ``duplicates`` argument specifies how models that have the same name, + or that have the same filename if a name isn't specified in the file, + are handled. This effectively changes the priority of the library's data + directories specified during library creation. + **Warning**, if two files in the same directory have models + with the same name, there is no guarantee which will be read in first. + + Parameters + ---------- + duplicates : {"error" | "skip" | "replace"}, optional + how to handle models with the same name, by default ``"error"``. + + A value of of ``"error"`` raises an exception and stops execution. A value of ``"skip"`` will + skip models with the same `name` as a model that already exists in the + library (prioritizing directories as described in the :class:`ReactionLibrary` + documentation). A value of ``"replace"`` will replace any existing model + with a model that is read in that has the same `name` (effecitvely, this + reverses the precedence of the library's configured directories by + prioritizing models in the last + user-specified directories, then models in the paths in envvar in reverse order, if + applicable, and giving lowest priority to builtin models). + + Raises + ------ + TypeError + if `duplicates` is not a string + ValueError + if `duplicates` is not a valid value + IOError + if `path_to_folder` is not a directory + KeyError + if `duplicates` is ``"error"`` and two models have the same name + + Returns + ------- + List[Tuple[str, str, Any]] + files that caused problems, with tuple elements: + + 0. the full path to the file that caused a problem; + 1. the reason for the problem; + 2. the model that was *not* included, or was removed, + or the exception that was raised when trying to read the file + """ + if duplicates and not isinstance(duplicates, str): + raise TypeError("The `duplicates` argument must be None or a string") + elif duplicates.lower() not in ["error", "skip", "replace"]: + raise ValueError('The `duplicates` argument must be None, "error", "skip", or "replace"') + + load_errors = list() + for folder in self.__library_paths: + errs = self.add_models_from_dir(folder, duplicates=duplicates) + load_errors.extend(errs) + return load_errors + + def add_models_from_dir(self, path_to_dir: str, duplicates: str = "error") -> List[Tuple[str, str, Union[MultispeciesQualityModel, Exception]]]: + """Load all valid model files in a folder. + + Note, this function is not recursive and does not 'walk' a directory tree. + + The ``duplicates`` argument specifies how models that have the same name, + or that have the same filename if a name isn't specified in the file, + are handled. **Warning**, if two files in the same directory have models + with the same name, there is no guarantee which will be read in first. + + + Parameters + ---------- + path_to_dir : str + the path to the folder to search + duplicates : {"error", "skip", "replace"}, optional + how to handle models with the same name, by default ``"error"`` + + A value of of ``"error"`` raises an exception and stops execution. A value + of ``"skip"`` will skip models with the same `name` as a model that already + exists in the library. A value of ``"replace"`` will replace any existing model + with a model that is read in that has the same `name`. + + Raises + ------ + TypeError + if `duplicates` is not a string + ValueError + if `duplicates` is not a valid value + IOError + if `path_to_folder` is not a directory + KeyError + if `duplicates` is ``"error"`` and two models have the same name + + Returns + ------- + str + the full path to the file that caused a problem; + str + the reason for the problem; + object + the model that was not included, was removed, or the exception raised + """ + if duplicates and not isinstance(duplicates, str): + raise TypeError("The `duplicates` argument must be None or a string") + elif duplicates.lower() not in ["error", "skip", "replace"]: + raise ValueError('The `duplicates` argument must be None, "error", "skip", or "replace"') + if not os.path.isdir(path_to_dir): + raise IOError("The following path is not valid/not a folder, {}".format(path_to_dir)) + load_errors = list() + folder = path_to_dir + files = os.listdir(folder) + for file in files: + ext = os.path.splitext(file)[1] + if ext is None or ext.lower() not in [".msx", ".json", ".yaml"]: + continue + if ext.lower() == ".msx": + try: + new = MultispeciesQualityModel(file) + except Exception as e: + logger.exception("Error reading file {}".format(os.path.join(folder, file))) + load_errors.append((os.path.join(folder, file), "load-failed", e)) + continue + elif ext.lower() == ".json": + with open(os.path.join(folder, file), "r") as fin: + try: + new = MultispeciesQualityModel.from_dict(json.load(fin)) + except Exception as e: + logger.exception("Error reading file {}".format(os.path.join(folder, file))) + load_errors.append((os.path.join(folder, file), "load-failed", e)) + continue + elif ext.lower() == ".yaml": + if yaml is None: + logger.exception("Error reading file {}".format(os.path.join(folder, file)), exc_info=yaml_err) + load_errors.append((os.path.join(folder, file), "load-failed", yaml_err)) + continue + with open(os.path.join(folder, file), "r") as fin: + try: + new = MultispeciesQualityModel.from_dict(yaml.safe_load(fin)) + except Exception as e: + logger.exception("Error reading file {}".format(os.path.join(folder, file))) + load_errors.append((os.path.join(folder, file), "load-failed", e)) + continue + else: # pragma: no cover + raise RuntimeError("This should be impossible to reach, since `ext` is checked above") + new._orig_file = os.path.join(folder, file) + if not new.name: + new.name = os.path.splitext(os.path.split(file)[1])[0] + if new.name not in self.__data: + self.__data[new.name] = new + else: # this name exists in the library + name = new.name + if not duplicates or duplicates.lower() == "error": + raise KeyError( + 'A model named "{}" already exists in the model; failed processing "{}"'.format( + new.name, os.path.join(folder, file) + ) + ) + elif duplicates.lower() == "skip": + load_errors.append((new._orig_file, "skipped", new)) + continue + elif duplicates.lower() == "replace": + old = self.__data[name] + load_errors.append((old._orig_file, "replaced", old)) + self.__data[name] = new + else: # pragma: no cover + raise RuntimeError("This should be impossible to get to, since `duplicates` is checked above") + return load_errors + + def add_model_from_file(self, path_and_filename: str, name: str = None): + """Load a reaction model from a file and add it to the model. + + Note, this **does not check** to see if a model exists with the same + name, and it will automatically overwrite the existing model if one + does exist. + + Parameters + ---------- + path_to_file : str + The full path **and** filename where the model is described. + name : str + The name to use for the model instead of the name provided in the + file or the filename. + """ + if not os.path.isfile(path_and_filename): + raise IOError("The following path does not identify a file, {}".format(path_and_filename)) + + ext = os.path.splitext(path_and_filename)[1] + if ext is None or ext.lower() not in [".msx", ".json", ".yaml"]: + raise IOError("The file is in an unknown format, {}".format(ext)) + if ext.lower() == ".msx": + new = MultispeciesQualityModel(path_and_filename) + elif ext.lower() == ".json": + with open(path_and_filename, "r") as fin: + new = MultispeciesQualityModel.from_dict(json.load(fin)) + elif ext.lower() == ".yaml": + if yaml is None: + raise RuntimeError("Unable to import yaml") from yaml_err + with open(path_and_filename, "r") as fin: + new = MultispeciesQualityModel.from_dict(yaml.safe_load(fin)) + else: # pragma: no cover + raise RuntimeError("This should be impossible to reach, since ext is checked above") + new._orig_file = path_and_filename + if not new.name: + new.name = os.path.splitext(os.path.split(path_and_filename)[1])[0] + if name is not None: + new.name = name + self.__data[new.name] = new + + def get_model(self, name: str) -> MultispeciesQualityModel: + """Get a reaction model from the library by model name + + Parameters + ---------- + name : str + the name of the model + + Returns + ------- + MultispeciesQualityModel + the model + """ + return self.__data[name] + + def model_name_list(self) -> List[str]: + """Get a list of model names in the library""" + return list(self.keys()) + + def __getitem__(self, __key: Any) -> Any: + return self.__data.__getitem__(__key) + + def __setitem__(self, __key: Any, __value: Any) -> None: + return self.__data.__setitem__(__key, __value) + + def __delitem__(self, __key: Any) -> None: + return self.__data.__delitem__(__key) + + def __contains__(self, __key: object) -> bool: + return self.__data.__contains__(__key) + + def __iter__(self) -> Iterator: + return self.__data.__iter__() + + def __len__(self) -> int: + return self.__data.__len__() + + def keys(self) -> KeysView: + return self.__data.keys() + + def items(self) -> ItemsView: + return self.__data.items() + + def values(self) -> ValuesView: + return self.__data.values() + + def clear(self) -> None: + return self.__data.clear() diff --git a/wntr/quality/multispecies.py b/wntr/quality/multispecies.py index a29e664e3..d96897b08 100644 --- a/wntr/quality/multispecies.py +++ b/wntr/quality/multispecies.py @@ -4,31 +4,34 @@ """ +from abc import abstractproperty import logging from typing import ( Any, Callable, Dict, - Iterator, List, Tuple, Union, ) +import warnings from wntr.epanet.util import ENcomment from wntr.network.elements import Source from wntr.network.model import PatternRegistry, SourceRegistry, WaterNetworkModel -from wntr.quality.base import WaterQualityReaction, WaterQualityVariable from wntr.utils.disjoint_mapping import DisjointMapping, KeyExistsError from .base import ( + WaterQualityReaction, + WaterQualityReactionSystem, + WaterQualityVariable, EXPR_TRANSFORMS, HYDRAULIC_VARIABLES, EXPR_FUNCTIONS, DynamicsType, - LocationType, + ReactionType, QualityVarType, SpeciesType, AnnotatedFloat, @@ -44,7 +47,7 @@ has_sympy = True except ImportError: sympy = None - logging.critical("This python installation does not have SymPy installed. Certain functionality will be disabled.") + logging.critical("This python installation does not have SymPy installed. " "Certain functionality will be disabled.") standard_transformations = (None,) convert_xor = None has_sympy = False @@ -60,7 +63,8 @@ "ReservedName", "HydraulicVariable", "MathFunction", - "VariableRegistry", + "Reaction", + "MultispeciesReactionSystem", "InitialQuality", "ParameterValues", "NetworkSpecificData", @@ -69,7 +73,19 @@ class Species(WaterQualityVariable): - """A biological or chemical species that impacts water quality.""" + """A biological or chemical species that impacts water quality. + + Attributes + ---------- + name : str + The name of the species + species_type : SpeciesType | str + The type of species, either "bulk" or "wall" + units : str + The units of mass used in expressions of concentration + diffusivity : float + The bulk diffusivity in water for bulk species + """ def __init__( self, @@ -81,15 +97,13 @@ def __init__( *, note=None, diffusivity: float = None, - pipe_reaction: "WaterQualityReaction" = None, - tank_reaction: "WaterQualityReaction" = None, _vars=None, _vals=None, ) -> None: """A biological or chemical species. - Arguments - --------- + Parameters + ---------- name : str The species name species_type : SpeciesType | str @@ -101,46 +115,37 @@ def __init__( rtol : float, optional The relative tolerance when solving this species' equations, by default None [1]_ - Keyword Arguments ----------------- note : str | dict | ENcomment, optional - Supplementary information regarding this variable, by default None (see :class:`~wntr.epanet.util.ENcomment` for dict structure) + Supplementary information regarding this variable, by default None + (see :class:`~wntr.epanet.util.ENcomment` for dict structure) diffusivity : float, optional Diffusivity of the species in water, by default None pipe_reaction : dict | MultispeciesReaction, optional Reaction dynamics of the species in pipes, by default None tank_reaction : dict | MultispeciesReaction, optional Reaction dynamics of the species in tanks, by default None - + _vars : VariableRegistry, optional + the variables registry object of the model this variable was added to, by default None + _vals : _type_, optional + _description_, by default None Raises ------ + KeyExistsError + if the name has already been used TypeError - if mandatory arguments are passed as None - TypeError - if a tank reaction is provided for a wall species - TypeError - if an invalid type is passed for a pipe or tank reaction + if mandatory arguments are passed as None; if a tank reaction is provided for a + wall species; if an invalid type is passed for a pipe or tank reaction .. [1] The `atol` and `rtol` arguments must both be None, or both be a float greater than 0. - - - .. rubric:: Developer-use Arguments - - The following function call parameters should only be used by a MultispeciesModel class - or model-building function; the user should not need to pass these arguments. - - Other Parameters - ---------------- - _vars : VariablesRegistry, optional - the variables registry object of the model this variable was added to, by default None - _vals : _type_, optional - _description_, by default None """ - super().__init__(name, note=note, _vars=_vars) + super().__init__(name, note=note) + if _vars is not None and name in _vars: + raise KeyExistsError("This variable name is already taken") species_type = SpeciesType.get(species_type) if species_type is None: raise TypeError("species_type cannot be None") @@ -154,34 +159,10 @@ def __init__( """ self.diffusivity: float = diffusivity """The diffusivity of this species in water, if being used, by default None""" - if species_type is SpeciesType.WALL and tank_reaction: - raise TypeError("Wall species tank_reaction must be None") - self.pipe_reaction: WaterQualityReaction = None - """The object that describes how this species reacts in pipes""" - self.tank_reaction: WaterQualityReaction = None - """The object that describes how this species reacts in tanks""" - if isinstance(pipe_reaction, WaterQualityReaction): - pipe_reaction.species = self - self.pipe_reaction = pipe_reaction - elif isinstance(pipe_reaction, dict): - pipe_reaction["location"] = "pipe" - pipe_reaction["species"] = self - self.pipe_reaction = self.add_reaction(**pipe_reaction) - elif pipe_reaction is None: - self.pipe_reaction = None + if _vars is not None and isinstance(_vars, MultispeciesReactionSystem): + self._vars = _vars else: - raise TypeError("The pipe_reaction is invalid") - if isinstance(tank_reaction, WaterQualityReaction): - tank_reaction.species = self - self.tank_reaction = tank_reaction - elif isinstance(tank_reaction, dict): - tank_reaction["location"] = "tank" - tank_reaction["species"] = self - self.tank_reaction = self.add_reaction(**tank_reaction) - elif tank_reaction is None: - self.tank_reaction = None - else: - raise TypeError("The tank_reaction is invalid") + self._vars = None if _vals is not None and isinstance(_vals, InitialQuality): self._vals = _vals else: @@ -221,8 +202,8 @@ def get_tolerances(self) -> Union[Tuple[float, float], None]: Returns ------- - (float, float) or None - absolute and relative tolerances, respectively, if they are set, otherwise returns None + Union[Tuple[float, float], None] + absolute and relative tolerances, respectively, if they are set """ return self._tolerances @@ -261,44 +242,20 @@ def initial_quality(self) -> "NetworkSpecificData": return self._vals else: raise TypeError("This species is not linked to a NetworkSpecificValues obejct, please `relink` your model") + + @property + def pipe_reaction(self): + if self._vars is not None: + return self._vars.pipe_reactions[self.name] + else: + raise AttributeError('This species is not connected to a ReactionSystem') - def add_reaction( - self, location: LocationType, dynamics_type: DynamicsType, expression: str, *, note: Any = None - ) -> "WaterQualityReaction": - """Add a reaction object to the species. - - Arguments - --------- - location : LocationType - where the reaction takes place, either PIPE or TANK - dynamics_type : DynamicsType - the type of dynamics described by the expression - expression : str - the reaction dynamics expression - - Keyword Arguments - ----------------- - note : str | dict | ENcomment, optional - Supplementary information regarding the reaction, by default None (see :class:`~wntr.epanet.util.ENcomment` for dict structure). - - Returns - ------- - MultispeciesReaction - the new reaction object - """ - location = LocationType.get(location, allow_none=False) - dynamics_type = DynamicsType.get(dynamics_type, allow_none=False) - new = WaterQualityReaction( - species=self, - dynamics_type=dynamics_type, - expression=expression, - note=note, - ) - if location is LocationType.PIPE: - self.pipe_reaction = new + @property + def tank_reaction(self): + if self._vars is not None: + return self._vars.tank_reactions[self.name] else: - self.tank_reaction = new - return new + raise AttributeError('This species is not connected to a ReactionSystem') def to_dict(self) -> Dict[str, Any]: """Create a dictionary representation of the object @@ -334,28 +291,6 @@ def to_dict(self) -> Dict[str, Any]: "diffusivity": { "type": "number", "minimum": 0 - }, - "pipe_reaction": { - "type": "object", - "properties": { - "dynamics_type": { - "enum": ["rate", "equil", "formula"] - }, - "expression": { - "type": "string" - } - } - }, - "tank_reaction": { - "type": "object", - "properties": { - "dynamics_type": { - "enum": ["rate", "equil", "formula"] - }, - "expression": { - "type": "string" - } - } } }, "required": ["name", "species_type", "units", "pipe_reaction", "tank_reaction"], @@ -375,16 +310,6 @@ def to_dict(self) -> Dict[str, Any]: elif isinstance(self.note, (str, dict, list)): ret["note"] = self.note - if self.pipe_reaction is not None: - pr = self.pipe_reaction.to_dict() - if "species" in pr: - del pr["species"] - ret["pipe_reaction"] = pr - if self.tank_reaction is not None: - tr = self.tank_reaction.to_dict() - if "species" in tr: - del tr["species"] - ret["tank_reaction"] = tr return ret @@ -401,29 +326,35 @@ def __init__(self, name: str, value: float, *, units: str = None, note=None, _va value : float The constant value. - Keyword Aguments - ---------------- + Keyword Arguments + ----------------- units : str, optional Units for the variable, by default None note : str | dict | ENcomment, optional - Supplementary information regarding this variable, by default None (see :class:`~wntr.epanet.util.ENcomment` for dict structure). - - - .. rubric:: Developer-use Arguments - - The following function call parameters should only be used by a MultispeciesModel class - or model-building function; the user should not need to pass these arguments. + Supplementary information regarding this variable, by default None + (see :class:`~wntr.epanet.util.ENcomment` for dict structure). Other Parameters ---------------- _vars : VariablesRegistry, optional the variables registry object of the model this variable was added to, by default None """ - super().__init__(name, note=note, _vars=_vars) + super().__init__(name, note=note) + if _vars is not None and name in _vars: + raise KeyExistsError("This variable name is already taken") self.value = float(value) """The value of the constant""" self.units = units """The units of the constant""" + if _vars is not None and isinstance(_vars, MultispeciesReactionSystem): + self._vars = _vars + elif _vars is None: + self._vars = None + else: + raise TypeError("Invalid type for _vars") + + def __call__(self, *, t=None) -> Any: + return self.value @property def var_type(self) -> QualityVarType: @@ -440,9 +371,6 @@ def to_dict(self) -> Dict[str, Any]: ret["note"] = self.note return ret - def __call__(self, *, t=None) -> Any: - return self.value - class Parameter(WaterQualityVariable): """A coefficient that is parameterized by pipe/tank.""" @@ -462,13 +390,8 @@ def __init__(self, name: str, global_value: float, *, units: str = None, note=No units : str, optional The units for this parameter, by default None note : str | dict | ENcomment, optional - Supplementary information regarding this variable, by default None (see :class:`~wntr.epanet.util.ENcomment` for dict structure). - - - .. rubric:: Developer-use Arguments - - The following function call parameters should only be used by a MultispeciesModel class - or model-building function; the user should not need to pass these arguments. + Supplementary information regarding this variable, by default None + (see :class:`~wntr.epanet.util.ENcomment` for dict structure). Other Parameters ---------------- @@ -478,26 +401,19 @@ def __init__(self, name: str, global_value: float, *, units: str = None, note=No Values for specific tanks or pipes, by default None. This argument should be passed by the MultispeciesModel during variable creation. """ - super().__init__(name, note=note, _vars=_vars) + super().__init__(name, note=note) + if _vars is not None and name in _vars: + raise KeyExistsError("This variable name is already taken") self.global_value = float(global_value) self.units = units + if _vars is not None and isinstance(_vars, MultispeciesReactionSystem): + self._vars = _vars + elif _vars is None: + self._vars = None + else: + raise TypeError("Invalid type for _vars") self._vals = _vals - @property - def var_type(self) -> QualityVarType: - """This is a parameterized coefficient.""" - return QualityVarType.PARAMETER - - def to_dict(self) -> Dict[str, Any]: - ret = dict(name=self.name, global_value=self.global_value) - if self.units: - ret["units"] = self.units - if isinstance(self.note, ENcomment): - ret["note"] = self.note.to_dict() - elif isinstance(self.note, (str, dict, list)): - ret["note"] = self.note - return ret - def __call__(self, *, t=None, pipe: float = None, tank: float = None) -> Any: if pipe is not None and tank is not None: raise TypeError("Both pipe and tank cannot be specified at the same time") @@ -509,6 +425,11 @@ def __call__(self, *, t=None, pipe: float = None, tank: float = None) -> Any: return self._vals.tank_values.get(pipe, self.global_value) return self.global_value + @property + def var_type(self) -> QualityVarType: + """This is a parameterized coefficient.""" + return QualityVarType.PARAMETER + def link_values(self, values: "ParameterValues"): """Link the paraemterized values to a model object. @@ -522,6 +443,16 @@ def link_values(self, values: "ParameterValues"): """ self._vals = values + def to_dict(self) -> Dict[str, Any]: + ret = dict(name=self.name, global_value=self.global_value) + if self.units: + ret["units"] = self.units + if isinstance(self.note, ENcomment): + ret["note"] = self.note.to_dict() + elif isinstance(self.note, (str, dict, list)): + ret["note"] = self.note + return ret + class Term(WaterQualityVariable): def __init__(self, name: str, expression: str, *, note=None, _vars=None) -> None: @@ -537,22 +468,25 @@ def __init__(self, name: str, expression: str, *, note=None, _vars=None) -> None Keyword Arguments ----------------- note : str | dict | ENcomment, optional - Supplementary information regarding this variable, by default None (see :class:`~wntr.epanet.util.ENcomment` for dict structure). - - - .. rubric:: Developer-use Arguments - - The following function call parameters should only be used by a MultispeciesModel class - or model-building function; the user should not need to pass these arguments. + Supplementary information regarding this variable, by default None + (see :class:`~wntr.epanet.util.ENcomment` for dict structure). Other Parameters ---------------- _vars : VariablesRegistry, optional the variables registry object of the model this variable was added to, by default None """ - super().__init__(name, note=note, _vars=_vars) + super().__init__(name, note=note) + if _vars is not None and name in _vars: + raise KeyExistsError("This variable name is already taken") self.expression = expression """The expression that is aliased by this term""" + if _vars is not None and isinstance(_vars, MultispeciesReactionSystem): + self._vars = _vars + elif _vars is None: + self._vars = None + else: + raise TypeError("Invalid type for _vars") @property def var_type(self) -> QualityVarType: @@ -569,7 +503,7 @@ def to_dict(self) -> Dict[str, Any]: class ReservedName(WaterQualityVariable): - def __init__(self, name: str, *, note=None, _vars: dict = None) -> None: + def __init__(self, name: str, *, note=None) -> None: """An object representing a reserved name that should not be used by the user. Arguments @@ -580,13 +514,8 @@ def __init__(self, name: str, *, note=None, _vars: dict = None) -> None: Keyword Arguments ----------------- note : str | dict | ENcomment, optional - Supplementary information regarding this variable, by default None (see :class:`~wntr.epanet.util.ENcomment` for dict structure). - - - .. rubric:: Developer-use Arguments - - The following function call parameters should only be used by a MultispeciesModel class - or model-building function; the user should not need to pass these arguments. + Supplementary information regarding this variable, by default None + (see :class:`~wntr.epanet.util.ENcomment` for dict structure). Other Parameters ---------------- @@ -598,11 +527,8 @@ def __init__(self, name: str, *, note=None, _vars: dict = None) -> None: KeyExistsError _description_ """ - if _vars is not None and name in _vars.keys(): - raise KeyExistsError("This variable name is already taken") self.name = name self.note = note - self._vars = _vars @property def var_type(self) -> QualityVarType: @@ -614,6 +540,8 @@ def to_dict(self) -> Dict[str, Any]: class HydraulicVariable(ReservedName): + """A variable representing instantaneous hydraulics data.""" + def __init__(self, name: str, units: str = None, *, note=None) -> None: """A variable representing instantaneous hydraulics data. @@ -627,11 +555,11 @@ def __init__(self, name: str, units: str = None, *, note=None) -> None: units : str, optional The units for hydraulic variable, by default None - Keyword Arguments ----------------- note : str | dict | ENcomment, optional - Supplementary information regarding this variable, by default None (see :class:`~wntr.epanet.util.ENcomment` for dict structure). + Supplementary information regarding this variable, by default None + (see :class:`~wntr.epanet.util.ENcomment` for dict structure). """ super().__init__(name, note=note) self.units = units @@ -639,6 +567,8 @@ def __init__(self, name: str, units: str = None, *, note=None) -> None: class MathFunction(ReservedName): + """A variable that is actually a mathematical function defined by MSX.""" + def __init__(self, name: str, func: Callable, *, note=None) -> None: """A variable that is actually a mathematical function defined by MSX. @@ -649,11 +579,11 @@ def __init__(self, name: str, func: Callable, *, note=None) -> None: func : Callable The callable function - Keyword Arguments ----------------- note : str | dict | ENcomment, optional - Supplementary information regarding this variable, by default None (see :class:`~wntr.epanet.util.ENcomment` for dict structure). + Supplementary information regarding this variable, by default None + (see :class:`~wntr.epanet.util.ENcomment` for dict structure). """ super().__init__(name, note=note) self.func = func @@ -663,51 +593,42 @@ def __call__(self, *args: Any, **kwds: Any) -> Any: return self.func(*args, **kwds) + class Reaction(WaterQualityReaction): - def __init__(self, species: Species, dynamics_type: DynamicsType, expression: str, *, note=None) -> None: - """A water quality biochemical reaction dynamics definition for a specific species. + """A water quality biochemical reaction dynamics definition for a specific species.""" - This object must be attached to a species in the appropriate pipe or tank reaction attribute. + def __init__(self, species_name: str, reaction_type: ReactionType, dynamics_type: DynamicsType, expression: str, *, note=None) -> None: + """A water quality biochemical reaction dynamics definition for a specific species. Arguments --------- - species : Species | str + species_name : Species | str The species (object or name) this reaction is applicable to. dynamics_type : DynamicsType The type of reaction dynamics being described by the expression: one of RATE, FORMULA, or EQUIL. expression : str The mathematical expression for the right-hand-side of the reaction equation. - Keyword Arguments ----------------- note : str | dict | ENcomment, optional - Supplementary information regarding this reaction, by default None (see :class:`~wntr.epanet.util.ENcomment` for dict structure). - - - Raises - ------ - TypeError - _description_ - TypeError - _description_ - TypeError - _description_ + Supplementary information regarding this reaction, by default None + (see :class:`~wntr.epanet.util.ENcomment` for dict structure). """ - super().__init__(dynamics_type, note=note) - if species is None: - raise TypeError("species cannot be None") + super().__init__(species_name=species_name, note=note) + dynamics_type = DynamicsType.get(dynamics_type) + reaction_type = ReactionType.get(reaction_type) + if reaction_type is None: + raise TypeError("Required argument reaction_type cannot be None") + if dynamics_type is None: + raise TypeError("Required argument dynamics_type cannot be None") + self.__reaction_type = reaction_type + self._dynamics_type = dynamics_type if not expression: raise TypeError("expression cannot be None") - self._species = species self.expression = expression """The mathematical expression (right-hand-side)""" - @property - def species(self) -> str: - """The name of the species that reaction dynamics is being described.""" - return str(self._species) - @property def dynamics_type(self) -> DynamicsType: """The type of dynamics being described. @@ -715,12 +636,13 @@ def dynamics_type(self) -> DynamicsType: """ return self._dynamics_type - def __str__(self) -> str: - """Return a string representation of the reaction""" - return "{}({}) = ".format(self.dynamics_type.name, self.species) + self.expression + @property + def reaction_type(self) -> ReactionType: + """The type of reaction""" + return self.__reaction_type def to_dict(self) -> dict: - ret = dict(species=str(self.species), dynamics_type=self.dynamics_type.name.lower(), expression=self.expression) + ret = dict(species_name=str(self.species_name), dynamics_type=self.dynamics_type.name.lower(), expression=self.expression) if isinstance(self.note, ENcomment): ret["note"] = self.note.to_dict() elif isinstance(self.note, (str, dict, list)): @@ -728,7 +650,7 @@ def to_dict(self) -> dict: return ret -class VariableRegistry: +class MultispeciesReactionSystem(WaterQualityReactionSystem): """A registry for all the variables registered in the multispecies reactions model. This object can be used like an immutable mapping, with the ``__len__``, ``__getitem__``, @@ -736,17 +658,17 @@ class VariableRegistry: """ def __init__(self) -> None: - self._vars = DisjointMapping() + """Create a new reaction system. + """ + super().__init__() self._vars.add_disjoint_group("reserved") self._species = self._vars.add_disjoint_group("species") self._const = self._vars.add_disjoint_group("constant") self._param = self._vars.add_disjoint_group("parameter") self._term = self._vars.add_disjoint_group("term") - - @property - def all_variables(self) -> Dict[str, WaterQualityVariable]: - """The dictionary view onto all variables""" - return self._vars + self._rxns = dict(pipe=dict(), tank=dict()) + self._pipes = self._rxns['pipe'] + self._tanks = self._rxns['tank'] @property def species(self) -> Dict[str, Species]: @@ -768,6 +690,16 @@ def terms(self) -> Dict[str, Term]: """The dictionary view onto only named terms""" return self._term + @property + def pipe_reactions(self) -> Dict[str, WaterQualityReaction]: + """The dictionary view onto pipe reactions""" + return self._pipes + + @property + def tank_reactions(self) -> Dict[str, WaterQualityReaction]: + """The dictionary view onto tank reactions""" + return self._tanks + def add_variable(self, obj: WaterQualityVariable) -> None: """Add a variable object to the registry. @@ -789,33 +721,41 @@ def add_variable(self, obj: WaterQualityVariable) -> None: if not isinstance(obj, WaterQualityVariable): raise TypeError("Expected WaterQualityVariable object") if obj.name in self: - raise KeyExistsError("Variable name {} already exists in model") + raise KeyExistsError("Variable name {} already exists in model".format(obj.name)) obj._vars = self self._vars.add_item_to_group(obj.var_type.name.lower(), obj.name, obj) - def __contains__(self, __key: object) -> bool: - return self._vars.__contains__(__key) + def add_reaction(self, obj: WaterQualityReaction) -> None: + """Add a reaction to the model - def __eq__(self, __value: object) -> bool: - return self._vars.__eq__(__value) - - def __ne__(self, __value: object) -> bool: - return self._vars.__ne__(__value) - - # def __delitem__(self, __key: str) -> None: - # return self._vars.__delitem__(__key) - - def __getitem__(self, __key: str) -> WaterQualityVariable: - return self._vars.__getitem__(__key) - - # def __setitem__(self, __key: str, __value: MultispeciesVariable) -> None: - # return self._vars.__setitem__(__key, __value) - - def __iter__(self) -> Iterator: - return self._vars.__iter__() + Parameters + ---------- + obj : WaterQualityReaction + _description_ - def __len__(self) -> int: - return self._vars.__len__() + Raises + ------ + TypeError + _description_ + KeyError + _description_ + """ + if not isinstance(obj, WaterQualityReaction): + raise TypeError("Expected WaterQualityReaction object") + if obj.species_name not in self: + raise KeyError("Species {} does not exist in the model".format(obj.species_name)) + self._rxns[obj.reaction_type.name.lower()][obj.species_name] = obj + + def all_variables(self): + """A generator looping through all variables""" + for k, v in self._vars.items(): + yield k, v.var_type.name.lower(), v + + def all_reactions(self): + """A generator looping through all reactions""" + for k2, v in self._rxns.items(): + for k1, v1 in v.items(): + yield k1, k2, v1 def to_dict(self): return dict( @@ -823,6 +763,8 @@ def to_dict(self): constants=[v.to_dict() for v in self._const.values()], parameters=[v.to_dict() for v in self._param.values()], terms=[v.to_dict() for v in self._term.values()], + pipe_reactions=[v.to_dict() for v in self.pipe_reactions.values()], + tank_reactions=[v.to_dict() for v in self.tank_reactions.values()], ) @@ -846,6 +788,11 @@ def __init__(self, global_value: float = 0.0, node_values: dict = None, link_val self._node_values = node_values if node_values is not None else dict() self._link_values = link_values if link_values is not None else dict() + def __repr__(self) -> str: + return self.__class__.__name__ + "(global_value={}, node_values=<{} entries>, link_values=<{} entries>)".format( + self.global_value, len(self._node_values), len(self._link_values) + ) + @property def node_values(self) -> Dict[str, float]: """A mapping of node names to initial quality values for this species""" @@ -859,11 +806,6 @@ def link_values(self) -> Dict[str, float]: def to_dict(self) -> Dict[str, Dict[str, float]]: return dict(global_value=self.global_value, node_values=self._node_values.copy(), link_values=self._link_values.copy()) - def __repr__(self) -> str: - return self.__class__.__name__ + "(global_value={}, node_values=<{} entries>, link_values=<{} entries>)".format( - self.global_value, len(self._node_values), len(self._link_values) - ) - class ParameterValues: """A container for pipe and tank specific values of a parameter for a specific network.""" @@ -881,6 +823,11 @@ def __init__(self, *, pipe_values: dict = None, tank_values: dict = None) -> Non self._pipe_values = pipe_values if pipe_values is not None else dict() self._tank_values = tank_values if tank_values is not None else dict() + def __repr__(self) -> str: + return self.__class__.__name__ + "(pipe_values=<{} entries>, tank_values=<{} entries>)".format( + len(self._pipe_values), len(self._tank_values) + ) + @property def pipe_values(self) -> Dict[str, float]: """View onto the pipe values dictionary""" @@ -894,20 +841,46 @@ def tank_values(self) -> Dict[str, float]: def to_dict(self) -> Dict[str, Dict[str, float]]: return dict(pipe_values=self._pipe_values.copy(), tank_values=self._tank_values.copy()) - def __repr__(self) -> str: - return self.__class__.__name__ + "(pipe_values=<{} entries>, tank_values=<{} entries>)".format( - len(self._pipe_values), len(self._tank_values) - ) - class NetworkSpecificData: + """A container for network-specific values associated with a multispecies water quality model.""" - def __init__(self) -> None: - """A container for network-specific values associated with a multispecies water quality model.""" + def __init__(self, patterns: dict = None, sources: dict = None, initial_quality: dict = None, parameter_values: dict = None) -> None: + """A container for network-specific values associated with a multispecies water quality model. + + Data is copied from dictionaries passed in, so once created, the dictionaries passed are not connected + to this object. + + Parameters + ---------- + patterns : Dict[str, List[float]] + patterns to use for sources + sources : Dict[str, dict] + sources defined for the model + initial_quality : Dict[str, dict] + initial values for different species at different nodes, links, and the global value + parameter_values : Dict[str, dict] + parameter values for different pipes and tanks + """ + if sources is None: + sources = dict() + if initial_quality is None: + initial_quality = dict() + if patterns is None: + patterns = dict() + if parameter_values is None: + parameter_values = dict() self._source_dict = dict() - self._initial_quality_dict: Dict[str, InitialQuality] = dict() self._pattern_dict = dict() + self._initial_quality_dict: Dict[str, InitialQuality] = dict() self._parameter_value_dict: Dict[str, ParameterValues] = dict() + + self._source_dict = sources.copy() + self._pattern_dict = patterns.copy() + for k, v in initial_quality.items(): + self._initial_quality_dict[k] = InitialQuality(**v) + for k, v in parameter_values.items(): + self._parameter_value_dict[k] = ParameterValues(**v) @property def sources(self): @@ -946,7 +919,7 @@ def add_pattern(self, name: str, multipliers: List[float]): """ self._pattern_dict[name] = multipliers - def new_quality_values(self, species: Species): + def init_new_species(self, species: Species): """(Re)set the initial quality values for a species to a new container Arguments @@ -979,7 +952,7 @@ def remove_species(self, species: Union[Species, str]): except KeyError: pass - def new_parameter_values(self, param: Parameter): + def init_new_parameter(self, param: Parameter): """(Re)initialize parameter values for a parameter. Arguments @@ -1021,7 +994,7 @@ def to_dict(self): ret["sources"] = self._source_dict.copy() ret["patterns"] = self._pattern_dict.copy() return ret - + class MultispeciesQualityModel: """A multispecies water quality model for use with WNTR EPANET-MSX simulator.""" @@ -1039,21 +1012,37 @@ def __init__(self, msx_file_name=None) -> None: self.title: str = None """The title line from the MSX file, must be a single line""" self.desc: str = None - """A longer description, converted to comments in the top of an MSX file""" - self._msxfile: str = None + """A longer description, note that multi-line descriptions may not be + represented well in dictionary form.""" + self._orig_file: str = None """The original filename""" self._references: List[Union[str, Dict[str, str]]] = list() self._options = MultispeciesOptions() - self._vars = VariableRegistry() - self._net = NetworkSpecificData() + self._reaction_system = MultispeciesReactionSystem() + self._network_data = NetworkSpecificData() self._wn = None for v in HYDRAULIC_VARIABLES: - self._vars.add_variable(HydraulicVariable(**v)) + self._reaction_system.add_variable(HydraulicVariable(**v)) for k, v in EXPR_FUNCTIONS.items(): - self._vars.add_variable(MathFunction(name=k.lower(), func=v)) - self._vars.add_variable(MathFunction(name=k.capitalize(), func=v)) - self._vars.add_variable(MathFunction(name=k.upper(), func=v)) + self._reaction_system.add_variable(MathFunction(name=k.lower(), func=v)) + self._reaction_system.add_variable(MathFunction(name=k.capitalize(), func=v)) + self._reaction_system.add_variable(MathFunction(name=k.upper(), func=v)) + + if msx_file_name is not None: + from wntr.epanet.msx.io import MsxFile + MsxFile.read(msx_file_name, self) + + def __repr__(self) -> str: + ret = '{}('.format(self.__class__.__name__) + if self.name: + ret = ret + 'name={}'.format(repr(self.name)) + elif self.title: + ret = ret + 'title={}'.format(repr(self.title)) + elif self._orig_file: + ret = ret + 'msx_file_name={}'.format(repr(self._orig_file)) + ret = ret + ')' + return ret @property def references(self) -> List[Union[str, Dict[str, str]]]: @@ -1064,20 +1053,50 @@ def references(self) -> List[Union[str, Dict[str, str]]]: return self._references @property - def vars(self) -> VariableRegistry: + def reaction_system(self) -> MultispeciesReactionSystem: """The reaction variables defined for this model.""" - return self._vars + return self._reaction_system + + @property + def rxn_sys(self) -> MultispeciesReactionSystem: + """Alias for the reaction_system property for ease of programming""" + return self._reaction_system @property - def net(self) -> NetworkSpecificData: + def network_data(self) -> NetworkSpecificData: """The network-specific values added to this model.""" - return self._net + return self._network_data + + @property + def net_data(self) -> NetworkSpecificData: + """Alias for the reaction_system property for ease of programming""" + return self._network_data @property def options(self) -> MultispeciesOptions: """The MSX model options""" return self._options + @property + def species_name_list(self) -> List[str]: + """all defined species names""" + return list(self.reaction_system.species.keys()) + + @property + def constant_name_list(self) -> List[str]: + """all defined coefficient names""" + return list(self.reaction_system.constants.keys()) + + @property + def parameter_name_list(self) -> List[str]: + """all defined coefficient names""" + return list(self.reaction_system.parameters.keys()) + + @property + def term_name_list(self) -> List[str]: + """all defined function (MSX 'terms') names""" + return list(self.reaction_system.terms.keys()) + @options.setter def options(self, value): if isinstance(value, dict): @@ -1097,8 +1116,6 @@ def add_species( *, note: Any = None, diffusivity: float = None, - pipe_reaction: dict = None, - tank_reaction: dict = None, ) -> Species: """Add a species to the model @@ -1118,30 +1135,27 @@ def add_species( Keyword Arguments ----------------- note : str | dict | ENcomment, optional - Supplementary information regarding this variable, by default None (see :class:`~wntr.epanet.util.ENcomment` for dict structure). + Supplementary information regarding this variable, by default None + (see :class:`~wntr.epanet.util.ENcomment` for dict structure). diffusivity : float, optional Diffusivity in water for this species. - pipe_reaction : dict, optional - A dictionary that can be passed to the species' reaction builder - tank_reaction : dict, optional - A dictionary that can be passed to the species' reaction builder - - Returns - ------- - Species - _description_ Raises ------ KeyError _description_ + + Returns + ------- + Species + _description_ """ - if name in self._vars: + if name in self._reaction_system: raise KeyError( - "Variable named {} already exists in model as type {}".format(name, self._vars._vars.get_groupname(name)) + "Variable named {} already exists in model as type {}".format(name, self._reaction_system._vars.get_groupname(name)) ) species_type = SpeciesType.get(species_type, allow_none=False) - iq = self.net.new_quality_values(name) + iq = self.network_data.init_new_species(name) new = Species( name=name, species_type=species_type, @@ -1149,13 +1163,11 @@ def add_species( atol=atol, rtol=rtol, note=note, - _vars=self._vars, + _vars=self._reaction_system, _vals=iq, diffusivity=diffusivity, - pipe_reaction=pipe_reaction, - tank_reaction=tank_reaction, ) - self.vars.add_variable(new) + self.reaction_system.add_variable(new) return new def remove_species(self, species): @@ -1167,9 +1179,9 @@ def remove_species(self, species): _description_ """ name = str(species) - self.net.remove_species(name) + self.network_data.remove_species(name) # FIXME: validate additional items - self.vars.__delitem__(name) + self.reaction_system.__delitem__(name) def add_constant(self, name: str, value: float, *, units: str = None, note: Any = None) -> Constant: """Add a constant coefficient to the model. @@ -1186,24 +1198,25 @@ def add_constant(self, name: str, value: float, *, units: str = None, note: Any units : str, optional _description_, by default None note : str | dict | ENcomment, optional - Supplementary information regarding this variable, by default None (see :class:`~wntr.epanet.util.ENcomment` for dict structure). - - Returns - ------- - Constant - _description_ + Supplementary information regarding this variable, by default None + (see :class:`~wntr.epanet.util.ENcomment` for dict structure). Raises ------ KeyError _description_ + + Returns + ------- + Constant + _description_ """ - if name in self._vars: + if name in self._reaction_system: raise KeyError( - "Variable named {} already exists in model as type {}".format(name, self._vars._vars.get_groupname(name)) + "Variable named {} already exists in model as type {}".format(name, self._reaction_system._vars.get_groupname(name)) ) - new = Constant(name=name, value=value, units=units, note=note, _vars=self._vars) - self.vars.add_variable(new) + new = Constant(name=name, value=value, units=units, note=note, _vars=self._reaction_system) + self.reaction_system.add_variable(new) return new def remove_constant(self, const): @@ -1216,7 +1229,7 @@ def remove_constant(self, const): """ name = str(const) # FIXME: validate deletion - self.vars.__delitem__(name) + self.reaction_system.__delitem__(name) def add_parameter(self, name: str, global_value: float, *, units: str = None, note: Any = None) -> Parameter: """Add a parameterized coefficient to the model. @@ -1233,25 +1246,26 @@ def add_parameter(self, name: str, global_value: float, *, units: str = None, no units : str, optional _description_, by default None note : str | dict | ENcomment, optional - Supplementary information regarding this variable, by default None (see :class:`~wntr.epanet.util.ENcomment` for dict structure). - - Returns - ------- - Parameter - _description_ + Supplementary information regarding this variable, by default None + (see :class:`~wntr.epanet.util.ENcomment` for dict structure). Raises ------ KeyError _description_ + + Returns + ------- + Parameter + _description_ """ - if name in self._vars: + if name in self._reaction_system: raise KeyError( - "Variable named {} already exists in model as type {}".format(name, self._vars._vars.get_groupname(name)) + "Variable named {} already exists in model as type {}".format(name, self._reaction_system._vars.get_groupname(name)) ) - pv = self.net.new_parameter_values(name) - new = Parameter(name=name, global_value=global_value, units=units, note=note, _vars=self._vars, _vals=pv) - self.vars.add_variable(new) + pv = self.network_data.init_new_parameter(name) + new = Parameter(name=name, global_value=global_value, units=units, note=note, _vars=self._reaction_system, _vals=pv) + self.reaction_system.add_variable(new) return new def remove_parameter(self, param): @@ -1263,9 +1277,9 @@ def remove_parameter(self, param): _description_ """ name = str(param) - self.net.remove_parameter(name) + self.network_data.remove_parameter(name) # FIXME: validate additional items - self.vars.__delitem__(name) + self.reaction_system.__delitem__(name) def add_term(self, name: str, expression: str, *, note: Any = None) -> Term: """Add a named expression (term) to the model. @@ -1280,24 +1294,25 @@ def add_term(self, name: str, expression: str, *, note: Any = None) -> Term: Keyword Arguments ----------------- note : str | dict | ENcomment, optional - Supplementary information regarding this variable, by default None (see :class:`~wntr.epanet.util.ENcomment` for dict structure). - - Returns - ------- - Term - _description_ + Supplementary information regarding this variable, by default None + (see :class:`~wntr.epanet.util.ENcomment` for dict structure). Raises ------ KeyError _description_ + + Returns + ------- + Term + _description_ """ - if name in self._vars: + if name in self._reaction_system: raise KeyError( - "Variable named {} already exists in model as type {}".format(name, self._vars._vars.get_groupname(name)) + "Variable named {} already exists in model as type {}".format(name, self._reaction_system._vars.get_groupname(name)) ) - new = Term(name=name, expression=expression, note=note, _vars=self._vars) - self.vars.add_variable(new) + new = Term(name=name, expression=expression, note=note, _vars=self._reaction_system) + self.reaction_system.add_variable(new) return new def remove_term(self, term): @@ -1310,23 +1325,25 @@ def remove_term(self, term): """ name = str(term) # FIXME: validate deletion - self.vars.__delitem__(name) + self.reaction_system.__delitem__(name) def add_reaction( - self, species: Species, location: LocationType, dynamics_type: DynamicsType, expression: str, *, note: Any = None + self, species_name: str, reaction_type: ReactionType, dynamics_type: DynamicsType, expression: str, *, note: Any = None ) -> WaterQualityReaction: """Add a reaction to a species in the model. - Note that all species need to have both a pipe and tank reaction defined unless all species are bulk species and - the tank reactions are identical to the pipe reactions. However, it is not recommended that users take this approach. + Note that all species need to have both a pipe and tank reaction defined + unless all species are bulk species and + the tank reactions are identical to the pipe reactions. However, it is not + recommended that users take this approach. Once added, access the reactions from the species' object. Arguments --------- - species : Species + species_name : str _description_ - location : LocationType + location_type : LocationType _description_ dynamics_type : DynamicsType _description_ @@ -1336,29 +1353,30 @@ def add_reaction( Keyword Arguments ----------------- note : str | dict | ENcomment, optional - Supplementary information regarding this reaction, by default None (see :class:`~wntr.epanet.util.ENcomment` for dict structure). - - Returns - ------- - MultispeciesReaction - _description_ + Supplementary information regarding this reaction, by default None + (see :class:`~wntr.epanet.util.ENcomment` for dict structure). Raises ------ TypeError _description_ + + Returns + ------- + MultispeciesReaction + _description_ """ - species = str(species) - species = self.vars.species[species] + species_name = str(species_name) + species = self.reaction_system.species[species_name] if species.var_type is not QualityVarType.SPECIES: - raise TypeError("Variable {} is not a Species, is a {}".format(species, species.var_type)) - if isinstance(location, str): - location.replace("_reaction", "") - location = LocationType.get(location, allow_none=False) + raise TypeError("Variable {} is not a Species, is a {}".format(species.name, species.var_type)) + reaction_type = ReactionType.get(reaction_type, allow_none=False) dynamics_type = DynamicsType.get(dynamics_type, allow_none=False) - return species.add_reaction(location=location, dynamics_type=dynamics_type, expression=expression, note=note) + new = Reaction(reaction_type=reaction_type, dynamics_type=dynamics_type, species_name=species_name, expression=expression, note=note) + self.reaction_system.add_reaction(new) + return new - def remove_reaction(self, species: str, location: LocationType) -> None: + def remove_reaction(self, species_name: str, reaction_type: ReactionType) -> None: """Remove a reaction at a specified location from a species. Parameters @@ -1368,46 +1386,67 @@ def remove_reaction(self, species: str, location: LocationType) -> None: location : LocationType the location to remove the reaction from """ - location = LocationType.get(location, allow_none=False) - species = str(species) - spec_obj = self.vars.species[species] - if location is LocationType.PIPE: - spec_obj.pipe_reaction = None - elif location is LocationType.TANK: - spec_obj.tank_reaction = None - else: - raise ValueError("Unknown location, {}".format(location)) - - @property - def species_name_list(self) -> List[str]: - """all defined species names""" - return list(self.vars.species.keys()) - - @property - def constant_name_list(self) -> List[str]: - """all defined coefficient names""" - return list(self.vars.constants.keys()) - - @property - def parameter_name_list(self) -> List[str]: - """all defined coefficient names""" - return list(self.vars.parameters.keys()) - - @property - def term_name_list(self) -> List[str]: - """all defined function (MSX 'terms') names""" - return list(self.vars.terms.keys()) + reaction_type = ReactionType.get(reaction_type, allow_none=False) + species_name = str(species_name) + del self.reaction_system.all_reactions[reaction_type.name.lower()][species_name] def to_dict(self): from wntr import __version__ - return dict( - version="wntr-{}".format(__version__), - name=self.name, - title=self.title, - desc=self.desc, - references=self.references.copy(), - variables=self.vars.to_dict(), - net_specific=self.net.to_dict(), - options=self.options.to_dict(), - ) + return { + 'wntr-version': "{}".format(__version__), + 'name': self.name, + 'title': self.title, + 'desc': self.desc if self.desc is None or '\n' not in self.desc else self.desc.splitlines(), + 'references': self.references.copy(), + 'reaction_system': self.reaction_system.to_dict(), + 'network_data': self.network_data.to_dict(), + 'options': self.options.to_dict(), + } + + @classmethod + def from_dict(cls, data): + from wntr import __version__ + + ver = data.get('wntr-version', None) + if ver > __version__: + logger.warn('Importing from a file created by a newer version of wntr, compatibility not guaranteed') + warnings.warn('Importing from a file created by a newer version of wntr, compatibility not guaranteed') + new = cls() + new.name = data.get('name', None) + new.title = data.get('title', None) + new.desc = data.get('desc', None) + if isinstance(new.desc, (list, tuple)): + desc = '\n'.join(new.desc) + new.desc = desc + new.references.extend(data.get('references', list())) + + rxn_sys = data.get('reaction_system', dict()) + for var in rxn_sys.get('species', list()): + new.add_species(**var) + for var in rxn_sys.get('constants', list()): + new.add_constant(**var) + for var in rxn_sys.get('parameters', list()): + new.add_parameter(**var) + for var in rxn_sys.get('terms', list()): + new.add_term(**var) + for rxn in rxn_sys.get('pipe_reactions', list()): + rxn['reaction_type'] = 'pipe' + new.add_reaction(**rxn) + for rxn in rxn_sys.get('tank_reactions', list()): + rxn['reaction_type'] = 'tank' + new.add_reaction(**rxn) + + new._network_data = NetworkSpecificData(**data.get('network_data', dict())) + for species in new.rxn_sys.species: + if species not in new.net_data.initial_quality: + new.net_data.init_new_species(species) + for param in new.rxn_sys.parameters: + if param not in new.net_data.parameter_values: + new.net_data.init_new_parameter(param) + + opts = data.get('options', None) + if opts: + new.options = opts + + return new diff --git a/wntr/quality/options.py b/wntr/quality/options.py index 1814c9fba..b91c2c9f9 100644 --- a/wntr/quality/options.py +++ b/wntr/quality/options.py @@ -12,31 +12,6 @@ class ReportOptions(_OptionsBase): """ Options related to EPANET-MSX report outputs. - - Parameters - ---------- - report_filename : str - Provides the filename to use for outputting an EPANET report file, - by default this will be the prefix plus ".rpt". - - species : dict[str, bool] - Output species concentrations - - species_precision : dict[str, float] - Output species concentrations with the specified precision - - nodes : None, "ALL", or list - Output node information in report file. If a list of node names is provided, - EPANET only provides report information for those nodes. - - links : None, "ALL", or list - Output link information in report file. If a list of link names is provided, - EPANET only provides report information for those links. - - pagesize : str - Page size for EPANET report output - - """ def __init__( @@ -48,6 +23,33 @@ def __init__( nodes: Union[Literal["ALL"], List[str]] = None, links: Union[Literal["ALL"], List[str]] = None, ): + """ + Options related to EPANET-MSX report outputs. + + Parameters + ---------- + report_filename : str + Provides the filename to use for outputting an EPANET report file, + by default this will be the prefix plus ".rpt". + + species : dict[str, bool] + Output species concentrations + + species_precision : dict[str, float] + Output species concentrations with the specified precision + + nodes : None, "ALL", or list + Output node information in report file. If a list of node names is provided, + EPANET only provides report information for those nodes. + + links : None, "ALL", or list + Output link information in report file. If a list of link names is provided, + EPANET only provides report information for those links. + + pagesize : str + Page size for EPANET report output + + """ self.pagesize = pagesize """The pagesize for the report""" self.report_filename = report_filename @@ -71,35 +73,6 @@ def __setattr__(self, name, value): class MultispeciesOptions(_OptionsBase): """ Multispecies quality model options. - - Parameters - ---------- - timestep : int >= 1 - Water quality timestep (seconds), by default 60 (one minute). - area_units : str, optional - The units of area to use in surface concentration forms, by default ``M2``. Valid values are ``FT2``, ``M2``, or ``CM2``. - rate_units : str, optional - The time units to use in all rate reactions, by default ``MIN``. Valid values are ``SEC``, ``MIN``, ``HR``, or ``DAY``. - solver : str, optional - The solver to use, by default ``RK5``. Options are ``RK5`` (5th order Runge-Kutta method), ``ROS2`` (2nd order Rosenbrock method), or ``EUL`` (Euler method). - coupling : str, optional - Use coupling method for solution, by default ``NONE``. Valid options are ``FULL`` or ``NONE``. - atol : float, optional - Absolute concentration tolerance, by default 0.01 (regardless of species concentration units). - rtol : float, optional - Relative concentration tolerance, by default 0.001 (±0.1%). - compiler : str, optional - Whether to use a compiler, by default ``NONE``. Valid options are ``VC``, ``GC``, or ``NONE`` - segments : int, optional - Maximum number of segments per pipe (MSX 2.0 or newer only), by default 5000. - peclet : int, optional - Peclet threshold for applying dispersion (MSX 2.0 or newer only), by default 1000. - - Other Parameters - ---------------- - report : ReportOptions or dict - Options on how to report out results. - """ def __init__( @@ -117,6 +90,35 @@ def __init__( # global_initial_quality: Dict[str, float] = None, report: ReportOptions = None, ): + """ + Multispecies quality model options. + + Parameters + ---------- + timestep : int >= 1 + Water quality timestep (seconds), by default 60 (one minute). + area_units : str, optional + The units of area to use in surface concentration forms, by default ``M2``. Valid values are ``FT2``, ``M2``, or ``CM2``. + rate_units : str, optional + The time units to use in all rate reactions, by default ``MIN``. Valid values are ``SEC``, ``MIN``, ``HR``, or ``DAY``. + solver : str, optional + The solver to use, by default ``RK5``. Options are ``RK5`` (5th order Runge-Kutta method), ``ROS2`` (2nd order Rosenbrock method), or ``EUL`` (Euler method). + coupling : str, optional + Use coupling method for solution, by default ``NONE``. Valid options are ``FULL`` or ``NONE``. + atol : float, optional + Absolute concentration tolerance, by default 0.01 (regardless of species concentration units). + rtol : float, optional + Relative concentration tolerance, by default 0.001 (±0.1%). + compiler : str, optional + Whether to use a compiler, by default ``NONE``. Valid options are ``VC``, ``GC``, or ``NONE`` + segments : int, optional + Maximum number of segments per pipe (MSX 2.0 or newer only), by default 5000. + peclet : int, optional + Peclet threshold for applying dispersion (MSX 2.0 or newer only), by default 1000. + report : ReportOptions or dict + Options on how to report out results. + + """ self.timestep: int = timestep """The timestep, in seconds, by default 360""" self.area_units: str = area_units diff --git a/wntr/sim/epanet.py b/wntr/sim/epanet.py index 934324578..c74905b45 100644 --- a/wntr/sim/epanet.py +++ b/wntr/sim/epanet.py @@ -102,9 +102,11 @@ def run_sim(self, file_prefix='temp', save_hyd=False, use_hyd=False, hydfile=Non inpfile = file_prefix + '.inp' write_inpfile(self._wn, inpfile, units=self._wn.options.hydraulic.inpfile_units, version=version) enData = wntr.epanet.toolkit.ENepanet(version=version) + self.enData = enData rptfile = file_prefix + '.rpt' outfile = file_prefix + '.bin' - + if self._wn._msx is not None: + save_hyd = True if hydfile is None: hydfile = file_prefix + '.hyd' enData.ENopen(inpfile, rptfile, outfile) @@ -127,5 +129,25 @@ def run_sim(self, file_prefix='temp', save_hyd=False, use_hyd=False, hydfile=Non results = self.reader.read(outfile, convergence_error, self._wn.options.hydraulic.headloss=='D-W') + if self._wn._msx is not None: + msxfile = file_prefix + '.msx' + rptfile = file_prefix + '.msx-rpt' + binfile = file_prefix + '.msx-bin' + msxfile2 = file_prefix + '.check.msx' + wntr.epanet.msx.io.MsxFile.write(msxfile, self._wn._msx) + msx = wntr.epanet.msx.MSXepanet(inpfile, rptfile, outfile, msxfile) + msx.ENopen(inpfile, rptfile, outfile) + msx.MSXopen(msxfile) + msx.MSXusehydfile(hydfile) + msx.MSXinit() + msx.MSXsolveH() + msx.MSXsolveQ() + msx.MSXreport() + msx.MSXsaveoutfile(binfile) + msx.MSXsavemsxfile(msxfile2) + msx.MSXclose() + msx.ENclose() + results = wntr.epanet.msx.io.MsxBinFile(binfile, self._wn, results) + return results diff --git a/wntr/tests/test_quality_variables.py b/wntr/tests/test_quality_variables.py index e14357fbb..7deb011cc 100644 --- a/wntr/tests/test_quality_variables.py +++ b/wntr/tests/test_quality_variables.py @@ -24,14 +24,14 @@ def tearDownClass(self): pass def test_ReactionVariable_reserved_name_exception(self): - self.assertRaises(ValueError, wntr.quality.BulkSpecies, "D", "mg") - self.assertRaises(ValueError, wntr.quality.WallSpecies, "Q", "mg") + self.assertRaises(ValueError, wntr.quality.Species, 'bulk', "D", "mg") + self.assertRaises(ValueError, wntr.quality.Species, 'wall', "Q", "mg") self.assertRaises(ValueError, wntr.quality.Constant, "Re", 0.52) self.assertRaises(ValueError, wntr.quality.Parameter, "Re", 0.52) self.assertRaises(ValueError, wntr.quality.OtherTerm, "Re", 0.52) def test_RxnVariable_symbols_and_sympy(self): - species1 = wntr.quality.BulkSpecies("Cl", "mg") + species1 = wntr.quality.Species('BULK', "Cl", "mg") symbol1 = sympy.symbols("Cl") self.assertEqual(species1.symbol, symbol1) @@ -60,8 +60,8 @@ def test_RxnVariable_values(self): self.assertRaises(TypeError, param2.get_value, pipe="PIPE", tank="TANK") def test_RxnVariable_string_functions(self): - species1 = wntr.quality.BulkSpecies("Cl", "mg") - species2 = wntr.quality.WallSpecies("Cl", "mg", 0.01, 0.0001, note="Testing stuff") + species1 = wntr.quality.Species('BULK', "Cl", "mg") + species2 = wntr.quality.Species('WALL', "Cl", "mg", 0.01, 0.0001, note="Testing stuff") const1 = wntr.quality.Constant("Kb", 0.482) param1 = wntr.quality.Parameter("Ka", 0.482, note="foo") term1 = wntr.quality.OtherTerm("T0", "-3.2 * Kb * Cl^2", note="bar") @@ -73,8 +73,8 @@ def test_RxnVariable_string_functions(self): def test_Species_tolerances(self): # """RxnSpecies(*s) tolerance settings""" - species1 = wntr.quality.BulkSpecies("Cl", "mg") - species2 = wntr.quality.WallSpecies("Cl", "mg", 0.01, 0.0001, note="Testing stuff") + species1 = wntr.quality.Species("B", "Cl", "mg") + species2 = wntr.quality.Species("W", "Cl", "mg", 0.01, 0.0001, note="Testing stuff") self.assertIsNone(species1.get_tolerances()) self.assertIsNotNone(species2.get_tolerances()) self.assertTupleEqual(species2.get_tolerances(), (0.01, 0.0001)) @@ -94,19 +94,19 @@ def test_Species_tolerances(self): def test_BulkSpecies_creation(self): # """BlukSpecies object creation (direct instantiation)""" - self.assertRaises(TypeError, wntr.quality.BulkSpecies, "Re") - self.assertRaises(ValueError, wntr.quality.BulkSpecies, "Re", "mg") - self.assertRaises(TypeError, wntr.quality.BulkSpecies, "Cl", "mg", 0.01) - self.assertRaises(TypeError, wntr.quality.BulkSpecies, "Cl", "mg", None, 0.01) - species = wntr.quality.BulkSpecies("Cl", "mg") + self.assertRaises(TypeError, wntr.quality.Species, "b", "Re") + self.assertRaises(ValueError, wntr.quality.Species, "B", "Re", "mg") + self.assertRaises(TypeError, wntr.quality.Species, 1, "Cl", "mg", 0.01) + self.assertRaises(TypeError, wntr.quality.Species, wntr.quality.base.SpeciesType.BULK, "Cl", "mg", None, 0.01) + species = wntr.quality.Species(1, "Cl", "mg") self.assertEqual(species.name, "Cl") self.assertEqual(species.units, "mg") - self.assertEqual(species.var_type, wntr.quality.VariableType.BULK) + self.assertEqual(species.var_type, wntr.quality.SpeciesType.BULK) self.assertIsNone(species._atol) self.assertIsNone(species._rtol) self.assertIsNone(species.note) - species = wntr.quality.BulkSpecies("Cl", "mg", 0.01, 0.0001, note="Testing stuff") - self.assertEqual(species.var_type, wntr.quality.VariableType.BULK) + species = wntr.quality.Species('b', "Cl", "mg", 0.01, 0.0001, note="Testing stuff") + self.assertEqual(species.var_type, wntr.quality.SpeciesType.BULK) self.assertEqual(species.name, "Cl") self.assertEqual(species.units, "mg") self.assertEqual(species._atol, 0.01) @@ -115,19 +115,19 @@ def test_BulkSpecies_creation(self): def test_WallSpecies_creation(self): # """WallSpecies object creation (direct instantiation)""" - self.assertRaises(TypeError, wntr.quality.WallSpecies, "Re") - self.assertRaises(ValueError, wntr.quality.WallSpecies, "Re", "mg") - self.assertRaises(TypeError, wntr.quality.WallSpecies, "Cl", "mg", 0.01) - self.assertRaises(TypeError, wntr.quality.WallSpecies, "Cl", "mg", None, 0.01) - species = wntr.quality.WallSpecies("Cl", "mg") + self.assertRaises(TypeError, wntr.quality.Species, 'W', "Re") + self.assertRaises(ValueError, wntr.quality.Species, 'Wall', "Re", "mg") + self.assertRaises(TypeError, wntr.quality.Species, 2, "Cl", "mg", 0.01) + self.assertRaises(TypeError, wntr.quality.Species, 'W', "Cl", "mg", None, 0.01) + species = wntr.quality.Species('w', "Cl", "mg") self.assertEqual(species.name, "Cl") self.assertEqual(species.units, "mg") - self.assertEqual(species.var_type, wntr.quality.VariableType.WALL) + self.assertEqual(species.var_type, wntr.quality.SpeciesType.WALL) self.assertIsNone(species._atol) self.assertIsNone(species._rtol) self.assertIsNone(species.note) - species = wntr.quality.WallSpecies("Cl", "mg", 0.01, 0.0001, note="Testing stuff") - self.assertEqual(species.var_type, wntr.quality.VariableType.WALL) + species = wntr.quality.Species('w', "Cl", "mg", 0.01, 0.0001, note="Testing stuff") + self.assertEqual(species.var_type, wntr.quality.SpeciesType.WALL) self.assertEqual(species.name, "Cl") self.assertEqual(species.units, "mg") self.assertEqual(species._atol, 0.01) @@ -143,7 +143,7 @@ def test_Constant_creation(self): self.assertEqual(const1.name, "Kb") self.assertEqual(const1.global_value, 0.482) self.assertEqual(const1.get_value(), const1.global_value) - self.assertEqual(const1.var_type, wntr.quality.VariableType.CONST) + self.assertEqual(const1.var_type, wntr.quality.QualityVarType.CONST) self.assertEqual(const1.note, "test") def test_Parameter_creation(self): @@ -153,7 +153,7 @@ def test_Parameter_creation(self): self.assertEqual(param1.name, "Kb") self.assertEqual(param1.global_value, 0.482) self.assertEqual(param1.get_value(), param1.global_value) - self.assertEqual(param1.var_type, wntr.quality.VariableType.PARAM) + self.assertEqual(param1.var_type, wntr.quality.QualityVarType.PARAM) self.assertEqual(param1.note, "test") test_pipe_dict = {"PIPE": 0.38} test_tank_dict = {"TANK": 222.23} @@ -167,48 +167,48 @@ def test_RxnTerm_creation(self): term1 = wntr.quality.OtherTerm("T0", "-3.2 * Kb * Cl^2", note="bar") self.assertEqual(term1.name, "T0") self.assertEqual(term1.expression, "-3.2 * Kb * Cl^2") - self.assertEqual(term1.var_type, wntr.quality.VariableType.TERM) + self.assertEqual(term1.var_type, wntr.quality.QualityVarType.TERM) self.assertEqual(term1.note, "bar") def test_RxnExpression_strings(self): - equil1 = wntr.quality.EquilibriumDynamics("Cl", wntr.quality.LocationType.PIPE, "-Ka + Kb * Cl + T0") - rate1 = wntr.quality.RateDynamics("Cl", wntr.quality.LocationType.TANK, "-Ka + Kb * Cl + T0", note="Foo Bar") - formula1 = wntr.quality.FormulaDynamics("Cl", wntr.quality.LocationType.PIPE, "-Ka + Kb * Cl + T0") + equil1 = wntr.quality.EquilibriumDynamics("Cl", wntr.quality.ReactionType.PIPE, "-Ka + Kb * Cl + T0") + rate1 = wntr.quality.TankReaction("Cl", wntr.quality.ReactionType.TANK, "-Ka + Kb * Cl + T0", note="Foo Bar") + formula1 = wntr.quality.PipeReaction("Cl", wntr.quality.ReactionType.PIPE, "-Ka + Kb * Cl + T0") def test_Equilibrium_creation(self): - equil1 = wntr.quality.EquilibriumDynamics("Cl", wntr.quality.LocationType.PIPE, "-Ka + Kb * Cl + T0") + equil1 = wntr.quality.EquilibriumDynamics("Cl", wntr.quality.ReactionType.PIPE, "-Ka + Kb * Cl + T0") self.assertEqual(equil1.species, "Cl") self.assertEqual(equil1.expression, "-Ka + Kb * Cl + T0") - self.assertEqual(equil1.expr_type, wntr.quality.DynamicsType.EQUIL) + self.assertEqual(equil1.dynamics, wntr.quality.DynamicsType.EQUIL) def test_Rate_creation(self): - rate1 = wntr.quality.RateDynamics("Cl", wntr.quality.LocationType.TANK, "-Ka + Kb * Cl + T0", note="Foo Bar") - self.assertEqual(rate1.species, "Cl") + rate1 = wntr.quality.TankReaction("Cl", wntr.quality.ReactionType.TANK, "-Ka + Kb * Cl + T0", note="Foo Bar") + self.assertEqual(rate1.species_name, "Cl") self.assertEqual(rate1.expression, "-Ka + Kb * Cl + T0") - self.assertEqual(rate1.expr_type, wntr.quality.DynamicsType.RATE) + self.assertEqual(rate1.dynamics, wntr.quality.DynamicsType.RATE) self.assertEqual(rate1.note, "Foo Bar") def test_Formula_creation(self): - formula1 = wntr.quality.FormulaDynamics("Cl", wntr.quality.LocationType.PIPE, "-Ka + Kb * Cl + T0") + formula1 = wntr.quality.FormulaDynamics("Cl", wntr.quality.ReactionType.PIPE, "-Ka + Kb * Cl + T0") self.assertEqual(formula1.species, "Cl") self.assertEqual(formula1.expression, "-Ka + Kb * Cl + T0") - self.assertEqual(formula1.expr_type, wntr.quality.DynamicsType.FORMULA) + self.assertEqual(formula1.dynamics, wntr.quality.DynamicsType.FORMULA) def test_WaterQualityReactionsModel_creation_specific_everything(self): rxn_model1 = wntr.quality.MultispeciesQualityModel() - bulk1 = wntr.quality.BulkSpecies("Cl", "mg") - wall1 = wntr.quality.WallSpecies("ClOH", "mg", 0.01, 0.0001, note="Testing stuff") + bulk1 = wntr.quality.Species('b',"Cl", "mg") + wall1 = wntr.quality.Species('w', "ClOH", "mg", 0.01, 0.0001, note="Testing stuff") const1 = wntr.quality.Constant("Kb", 0.482) param1 = wntr.quality.Parameter("Ka", 0.482, note="foo") term1 = wntr.quality.OtherTerm("T0", "-3.2 * Kb * Cl^2", note="bar") - equil1 = wntr.quality.EquilibriumDynamics(bulk1, wntr.quality.LocationType.PIPE, "-Ka + Kb * Cl + T0") - rate1 = wntr.quality.RateDynamics(bulk1, wntr.quality.LocationType.TANK, "-Ka + Kb * Cl + T0", note="Foo Bar") - formula1 = wntr.quality.FormulaDynamics(wall1, wntr.quality.LocationType.PIPE, "-Ka + Kb * Cl + T0") + equil1 = wntr.quality.EquilibriumDynamics(bulk1, wntr.quality.ReactionType.PIPE, "-Ka + Kb * Cl + T0") + rate1 = wntr.quality.TankReaction(bulk1, wntr.quality.ReactionType.TANK, "-Ka + Kb * Cl + T0", note="Foo Bar") + formula1 = wntr.quality.FormulaDynamics(wall1, wntr.quality.ReactionType.PIPE, "-Ka + Kb * Cl + T0") bulk2 = rxn_model1.add_bulk_species("Cl", "mg") wall2 = rxn_model1.add_wall_species("ClOH", "mg", 0.01, 0.0001, note="Testing stuff") - const2 = rxn_model1.add_constant_coeff("Kb", 0.482) - param2 = rxn_model1.add_parameterized_coeff("Ka", 0.482, note="foo") + const2 = rxn_model1.add_constant("Kb", 0.482) + param2 = rxn_model1.add_parameter("Ka", 0.482, note="foo") term2 = rxn_model1.add_other_term("T0", "-3.2 * Kb * Cl^2", note="bar") equil2 = rxn_model1.add_pipe_reaction("Cl", "equil", "-Ka + Kb * Cl + T0") rate2 = rxn_model1.add_tank_reaction("Cl", wntr.quality.DynamicsType.R, "-Ka + Kb * Cl + T0", note="Foo Bar") @@ -223,22 +223,22 @@ def test_WaterQualityReactionsModel_creation_specific_everything(self): # self.assertEqual(formula1, formula2) def test_WaterQualityReactionsModel_creation_generic_species_coeffs(self): - bulk1 = wntr.quality.BulkSpecies("Cl", "mg") - wall1 = wntr.quality.WallSpecies("ClOH", "mg", 0.01, 0.0001, note="Testing stuff") + bulk1 = wntr.quality.Species('b', "Cl", "mg") + wall1 = wntr.quality.Species(2, "ClOH", "mg", 0.01, 0.0001, note="Testing stuff") const1 = wntr.quality.Constant("Kb", 0.482) param1 = wntr.quality.Parameter("Ka", 0.482, note="foo") term1 = wntr.quality.OtherTerm("T0", "-3.2 * Kb * Cl^2", note="bar") rxn_model2 = wntr.quality.MultispeciesQualityModel() - self.assertRaises(ValueError, rxn_model2.add_species, wntr.quality.VariableType.CONST, "Cl", "mg") + self.assertRaises(ValueError, rxn_model2.add_species, wntr.quality.QualityVarType.CONST, "Cl", "mg") self.assertRaises(TypeError, rxn_model2.add_coefficient, None, "Kb", 0.482) self.assertRaises(ValueError, rxn_model2.add_coefficient, "Wall", "Kb", 0.482) bulk3 = rxn_model2.add_species("BULK", "Cl", "mg") - wall3 = rxn_model2.add_species(wntr.quality.VariableType.WALL, "ClOH", "mg", 0.01, 0.0001, note="Testing stuff") + wall3 = rxn_model2.add_species(wntr.quality.QualityVarType.WALL, "ClOH", "mg", 0.01, 0.0001, note="Testing stuff") const3 = rxn_model2.add_coefficient("Consolation", "Kb", 0.482) - param3 = rxn_model2.add_coefficient(wntr.quality.VariableType.P, "Ka", 0.482, note="foo") + param3 = rxn_model2.add_coefficient(wntr.quality.QualityVarType.P, "Ka", 0.482, note="foo") self.assertEqual(bulk3, bulk1) self.assertEqual(wall3, wall1) diff --git a/wntr/utils/citations.py b/wntr/utils/citations.py deleted file mode 100644 index db0cba886..000000000 --- a/wntr/utils/citations.py +++ /dev/null @@ -1,337 +0,0 @@ -# coding: utf-8 -"""Contains a dataclass that can be used to store citations. -""" -from __future__ import annotations -import dataclasses - -import datetime -from dataclasses import asdict, dataclass, field, is_dataclass -from typing import Any, Dict, Union, List, Tuple - -Literal = str -"""A literal string""" -Name = str -"""A name string, preferrably in order without commas""" -NameList = Union[Name, List[Name]] -"""A list of names, or a string with "and" between names""" -LiteralList = Union[Literal, List[Literal]] -"""A list of literals, or a string with "and" between literals""" -Key = str -"""A string that comes from a limited set of values""" -KeyList = Union[Key, List[Key]] -"""A list of keys, or a string with "and" between keys""" -Verbatim = str -"""A string that should not be interpreted (ie raw)""" -Special = Any -"""Anything that isn't a string or list of strings""" -URI = str -"""A valid URI""" -Date = Union[str, datetime.date] -"""A date or string in yyyy-mm-dd format (must be 0-padded, eg 2021-02-02 for February 2, 2021""" -Range = Union[str, Tuple[Any, Any]] -"""A 2-tuple of (start,stop) or a string with two values separated by '--' """ -SeparatedValues = Union[str, List[str]] -"""A list of strings, or a string that is delimited (the delimiter is not specified)""" - - -@dataclass(repr=False) -class Citation: - """A class to hold a citation to document the source of a model. - - Parameters - ---------- - entry_type : str - Describe the type of citation, for example, 'journal' or 'book'. - key : str - A key to use to identify this citation. Usually a BibTeX key or an - alphanumeric key per citation standards. - fields : CitationFields - An object that has attributes that align with different citation - fields, such as 'title' or 'author'. - """ - - entry_type: str - key: str - fields: "CitationFields" = None - - def __post_init__(self): - if self.fields is None: - self.fields = CitationFields(None) - elif isinstance(self.fields, dict): - self.fields = CitationFields(**self.fields) - elif isinstance(self.fields, list): - self.fields = CitationFields(*self.fields) - - def to_dict(self): - """Convert to a dictionary. - - Returns - ------- - dict - the citation dictionary - """ - try: - ret = dict() - ret["entry_type"] = self.entry_type - ret["key"] = self.key - ret["fields"] = self.fields.to_dict() - return ret - except: - return asdict(self) - - -@dataclass(repr=False) -class CitationFields: - """A dataclass for citation fields; field names and types are taken from BibLaTeX. - This class makes no attempt to format or represent the citation in any form - other than as a dictionary. This class also does not perform any type-checking - on fields, although it does create ``TypeAlias`` es for each field for the - user's information. Please see the BibLaTeX or BibTeX documentation for a list of - valid field names. - """ - - title: Literal = None - """Title of the work, required for most bibliographies.""" - author: NameList = None - """The author of a work. Typically, either `author` or `editor` is required.""" - editor: NameList = None - """The editor of a work. Typically, either `author` or `editor` is required.""" - date: Date = None - """The date the work was published. Typically, either `year` or `date` is required""" - year: Literal = None - """The year the work was published. Typically, either `year` or `date` is required.""" - journal: Literal = None - """The journal an articles was published in. Both `journal` and `journaltitle` are accepted as field names.""" - journaltitle: Literal = None - """The journal an articles was published in. Both `journal` and `journaltitle` are accepted as field names.""" - doi: Verbatim = None - """The DOI identifier. Most works, and nearly all journal articles, have a DOI.""" - type: Key = None - """The (sub)type of an :attr:`Citation.entry_type`. For example, "masters" for a masters thesis.""" - - volume: int = None - """The volume for a journal or multi-volume set. Use `volumes` to list the total number of volumes in a set.""" - number: Literal = None - """The journal number within a volume, or a report number.""" - pages: Range = None - """The pages for the work.""" - eid: Literal = None - """The electronic identifier number, has replaced pages in some digital journals.""" - issue: Literal = None - """The issue if the issue is not a number, for example, 'Spring'""" - series: Literal = None - """The series name, such as 'Chemical Reviews'""" - part: Literal = None - """The part, usually for reports or multi-volume sets.""" - - eprint: Verbatim = None - """Used for alternatives to DOI, such as PubMed PMIDs. The `eprintclass` and `eprinttype` fields identify the type of ID.""" - eprintclass: Literal = None - eprinttype: Literal = None - url: URI = None - """A URL for access to a dataset or work. Use `urldate` to indicate when the URL was accessed.""" - urldate: Date = None - """The date a `url` was accessed.""" - - issuetitle: Literal = None - booktitle: Literal = None - eventtitle: Literal = None - maintitle: Literal = None - """The `maintitle`, `booktitle`, `eventtitle`, and `issuetitle` are used for containing works, such as for works within proceedings.""" - - eventdate: Date = None - - institution: LiteralList = None - organization: LiteralList = None - publisher: LiteralList = None - school: LiteralList = None - - location: LiteralList = None - address: LiteralList = None - venue: Literal = None - - abstract: Literal = None - addendum: Literal = None - afterword: NameList = None - annotation: Literal = None - annotator: NameList = None - authortype: Key = None - bookauthor: NameList = None - bookpagination: Key = None - chapter: Literal = None - commentator: NameList = None - edition: Union[int, Literal] = None - editora: NameList = None - editorb: NameList = None - editorc: NameList = None - editortype: Key = None - editoratype: Key = None - editorbtype: Key = None - editorctype: Key = None - entrysubtype: Literal = None - file: Verbatim = None - foreword: NameList = None - holder: NameList = None - howpublished: Literal = None - introduction: NameList = None - isan: Literal = None - isbn: Literal = None - ismn: Literal = None - isrn: Literal = None - issn: Literal = None - iswc: Literal = None - # Titles - eventtitleaddon: Literal = None - subtitle: Literal = None - titleaddon: Literal = None - journalsubtitle: Literal = None - journaltitleaddon: Literal = None - issuesubtitle: Literal = None - issuetitleaddon: Literal = None - booksubtitle: Literal = None - booktitleaddon: Literal = None - mainsubtitle: Literal = None - maintitleaddon: Literal = None - origtitle: Literal = None - reprinttitle: Literal = None - shorttitle: Literal = None - shortjournal: Literal = None - indextitle: Literal = None - indexsorttitle: Literal = None - sorttitle: Literal = None - # Continued - label: Literal = None - language: KeyList = None - library: Literal = None - month: Literal = None - nameaddon: Literal = None - note: Literal = None - origdate: Date = None - origlanguage: KeyList = None - origlocation: LiteralList = None - origpublisher: LiteralList = None - pagetotal: Literal = None - pagination: Key = None - pubstate: Key = None - shortauthor: NameList = None - shorteditor: NameList = None - shorthand: Literal = None - shorthandintro: Literal = None - shortseries: Literal = None - translator: NameList = None - version: Literal = None - volumes: int = None - # SPECIAL FIELDS - crossref: Key = None - entryset: SeparatedValues = None - execute: Special = None - gender: Key = None - langid: Key = None - langidopts: Special = None - ids: SeparatedValues = None - keywords: SeparatedValues = None - options: Special = None - presort: Special = None - related: SeparatedValues = None - relatedoptions: SeparatedValues = None - relatedtype: Special = None - relatedstring: Literal = None - sortkey: Literal = None - sortname: NameList = None - sortshorthand: Literal = None - sortyear: int = None - xdata: SeparatedValues = None - xref: Key = None - # FIELD ALIASES - annote: Literal = None - archiveprefix: Literal = None - pdf: Verbatim = None - primaryclass: Literal = None - - def to_dict(self) -> Dict[str, Any]: - """Return a dictionary representation of the citation. - All blank (None) values will be removed from the dictionary - so that it is minimal. - - Returns - ------- - Dict[str, Any] - minimal dictionary representation of the Citation - """ - d = asdict(self) - for k in list(d.keys()): - if d[k] is None: - del d[k] - return d - - def __repr__(self) -> str: - d = asdict(self) - for k in list(d.keys()): - if d[k] is None: - del d[k] - rep = str(self.__class__.__name__) + "(" - rep = rep + ", ".join(["{}={}".format(k, repr(v)) for k, v in d.items()]) - rep = rep + ")" - return rep - - -def to_jsontypes(citations): - """Convert a Citation, list of citations, or dictionary of citations to a JSON mapping. - - Parameters - ---------- - citations : Citation, List[Citation], Any - the citation(s) to convert - - Returns - ------- - JSON valid object - dictionary, list, or scalar - """ - if isinstance(citations, str): - return citations - elif not isinstance(citations, list) and hasattr(citations, 'to_dict'): - return citations.to_dict() - elif is_dataclass(citations.__class__): - return asdict(citations) - elif isinstance(citations, (list, tuple)): - ret = list() - for obj in citations: - ret.append(to_jsontypes(obj)) - return ret - elif isinstance(citations, dict): - ret = dict() - for key, obj in citations.items(): - ret[key] = to_jsontypes(obj) - return ret - else: - return str(citations) - -def from_jsontypes(citations): - """Convert a JSON mapping or list of mappings to a Citation structure. - - Parameters - ---------- - citations : dict, list[dict] - a dictionary or list of dictionaries to convert to Citation objects or leave as strings. - - Returns - ------- - Any - the converted objects - """ - if isinstance(citations, list): - ret = list() - for obj in citations: - ret.append(from_jsontypes(obj)) - return ret - elif isinstance(citations, dict): - try: - ret = Citation(**citations) - except: - ret = dict() - for key, obj in citations.items(): - ret[key] = from_jsontypes(citations) - return ret - elif isinstance(citations, str): - return ret diff --git a/wntr/utils/enumtools.py b/wntr/utils/enumtools.py index 8f02fe281..a05e3c6fc 100644 --- a/wntr/utils/enumtools.py +++ b/wntr/utils/enumtools.py @@ -6,7 +6,7 @@ from typing import Union import functools -def add_get(cls=None, *, prefix=None, abbrev=False): +def add_get(cls=None, *, prefix=None, abbrev=False, allow_none=True): """Decorator that will add a ``get()`` classmethod to an enum class. Parameters @@ -15,35 +15,69 @@ def add_get(cls=None, *, prefix=None, abbrev=False): A prefix to strip off any string values passed in, by default None abbrev : bool, optional Allow truncating to the first character for checks, by default False - + allow_none : bool, optional + Allow None to be be passed through without raising error, by default True Returns ------- class the modified class + + Notes + ----- + The ``get`` method behaves as follows: + + For an integer, the integer value will be used to select the proper member. + For an :class:`Enum` object, the object's ``name`` will be used, and it will + be processed as a string. For a string, the method will: + + 0. if ``allow_none`` is False, then raise a TypeError if the value is None, otherwise + pass None back to calling function for processing + 1. capitalize the string + 2. remove leading or trailing spaces + 3. convert interior spaces or dashes to underscores + 4. optionally, remove a specified prefix from a string (using ``prefix``, which + should have a default assigned by the :func:`wntr.utils.enumtools.add_get` + function.) + + It will then try to get the member with the name corresponding to the converted + string. + + 5. optionally, if ``abbrev`` is True, then the string will be truncated to the first + letter, only, after trying to use the full string as passed in. The ``abbrev`` + parameter will have a default value based on how the :func:`~wntr.utils.enumtools.add_get` + decorator was called on this class. + """ if prefix is None: prefix = '' if abbrev is None: abbrev = False + if allow_none is None: + allow_none = True if cls is None: - return functools.partial(add_get, prefix=prefix, abbrev=abbrev) + return functools.partial(add_get, prefix=prefix, abbrev=abbrev, allow_none=allow_none) @functools.wraps(cls) def wrap(cls, prefix, abbrev): """Perform the decorator action""" - def get(cls, value: Union[str, int, Enum], prefix='', abbrev=False): + def get(cls, value: Union[str, int, Enum], prefix='', abbrev=False, allow_none=True): """Get the proper enum based on the name or value of the argument. + See :func:`~wntr.utils.enumtools.add_get` for details on how this function works. + + Parameters ---------- value : Union[str, int, Enum] the value to be checked, if it is an Enum, then the name will be used prefix : str, optional - a prefix to strip from the beginning of ``value``, default set by the decorator + a prefix to strip from the beginning of ``value``, default blank or set by decorator abbrev : bool, optional - whether to try a single-letter version of ``value``, default set by the decorator + whether to try a single-letter version of ``value``, default False or set by decorator + allow_none : bool, optional + passing None will return None, otherwise will raise TypeError, default True or set by decorator Returns ------- @@ -57,31 +91,11 @@ def get(cls, value: Union[str, int, Enum], prefix='', abbrev=False): ValueError if ``value`` is invalid - Notes - ----- - The get method behaves as follows. - For an integer, the integer value will be used to select the proper member. - For an :class:`Enum` object, the object's ``name`` will be used, and it will - be processed as a string. For a string, the method will: - - 1. capitalize the string - 2. remove leading or trailing spaces - 3. convert interior spaces or dashes to underscores - 4. optionally, remove a specified prefix from a string (using ``prefix``, which - should have a default assigned by the :func:`wntr.utils.enumtools.add_get` - function.) - - It will then try to get the member with the name corresponding to the converted - string. - - 5. optionally, if ``abbrev`` is True, then the string will be truncated to the first - letter, only, after trying to use the full string as passed in. The ``abbrev`` - parameter will have a default value based on how the :func:`~wntr.utils.enumtools.add_get` - decorator was called on this class. - """ - if value is None: + if value is None and allow_none: return None + elif value is None: + raise TypeError('A value is mandatory, but got None') name = str(value) if isinstance(value, cls): return value From 25a48e04c3260bca84b66f5100c5c05255b66316 Mon Sep 17 00:00:00 2001 From: dbhart Date: Fri, 27 Oct 2023 17:04:18 -0600 Subject: [PATCH 34/75] Renaming to conform to other wntr styles --- documentation/advancedqual.rst | 30 +- documentation/apidoc/wntr.msx.base.rst | 7 + ...quality.base.rst => wntr.msx.elements.rst} | 4 +- documentation/apidoc/wntr.msx.library.rst | 7 + documentation/apidoc/wntr.msx.model.rst | 7 + documentation/apidoc/wntr.msx.options.rst | 7 + documentation/apidoc/wntr.msx.rst | 20 + documentation/apidoc/wntr.quality.library.rst | 7 - .../apidoc/wntr.quality.multispecies.rst | 7 - documentation/apidoc/wntr.quality.options.rst | 7 - documentation/apidoc/wntr.quality.rst | 19 - documentation/apidoc/wntr.rst | 2 +- wntr/__init__.py | 2 +- wntr/epanet/msx/__init__.py | 20 +- wntr/epanet/msx/io.py | 45 +- wntr/epanet/msx/toolkit.py | 75 +- wntr/{quality => msx}/__init__.py | 2 +- .../_library_data/arsenic_chloramine.json | 20 +- .../_library_data/batch_chloramine_decay.json | 30 +- .../_library_data/lead_ppm.json | 6 +- .../_library_data/nicotine.json | 6 +- .../_library_data/nicotine_ri.json | 14 +- wntr/{quality => msx}/base.py | 160 +- wntr/msx/elements.py | 693 ++++++++ wntr/{quality => msx}/library.py | 30 +- wntr/msx/model.py | 770 +++++++++ wntr/{quality => msx}/options.py | 0 wntr/network/model.py | 6 +- wntr/quality/MSXPY_toolkit.py | 876 ---------- wntr/quality/multispecies.py | 1452 ----------------- wntr/sim/epanet.py | 1 + wntr/tests/test_epanet_msx_io.py | 6 +- wntr/tests/test_epanet_msx_tooklit.py | 4 +- wntr/tests/test_quality_variables.py | 152 +- 34 files changed, 1881 insertions(+), 2613 deletions(-) create mode 100644 documentation/apidoc/wntr.msx.base.rst rename documentation/apidoc/{wntr.quality.base.rst => wntr.msx.elements.rst} (57%) create mode 100644 documentation/apidoc/wntr.msx.library.rst create mode 100644 documentation/apidoc/wntr.msx.model.rst create mode 100644 documentation/apidoc/wntr.msx.options.rst create mode 100644 documentation/apidoc/wntr.msx.rst delete mode 100644 documentation/apidoc/wntr.quality.library.rst delete mode 100644 documentation/apidoc/wntr.quality.multispecies.rst delete mode 100644 documentation/apidoc/wntr.quality.options.rst delete mode 100644 documentation/apidoc/wntr.quality.rst rename wntr/{quality => msx}/__init__.py (90%) rename wntr/{quality => msx}/_library_data/arsenic_chloramine.json (90%) rename wntr/{quality => msx}/_library_data/batch_chloramine_decay.json (94%) rename wntr/{quality => msx}/_library_data/lead_ppm.json (94%) rename wntr/{quality => msx}/_library_data/nicotine.json (96%) rename wntr/{quality => msx}/_library_data/nicotine_ri.json (93%) rename wntr/{quality => msx}/base.py (81%) create mode 100644 wntr/msx/elements.py rename wntr/{quality => msx}/library.py (94%) create mode 100644 wntr/msx/model.py rename wntr/{quality => msx}/options.py (100%) delete mode 100644 wntr/quality/MSXPY_toolkit.py delete mode 100644 wntr/quality/multispecies.py diff --git a/documentation/advancedqual.rst b/documentation/advancedqual.rst index 54d58149b..b144cbb38 100644 --- a/documentation/advancedqual.rst +++ b/documentation/advancedqual.rst @@ -28,8 +28,8 @@ for the paper this model was described in. .. doctest:: - >>> import wntr.quality - >>> msx = wntr.quality.MultispeciesQualityModel() + >>> import wntr.msx + >>> msx = wntr.msx.MultispeciesQualityModel() >>> msx.name = "lead_ppm" >>> msx.title = "Lead Plumbosolvency Model (from Burkhardt et al 2020)" >>> msx.desc = "Parameters for EPA HPS Simulator Model" @@ -79,7 +79,7 @@ Name Type Units No :math:`Pb` bulk species :math:`\mathrm{μg}_\mathrm{(Pb)}` dissolved lead ======================== =============== ================================= ======================== -To add this species to the model, we can use the model's :meth:`~wntr.quality.multispecies.MultispeciesQualityModel.add_species` +To add this species to the model, we can use the model's :meth:`~wntr.msx.multispecies.MultispeciesQualityModel.add_species` method. The method arguments are the name, the species_type (which can either be "bulk" or "wall"), the units, and an optional note. @@ -91,7 +91,7 @@ This method will add the new species to the model and also return a copy of the Species(name='PB2', species_type=, units='ug', atol=None, rtol=None, note='dissolved lead (Pb)') The new species can be accessed by using the item's name and indexing on the model's -:attr:`~wntr.quality.multispecies.MultispeciesQualityModel.reaction_system` attribute. +:attr:`~wntr.msx.multispecies.MultispeciesQualityModel.reaction_system` attribute. >>> PB2 = msx.reaction_system['PB2'] >>> PB2 @@ -135,7 +135,7 @@ pipes, so we need to set the tank reaction to be unchanging. The system of equat Note that the pipe reaction has a variable that we have not defined, :math:`Av`, in its expression; this variable is a pre-defined hydraulic variable. The list of these variables can be found in -the EPANET-MSX documentation, and also in the :attr:`~wntr.quality.base.HYDRAULIC_VARIABLES` +the EPANET-MSX documentation, and also in the :attr:`~wntr.msx.base.HYDRAULIC_VARIABLES` documentation. The reactions can be described in WNTR as ================ ============== ========================================================================== @@ -145,7 +145,7 @@ pipe rate :math:`F \cdot Av \cdot M \cdot \left( E - Pb tank rate :math:`0` ================ ============== ========================================================================== -and then added to the reaction model using the :meth:`~wntr.quality.multispecies.MultispeciesQualityModel.add_reaction` +and then added to the reaction model using the :meth:`~wntr.msx.multispecies.MultispeciesQualityModel.add_reaction` method. .. doctest:: @@ -348,10 +348,10 @@ Creation in WNTR .. doctest:: - >>> msx = wntr.quality.MultispeciesQualityModel() + >>> msx = wntr.msx.MultispeciesQualityModel() >>> msx.name = "arsenic_chloramine" >>> msx.title = "Arsenic Oxidation/Adsorption Example" - >>> msx.references.append(wntr.quality.library.cite_msx()) + >>> msx.references.append(wntr.msx.library.cite_msx()) >>> AS3 = msx.add_species(name="AS3", species_type="BULK", units="UG", note="Dissolved arsenite") >>> AS5 = msx.add_species(name="AS5", species_type="BULK", units="UG", note="Dissolved arsenate") >>> AStot = msx.add_species(name="AStot", species_type="BULK", units="UG", note="Total dissolved arsenic") @@ -364,29 +364,29 @@ Creation in WNTR >>> Smax = msx.add_constant("Smax", 50.0, units="UG / M^2", note="Arsenate adsorption limit") >>> Ks = msx.add_term(name="Ks", expression="K1/K2", note="Equil. adsorption coeff.") >>> _ = msx.add_reaction( - ... species_name="AS3", reaction_type="pipes", dynamics_type="rate", expression="-Ka*AS3*NH2CL", note="Arsenite oxidation" + ... species_name="AS3", reaction_type="pipes", expression_type="rate", expression="-Ka*AS3*NH2CL", note="Arsenite oxidation" ... ) >>> _ = msx.add_reaction( ... "AS5", "pipes", "rate", "Ka*AS3*NH2CL - Av*(K1*(Smax-AS5s)*AS5 - K2*AS5s)", note="Arsenate production less adsorption" ... ) >>> _ = msx.add_reaction( - ... species_name="NH2CL", reaction_type="pipes", dynamics_type="rate", expression="-Kb*NH2CL", note="Monochloramine decay" + ... species_name="NH2CL", reaction_type="pipes", expression_type="rate", expression="-Kb*NH2CL", note="Monochloramine decay" ... ) >>> _ = msx.add_reaction("AS5s", "pipe", "equil", "Ks*Smax*AS5/(1+Ks*AS5) - AS5s", note="Arsenate adsorption") >>> _ = msx.add_reaction( - ... species_name="AStot", reaction_type="pipes", dynamics_type="formula", expression="AS3 + AS5", note="Total arsenic" + ... species_name="AStot", reaction_type="pipes", expression_type="formula", expression="AS3 + AS5", note="Total arsenic" ... ) >>> _ = msx.add_reaction( - ... species_name="AS3", reaction_type="tank", dynamics_type="rate", expression="-Ka*AS3*NH2CL", note="Arsenite oxidation" + ... species_name="AS3", reaction_type="tank", expression_type="rate", expression="-Ka*AS3*NH2CL", note="Arsenite oxidation" ... ) >>> _ = msx.add_reaction( - ... species_name="AS5", reaction_type="tank", dynamics_type="rate", expression="Ka*AS3*NH2CL", note="Arsenate production" + ... species_name="AS5", reaction_type="tank", expression_type="rate", expression="Ka*AS3*NH2CL", note="Arsenate production" ... ) >>> _ = msx.add_reaction( - ... species_name="NH2CL", reaction_type="tank", dynamics_type="rate", expression="-Kb*NH2CL", note="Monochloramine decay" + ... species_name="NH2CL", reaction_type="tank", expression_type="rate", expression="-Kb*NH2CL", note="Monochloramine decay" ... ) >>> _ = msx.add_reaction( - ... species_name="AStot", reaction_type="tanks", dynamics_type="formula", expression="AS3 + AS5", note="Total arsenic" + ... species_name="AStot", reaction_type="tanks", expression_type="formula", expression="AS3 + AS5", note="Total arsenic" ... ) >>> msx.options.area_units = "M2" >>> msx.options.rate_units = "HR" diff --git a/documentation/apidoc/wntr.msx.base.rst b/documentation/apidoc/wntr.msx.base.rst new file mode 100644 index 000000000..9df2031eb --- /dev/null +++ b/documentation/apidoc/wntr.msx.base.rst @@ -0,0 +1,7 @@ +wntr.msx.base module +==================== + +.. automodule:: wntr.msx.base + :members: + :undoc-members: + :show-inheritance: diff --git a/documentation/apidoc/wntr.quality.base.rst b/documentation/apidoc/wntr.msx.elements.rst similarity index 57% rename from documentation/apidoc/wntr.quality.base.rst rename to documentation/apidoc/wntr.msx.elements.rst index d3cc5ff4b..9bc59e92d 100644 --- a/documentation/apidoc/wntr.quality.base.rst +++ b/documentation/apidoc/wntr.msx.elements.rst @@ -1,7 +1,7 @@ -wntr.quality.base module +wntr.msx.elements module ======================== -.. automodule:: wntr.quality.base +.. automodule:: wntr.msx.elements :members: :undoc-members: :show-inheritance: diff --git a/documentation/apidoc/wntr.msx.library.rst b/documentation/apidoc/wntr.msx.library.rst new file mode 100644 index 000000000..dc10f1f4e --- /dev/null +++ b/documentation/apidoc/wntr.msx.library.rst @@ -0,0 +1,7 @@ +wntr.msx.library module +======================= + +.. automodule:: wntr.msx.library + :members: + :undoc-members: + :show-inheritance: diff --git a/documentation/apidoc/wntr.msx.model.rst b/documentation/apidoc/wntr.msx.model.rst new file mode 100644 index 000000000..ec8a7934e --- /dev/null +++ b/documentation/apidoc/wntr.msx.model.rst @@ -0,0 +1,7 @@ +wntr.msx.model module +===================== + +.. automodule:: wntr.msx.model + :members: + :undoc-members: + :show-inheritance: diff --git a/documentation/apidoc/wntr.msx.options.rst b/documentation/apidoc/wntr.msx.options.rst new file mode 100644 index 000000000..1e1b0c622 --- /dev/null +++ b/documentation/apidoc/wntr.msx.options.rst @@ -0,0 +1,7 @@ +wntr.msx.options module +======================= + +.. automodule:: wntr.msx.options + :members: + :undoc-members: + :show-inheritance: diff --git a/documentation/apidoc/wntr.msx.rst b/documentation/apidoc/wntr.msx.rst new file mode 100644 index 000000000..00b1530eb --- /dev/null +++ b/documentation/apidoc/wntr.msx.rst @@ -0,0 +1,20 @@ +wntr.msx package +================ + +.. automodule:: wntr.msx + :members: + :undoc-members: + :show-inheritance: + + +Submodules +---------- + +.. toctree:: + :maxdepth: 1 + + wntr.msx.base + wntr.msx.elements + wntr.msx.library + wntr.msx.model + wntr.msx.options diff --git a/documentation/apidoc/wntr.quality.library.rst b/documentation/apidoc/wntr.quality.library.rst deleted file mode 100644 index b7ea696fa..000000000 --- a/documentation/apidoc/wntr.quality.library.rst +++ /dev/null @@ -1,7 +0,0 @@ -wntr.quality.library module -=========================== - -.. automodule:: wntr.quality.library - :members: - :undoc-members: - :show-inheritance: diff --git a/documentation/apidoc/wntr.quality.multispecies.rst b/documentation/apidoc/wntr.quality.multispecies.rst deleted file mode 100644 index 192296011..000000000 --- a/documentation/apidoc/wntr.quality.multispecies.rst +++ /dev/null @@ -1,7 +0,0 @@ -wntr.quality.multispecies module -================================ - -.. automodule:: wntr.quality.multispecies - :members: - :undoc-members: - :show-inheritance: diff --git a/documentation/apidoc/wntr.quality.options.rst b/documentation/apidoc/wntr.quality.options.rst deleted file mode 100644 index e492fec10..000000000 --- a/documentation/apidoc/wntr.quality.options.rst +++ /dev/null @@ -1,7 +0,0 @@ -wntr.quality.options module -=========================== - -.. automodule:: wntr.quality.options - :members: - :undoc-members: - :show-inheritance: diff --git a/documentation/apidoc/wntr.quality.rst b/documentation/apidoc/wntr.quality.rst deleted file mode 100644 index 01d0bdb23..000000000 --- a/documentation/apidoc/wntr.quality.rst +++ /dev/null @@ -1,19 +0,0 @@ -wntr.quality package -==================== - -.. automodule:: wntr.quality - :members: - :undoc-members: - :show-inheritance: - - -Submodules ----------- - -.. toctree:: - :maxdepth: 1 - - wntr.quality.base - wntr.quality.library - wntr.quality.multispecies - wntr.quality.options diff --git a/documentation/apidoc/wntr.rst b/documentation/apidoc/wntr.rst index 4b5369d1b..7dd9f2ca5 100644 --- a/documentation/apidoc/wntr.rst +++ b/documentation/apidoc/wntr.rst @@ -20,7 +20,7 @@ Subpackages wntr.metrics wntr.morph wntr.network - wntr.quality + wntr.msx wntr.scenario wntr.sim wntr.utils diff --git a/wntr/__init__.py b/wntr/__init__.py index 50727d3f1..30cae0645 100644 --- a/wntr/__init__.py +++ b/wntr/__init__.py @@ -7,7 +7,7 @@ from wntr import graphics from wntr import gis from wntr import utils -from wntr import quality +from wntr import msx __version__ = '1.1.0' diff --git a/wntr/epanet/msx/__init__.py b/wntr/epanet/msx/__init__.py index 4144ddbcc..b7ae5c121 100644 --- a/wntr/epanet/msx/__init__.py +++ b/wntr/epanet/msx/__init__.py @@ -1,4 +1,22 @@ """The wntr.epanet.msx package provides EPANET-MSX compatibility functions for WNTR. + +The following environment variable must be set, or the command `set_msx_path` must +be run prior to trying to instantiate the EPANET-MSX toolkit. + +.. envvar:: WNTR_PATH_TO_EPANETMSX + + The full path to the directory where EPANET-MSX has been installed. Specifically, + the directory should contain both toolkit files, epanet2.dll and epanetmsx.dll + (or the appropriate equivalent files for your system architecture). + """ +import os as _os + +def set_msx_path(path): + if not _os.path.isdir(path): + raise FileNotFoundError('Directory not found, {}'.format(path)) + _os.environ['WNTR_PATH_TO_EPANETMSX'] = path + from .io import MsxFile, MsxBinFile -from .toolkit import MSXepanet \ No newline at end of file +from .toolkit import MSXepanet + diff --git a/wntr/epanet/msx/io.py b/wntr/epanet/msx/io.py index 1bf2d78a9..e1a87ae31 100644 --- a/wntr/epanet/msx/io.py +++ b/wntr/epanet/msx/io.py @@ -8,13 +8,14 @@ import numpy as np import pandas as pd +from wntr.msx.elements import Constant, Parameter, Species, Term import wntr.network from wntr.epanet.msx.exceptions import EpanetMsxException, MSXValueError from wntr.epanet.util import ENcomment from wntr.network.elements import Source -from wntr.quality.base import ReactionType, QualityVarType, SpeciesType -from wntr.quality.multispecies import Constant, MultispeciesQualityModel, Parameter, Species, Term +from wntr.msx.base import ReactionType, VariableType, SpeciesType +from wntr.msx.model import MsxModel sys_default_enc = sys.getdefaultencoding() @@ -68,7 +69,7 @@ class MsxFile(object): """ def __init__(self): - self.rxn: MultispeciesQualityModel = None + self.rxn: MsxModel = None self.sections = dict() for sec in _INP_SECTIONS: self.sections[sec] = [] @@ -76,7 +77,7 @@ def __init__(self): self.patterns = dict() @classmethod - def read(cls, msx_filename: str, rxn_model: MultispeciesQualityModel = None): + def read(cls, msx_filename: str, rxn_model: MsxModel = None): """ Read an EPANET-MSX input file (.msx) and load data into a water quality reactions model. Only MSX 2.0 files are recognized. @@ -94,7 +95,7 @@ def read(cls, msx_filename: str, rxn_model: MultispeciesQualityModel = None): the model with the new species, reactions and other options added """ if rxn_model is None: - rxn_model = MultispeciesQualityModel() + rxn_model = MsxModel() obj = cls() obj.rxn = rxn_model # if not isinstance(msx_file, list): @@ -173,7 +174,7 @@ def _read(): raise EpanetMsxException(200) from e @classmethod - def write(cls, filename: str, msx: MultispeciesQualityModel): + def write(cls, filename: str, msx: MsxModel): """Write an MSX input file. Parameters @@ -195,13 +196,12 @@ def write(cls, filename: str, msx: MultispeciesQualityModel): obj._write_terms(fout) obj._write_pipes(fout) obj._write_tanks(fout) - obj._write_source_dict(fout) - obj._write_quality(fout) obj._write_diffusivity(fout) obj._write_parameters(fout) obj._write_patterns(fout) obj._write_report(fout) - fout.write("; END of MSX file generated by WNTR\n") + obj._write_quality(fout) + obj._write_source_dict(fout) def _read_title(self): lines = [] @@ -218,7 +218,7 @@ def _read_title(self): if len(lines) > 0: comments = comments + ("\n" if comments else "") + "\n".join(lines) self.rxn.title = title - self.rxn.desc = comments + self.rxn.description = comments def _read_options(self): for lnum, line in self.sections["[OPTIONS]"]: @@ -299,10 +299,10 @@ def _read_coefficients(self): note.post = comment if len(vals) < 3: raise EpanetMsxException(402, note="at line {} of [COEFFICIENTS] section:\n{}".format(lnum, line)) - typ = QualityVarType.get(vals[0], allow_none=False) - if typ is QualityVarType.CONSTANT: + typ = VariableType.get(vals[0], allow_none=False) + if typ is VariableType.CONSTANT: self.rxn.add_constant(vals[1], float(vals[2]), note=note) - elif typ is QualityVarType.PARAMETER: + elif typ is VariableType.PARAMETER: self.rxn.add_parameter(vals[1], float(vals[2]), note=note) else: raise MSXValueError(403, vals[0], note="at line {} of [COEFFICIENTS] section:\n{}".format(lnum, line)) @@ -673,21 +673,21 @@ def _write_pipes(self, fout): fout.write( "{}\n".format( var.note.wrap_msx_string( - "{:<12s} {:<8s} {:<32s}".format(var.dynamics_type.name.upper(), str(var.species_name), var.expression) + "{:<12s} {:<8s} {:<32s}".format(var.expression_type.name.upper(), str(var.species_name), var.expression) ) ) ) elif isinstance(var.note, str): fout.write( " {} ; {}\n".format( - "{:<12s} {:<8s} {:<32s}".format(var.dynamics_type.name.upper(), str(var.species_name), var.expression), + "{:<12s} {:<8s} {:<32s}".format(var.expression_type.name.upper(), str(var.species_name), var.expression), var.note, ) ) else: fout.write( " {}\n".format( - "{:<12s} {:<8s} {:<32s}".format(var.dynamics_type.name.upper(), str(var.species_name), var.expression) + "{:<12s} {:<8s} {:<32s}".format(var.expression_type.name.upper(), str(var.species_name), var.expression) ) ) fout.write("\n") @@ -701,27 +701,28 @@ def _write_tanks(self, fout): var = spec.tank_reaction except KeyError: logger.warn('Species {} does not have a tank reaction - this may be a problem'.format(str(spec))) + continue if var is None: raise MSXValueError(508, note=" species {}".format(str(spec))) if isinstance(var.note, ENcomment): fout.write( "{}\n".format( var.note.wrap_msx_string( - "{:<12s} {:<8s} {:<32s}".format(var.dynamics_type.name.upper(), str(var.species_name), var.expression) + "{:<12s} {:<8s} {:<32s}".format(var.expression_type.name.upper(), str(var.species_name), var.expression) ) ) ) elif isinstance(var.note, str): fout.write( " {} ; {}\n".format( - "{:<12s} {:<8s} {:<32s}".format(var.dynamics_type.name.upper(), str(var.species_name), var.expression), + "{:<12s} {:<8s} {:<32s}".format(var.expression_type.name.upper(), str(var.species_name), var.expression), var.note, ) ) else: fout.write( " {}\n".format( - "{:<12s} {:<8s} {:<32s}".format(var.dynamics_type.name.upper(), str(var.species_name), var.expression) + "{:<12s} {:<8s} {:<32s}".format(var.expression_type.name.upper(), str(var.species_name), var.expression) ) ) fout.write("\n") @@ -860,14 +861,14 @@ def MsxBinFile(filename, wn: wntr.network.WaterNetworkModel, res = None): species_list = [] node_list = wn.node_name_list link_list = wn.link_name_list - print(magic1, version, nnodes, nlinks, nspecies, reportstep) + # print(magic1, version, nnodes, nlinks, nspecies, reportstep) species_mass = [] for i in range(nspecies): species_len = np.fromfile(fin, dtype=np.int32, count=1)[0] - print(species_len) + # print(species_len) species_name = "".join(chr(f) for f in np.fromfile(fin, dtype=np.uint8, count=species_len) if f != 0) - print(species_name) + # print(species_name) species_list.append(species_name) species_mass.append("".join(chr(f) for f in np.fromfile(fin, dtype=np.uint8, count=16) if f != 0)) diff --git a/wntr/epanet/msx/toolkit.py b/wntr/epanet/msx/toolkit.py index 69140c4f2..84fdcd9f2 100644 --- a/wntr/epanet/msx/toolkit.py +++ b/wntr/epanet/msx/toolkit.py @@ -4,9 +4,8 @@ .. note:: - Code in this section taken from code originally written by Junli Hao 07/29/2018, - "EPANET-MSX-Python-wrapper" on GitHub, licensed under the BSD license. See LICENSE.txt for more - details. + Code in this section based on code from "EPANET-MSX-Python-wrapper", + licensed under the BSD license. See LICENSE.txt for details. """ import ctypes from enum import IntEnum @@ -45,6 +44,11 @@ class MSXepanet(ENepanet): def __init__(self, inpfile="", rptfile="", binfile="", msxfile=""): + if 'WNTR_PATH_TO_EPANETMSX' in os.environ: + msx_toolkit = os.environ['WNTR_PATH_TO_EPANETMSX'] + else: + msx_toolkit = None + self.ENlib = None self.errcode = 0 self.errcodelist = [] @@ -62,25 +66,44 @@ def __init__(self, inpfile="", rptfile="", binfile="", msxfile=""): libnames = ["epanetmsx", "epanetmsx_win32"] if "64" in platform.machine(): libnames.insert(0, "epanetmsx_amd64") - for lib in libnames: - try: - if os.name in ["nt", "dos"]: - libepanet = resource_filename(epanet_toolkit, "Windows/%s.dll" % lib) - self.ENlib = ctypes.windll.LoadLibrary(libepanet) - elif sys.platform in ["darwin"]: - libepanet = resource_filename(epanet_toolkit, "Darwin/lib%s.dylib" % lib) - self.ENlib = ctypes.cdll.LoadLibrary(libepanet) - else: - libepanet = resource_filename(epanet_toolkit, "Linux/lib%s.so" % lib) - self.ENlib = ctypes.cdll.LoadLibrary(libepanet) - return - except Exception as E1: - if lib == libnames[-1]: - raise E1 - pass - finally: - self._project = None - + if msx_toolkit: + for lib in libnames: + try: + if os.name in ["nt", "dos"]: + libepanet = os.path.join(msx_toolkit, "%s.dll" % lib) + self.ENlib = ctypes.windll.LoadLibrary(libepanet) + elif sys.platform in ["darwin"]: + libepanet = os.path.join(msx_toolkit, "lib%s.dylib" % lib) + self.ENlib = ctypes.cdll.LoadLibrary(libepanet) + else: + libepanet = os.path.join(msx_toolkit, "lib%s.so" % lib) + self.ENlib = ctypes.cdll.LoadLibrary(libepanet) + return + except Exception as E1: + if lib == libnames[-1]: + raise E1 + pass + finally: + self._project = None + else: + for lib in libnames: + try: + if os.name in ["nt", "dos"]: + libepanet = resource_filename(epanet_toolkit, "Windows/%s.dll" % lib) + self.ENlib = ctypes.windll.LoadLibrary(libepanet) + elif sys.platform in ["darwin"]: + libepanet = resource_filename(epanet_toolkit, "Darwin/lib%s.dylib" % lib) + self.ENlib = ctypes.cdll.LoadLibrary(libepanet) + else: + libepanet = resource_filename(epanet_toolkit, "Linux/lib%s.so" % lib) + self.ENlib = ctypes.cdll.LoadLibrary(libepanet) + return + except Exception as E1: + if lib == libnames[-1]: + raise E1 + pass + finally: + self._project = None return def _error(self, *args): @@ -98,7 +121,7 @@ def _error(self, *args): return # ----------running the simulation----------------------------------------------------- - def MSXopen(self, msxfile=None): + def MSXopen(self, msxfile): """Opens the MSX Toolkit to analyze a particular distribution system. Parameters @@ -106,9 +129,9 @@ def MSXopen(self, msxfile=None): msxfile : str name of the MSX input file """ - if msxfile is None: - msxfile = self.msxfile - ierr = self.ENlib.MSXopen(ctypes.c_char_p(msxfile.encode())) + if msxfile is not None: + msxfile = ctypes.c_char_p(msxfile.encode()) + ierr = self.ENlib.MSXopen(msxfile) if ierr != 0: raise EpanetMsxException(ierr, msxfile) diff --git a/wntr/quality/__init__.py b/wntr/msx/__init__.py similarity index 90% rename from wntr/quality/__init__.py rename to wntr/msx/__init__.py index e625cb7ae..3cc6669e1 100644 --- a/wntr/quality/__init__.py +++ b/wntr/msx/__init__.py @@ -7,6 +7,6 @@ from ..epanet.msx.exceptions import EpanetMsxException from .base import * -from .multispecies import * +from .model import * from .options import MultispeciesOptions from . import library diff --git a/wntr/quality/_library_data/arsenic_chloramine.json b/wntr/msx/_library_data/arsenic_chloramine.json similarity index 90% rename from wntr/quality/_library_data/arsenic_chloramine.json rename to wntr/msx/_library_data/arsenic_chloramine.json index 3e6c5d3d9..c67e1dc13 100644 --- a/wntr/quality/_library_data/arsenic_chloramine.json +++ b/wntr/msx/_library_data/arsenic_chloramine.json @@ -2,7 +2,7 @@ "wntr-version": "1.0.0", "name": "arsenic_chloramine", "title": "Arsenic Oxidation/Adsorption Example", - "desc": "This example models monochloramine oxidation of arsenite/arsenate and wall adsoption/desorption, as given in section 3 of the EPANET-MSX user manual", + "description": "This example models monochloramine oxidation of arsenite/arsenate and wall adsoption/desorption, as given in section 3 of the EPANET-MSX user manual", "references": [ "Shang, F. and Rossman, L.A. and Uber, J.G. (2023) \"EPANET-MSX 2.0 User Manual\". (Cincinnati, OH: Water Infrastructure Division (CESER), U.S. Environmental Protection Agency). EPA/600/R-22/199." ], @@ -92,31 +92,31 @@ "pipe_reactions": [ { "species_name": "AS3", - "dynamics_type": "rate", + "expression_type": "rate", "expression": "-Ka*AS3*NH2CL", "note": "Arsenite oxidation" }, { "species_name": "AS5", - "dynamics_type": "rate", + "expression_type": "rate", "expression": "Ka*AS3*NH2CL - Av*(K1*(Smax-AS5s)*AS5 - K2*AS5s)", "note": "Arsenate production less adsorption" }, { "species_name": "NH2CL", - "dynamics_type": "rate", + "expression_type": "rate", "expression": "-Kb*NH2CL", "note": "Monochloramine decay" }, { "species_name": "AS5s", - "dynamics_type": "equil", + "expression_type": "equil", "expression": "Ks*Smax*AS5/(1+Ks*AS5) - AS5s", "note": "Arsenate adsorption" }, { "species_name": "AStot", - "dynamics_type": "formula", + "expression_type": "formula", "expression": "AS3 + AS5", "note": "Total arsenic" } @@ -124,25 +124,25 @@ "tank_reactions": [ { "species_name": "AS3", - "dynamics_type": "rate", + "expression_type": "rate", "expression": "-Ka*AS3*NH2CL", "note": "Arsenite oxidation" }, { "species_name": "AS5", - "dynamics_type": "rate", + "expression_type": "rate", "expression": "Ka*AS3*NH2CL", "note": "Arsenate production" }, { "species_name": "NH2CL", - "dynamics_type": "rate", + "expression_type": "rate", "expression": "-Kb*NH2CL", "note": "Monochloramine decay" }, { "species_name": "AStot", - "dynamics_type": "formula", + "expression_type": "formula", "expression": "AS3 + AS5", "note": "Total arsenic" } diff --git a/wntr/quality/_library_data/batch_chloramine_decay.json b/wntr/msx/_library_data/batch_chloramine_decay.json similarity index 94% rename from wntr/quality/_library_data/batch_chloramine_decay.json rename to wntr/msx/_library_data/batch_chloramine_decay.json index 2d0e5f9f2..fc4c416db 100644 --- a/wntr/quality/_library_data/batch_chloramine_decay.json +++ b/wntr/msx/_library_data/batch_chloramine_decay.json @@ -2,7 +2,7 @@ "wntr-version": "1.0.0", "name": "batch_chloramine_decay", "title": "Batch chloramine decay example", - "desc": null, + "description": null, "references": [], "reaction_system": { "species": [ @@ -207,72 +207,72 @@ "pipe_reactions": [ { "species_name": "HOCL", - "dynamics_type": "rate", + "expression_type": "rate", "expression": "-a1 + a2 - a3 + a4 + a8" }, { "species_name": "NH3", - "dynamics_type": "rate", + "expression_type": "rate", "expression": "-a1 + a2 + a5 - a6" }, { "species_name": "NH2CL", - "dynamics_type": "rate", + "expression_type": "rate", "expression": "a1 - a2 - a3 + a4 - a5 + a6 - a9 - a10" }, { "species_name": "NHCL2", - "dynamics_type": "rate", + "expression_type": "rate", "expression": "a3 - a4 + a5 - a6 - a7 - a8 - a10" }, { "species_name": "I", - "dynamics_type": "rate", + "expression_type": "rate", "expression": "a7 - a8 - a9" }, { "species_name": "H", - "dynamics_type": "rate", + "expression_type": "rate", "expression": "0" }, { "species_name": "ALK", - "dynamics_type": "rate", + "expression_type": "rate", "expression": "0" }, { "species_name": "OCL", - "dynamics_type": "equil", + "expression_type": "equil", "expression": "H * OCL - 3.16E-8 * HOCL" }, { "species_name": "NH4", - "dynamics_type": "equil", + "expression_type": "equil", "expression": "H * NH3 - 5.01e-10 * NH4" }, { "species_name": "CO3", - "dynamics_type": "equil", + "expression_type": "equil", "expression": "H * CO3 - 5.01e-11 * HCO3" }, { "species_name": "H2CO3", - "dynamics_type": "equil", + "expression_type": "equil", "expression": "H * HCO3 - 5.01e-7 * H2CO3" }, { "species_name": "HCO3", - "dynamics_type": "equil", + "expression_type": "equil", "expression": "ALK - HC03 - 2*CO3 - OH + H" }, { "species_name": "OH", - "dynamics_type": "equil", + "expression_type": "equil", "expression": "H * OH - 1.0e-14" }, { "species_name": "chloramine", - "dynamics_type": "formula", + "expression_type": "formula", "expression": "1000 * NH2CL" } ], diff --git a/wntr/quality/_library_data/lead_ppm.json b/wntr/msx/_library_data/lead_ppm.json similarity index 94% rename from wntr/quality/_library_data/lead_ppm.json rename to wntr/msx/_library_data/lead_ppm.json index 129140c45..63a69e852 100644 --- a/wntr/quality/_library_data/lead_ppm.json +++ b/wntr/msx/_library_data/lead_ppm.json @@ -2,7 +2,7 @@ "wntr-version": "1.0.0", "name": "lead_ppm", "title": "Lead Plumbosolvency Model (from Burkhardt et al 2020)", - "desc": "Parameters for EPA HPS Simulator Model", + "description": "Parameters for EPA HPS Simulator Model", "references": [ "J. B. Burkhardt, et al. (2020) \"Framework for Modeling Lead in Premise Plumbing Systems Using EPANET\". J Water Resour Plan Manag. 146(12). https://doi.org/10.1061/(asce)wr.1943-5452.0001304 PMID:33627937" ], @@ -42,14 +42,14 @@ "pipe_reactions": [ { "species_name": "PB2", - "dynamics_type": "rate", + "expression_type": "rate", "expression": "F * Av * M * (E - PB2) / E" } ], "tank_reactions": [ { "species_name": "PB2", - "dynamics_type": "rate", + "expression_type": "rate", "expression": "0" } ] diff --git a/wntr/quality/_library_data/nicotine.json b/wntr/msx/_library_data/nicotine.json similarity index 96% rename from wntr/quality/_library_data/nicotine.json rename to wntr/msx/_library_data/nicotine.json index 5ab62fc9d..7603d684d 100644 --- a/wntr/quality/_library_data/nicotine.json +++ b/wntr/msx/_library_data/nicotine.json @@ -2,7 +2,7 @@ "wntr-version": "1.0.0", "name": "nicotine", "title": "Nicotine - Chlorine reaction", - "desc": null, + "description": null, "references": [], "reaction_system": { "species": [ @@ -57,12 +57,12 @@ "pipe_reactions": [ { "species_name": "Nx", - "dynamics_type": "rate", + "expression_type": "rate", "expression": "-RxN" }, { "species_name": "HOCL", - "dynamics_type": "rate", + "expression_type": "rate", "expression": "-RxCl" } ], diff --git a/wntr/quality/_library_data/nicotine_ri.json b/wntr/msx/_library_data/nicotine_ri.json similarity index 93% rename from wntr/quality/_library_data/nicotine_ri.json rename to wntr/msx/_library_data/nicotine_ri.json index 3e9a2d981..f73267661 100644 --- a/wntr/quality/_library_data/nicotine_ri.json +++ b/wntr/msx/_library_data/nicotine_ri.json @@ -2,7 +2,7 @@ "wntr-version": "1.0.0", "name": "nicotine_ri", "title": "Nicotine - Chlorine reaction with reactive intermediate", - "desc": null, + "description": null, "references": [], "reaction_system": { "species": [ @@ -81,34 +81,34 @@ "pipe_reactions": [ { "species_name": "Nx", - "dynamics_type": "rate", + "expression_type": "rate", "expression": "-RXN" }, { "species_name": "HOCL", - "dynamics_type": "rate", + "expression_type": "rate", "expression": "-RXCL" }, { "species_name": "NX2", - "dynamics_type": "rate", + "expression_type": "rate", "expression": "RXNX2" } ], "tank_reactions": [ { "species_name": "Nx", - "dynamics_type": "rate", + "expression_type": "rate", "expression": "-RXN" }, { "species_name": "HOCL", - "dynamics_type": "rate", + "expression_type": "rate", "expression": "-RXCL" }, { "species_name": "NX2", - "dynamics_type": "rate", + "expression_type": "rate", "expression": "RXNX2" } ] diff --git a/wntr/quality/base.py b/wntr/msx/base.py similarity index 81% rename from wntr/quality/base.py rename to wntr/msx/base.py index 8e05f1a49..80b3b8d72 100644 --- a/wntr/quality/base.py +++ b/wntr/msx/base.py @@ -5,10 +5,11 @@ and/or mixin classes, and should not be instantiated directly. """ -from abc import ABC, abstractmethod, abstractproperty +from abc import ABC, abstractclassmethod, abstractmethod, abstractproperty import logging from enum import Enum, IntEnum -from typing import Any, Dict, Iterator +import os +from typing import Any, Dict, Iterator, List, Union from wntr.utils.disjoint_mapping import DisjointMapping from wntr.utils.enumtools import add_get @@ -109,6 +110,22 @@ def _coth(x): logger = logging.getLogger(__name__) +__all__ = [ + "HYDRAULIC_VARIABLES", + "EXPR_FUNCTIONS", + "RESERVED_NAMES", + "EXPR_TRANSFORMS", + "VariableType", + "SpeciesType", + "ReactionType", + "ExpressionType", + "AbstractVariable", + "AbstractReaction", + "ReactionSystem", + "VariableValues", + "AbstractModel", +] + HYDRAULIC_VARIABLES = [ {"name": "D", "note": "pipe diameter (feet or meters) "}, { @@ -282,7 +299,7 @@ def __init__(self, value, note=None): @add_get(abbrev=True) -class QualityVarType(IntEnum): +class VariableType(IntEnum): """The type of reaction variable. The following types are defined, and aliases of just the first character @@ -379,7 +396,7 @@ class ReactionType(Enum): @add_get(abbrev=True) -class DynamicsType(Enum): +class ExpressionType(Enum): """The type of reaction expression. The following types are defined, and aliases of just the first character @@ -412,21 +429,7 @@ class DynamicsType(Enum): F = FORMULA -__all__ = [ - "HYDRAULIC_VARIABLES", - "EXPR_FUNCTIONS", - "RESERVED_NAMES", - "EXPR_TRANSFORMS", - "QualityVarType", - "SpeciesType", - "ReactionType", - "DynamicsType", - "WaterQualityVariable", - "WaterQualityReaction", -] - - -class WaterQualityReaction(ABC): +class AbstractReaction(ABC): def __init__(self, species_name: str, *, note=None) -> None: """A water quality reaction definition. @@ -447,7 +450,7 @@ def __init__(self, species_name: str, *, note=None) -> None: Raises ------ TypeError - if dynamics_type is invalid + if expression_type is invalid """ if species_name is None: raise TypeError("The species_name cannot be None") @@ -462,7 +465,7 @@ def species_name(self) -> str: def reaction_type(self) -> Enum: """The type of reaction or where this reaction occurs.""" raise NotImplementedError - + def __str__(self) -> str: return "{}->{}".format(self.species_name, self.reaction_type.name) @@ -478,16 +481,16 @@ def to_dict(self) -> dict: raise NotImplementedError -class WaterQualityVariable(ABC): +class AbstractVariable(ABC): """A multi-species water quality model variable. This abstract class must be extended before use. There are several concrete classes that inhert from this class, including - :class:`~wntr.quality.msx.Species`, - :class:`~wntr.quality.msx.Constant`, - :class:`~wntr.quality.msx.Parameter`, - and :class:`~wntr.quality.msx.Term`. - See also the :class:`~wntr.quality.msx.MultispeciesModel`, which has the functions + :class:`~wntr.msx.msx.Species`, + :class:`~wntr.msx.msx.Constant`, + :class:`~wntr.msx.msx.Parameter`, + and :class:`~wntr.msx.msx.Term`. + See also the :class:`~wntr.msx.msx.MultispeciesModel`, which has the functions required to create these variables and define reactions. """ @@ -530,8 +533,8 @@ def __init__(self, name: str, *, note=None) -> None: """A note related to this variable""" @abstractproperty - def var_type(self) -> QualityVarType: - """The type of reaction model variable""" + def var_type(self) -> Enum: + """The type of reaction variable""" raise NotImplementedError @abstractmethod @@ -550,7 +553,7 @@ def __repr__(self) -> str: ) -class WaterQualityReactionSystem(ABC): +class ReactionSystem(ABC): """Abstract class for reaction systems, which contains variables and reaction expressions. This class contains the functions necessary to perform as a mapping view onto the @@ -562,22 +565,22 @@ def __init__(self) -> None: self._rxns = dict() @abstractmethod - def add_variable(self, obj: WaterQualityVariable) -> None: + def add_variable(self, obj: AbstractVariable) -> None: """Add a variable to the system""" raise NotImplementedError - + @abstractmethod - def add_reaction(self, obj: WaterQualityReaction) -> None: + def add_reaction(self, obj: AbstractReaction) -> None: """Add a reaction to the system""" raise NotImplementedError - + @abstractmethod - def all_variables(self): + def variables(self): """A generator looping through all variables""" raise NotImplementedError - + @abstractmethod - def all_reactions(self): + def reactions(self): """A generator looping through all reactions""" raise NotImplementedError @@ -595,7 +598,7 @@ def __eq__(self, __value: object) -> bool: def __ne__(self, __value: object) -> bool: return self._vars.__ne__(__value) - def __getitem__(self, __key: str) -> WaterQualityVariable: + def __getitem__(self, __key: str) -> AbstractVariable: return self._vars.__getitem__(__key) def __iter__(self) -> Iterator: @@ -603,4 +606,83 @@ def __iter__(self) -> Iterator: def __len__(self) -> int: return self._vars.__len__() - \ No newline at end of file + + +class VariableValues(ABC): + """Abstract class for a variable's network-specific values.""" + + @abstractproperty + def var_type(self) -> Enum: + """Define what type of variable this network-specific data is for""" + raise NotImplementedError + + @abstractmethod + def to_dict(self) -> dict: + """Represent the variable's network-specific values as a dictionary""" + raise NotImplementedError + + +class NetworkData(ABC): + """Abstract class containing network specific data. + + This class should be populated with things like initial quality, + sources, parameterized values, etc. + """ + + @abstractmethod + def to_dict(self) -> dict: + """Represent the network specific data as a dictionary""" + raise NotImplementedError + + +class AbstractModel(ABC): + """Abstract water quality model.""" + + def __init__(self, filename=None): + self.name: str = None if filename is None else os.path.splitext(os.path.split(filename)[1])[0] + """A name for the model, or the MSX model filename (no spaces allowed)""" + self.title: str = None + """The title line from the MSX file, must be a single line""" + self.description: str = None + """A longer description, note that multi-line descriptions may not be + represented well in dictionary form.""" + self._orig_file: str = filename + self._options = None + self._rxn_system: ReactionSystem = None + self._net_data: NetworkData = None + self._wn = None + + @abstractproperty + def options(self): + """The model options structure. + + Concrete classes should implement this with the appropriate typeing and + also implement a setter method. + """ + raise NotImplementedError + + @abstractproperty + def reaction_system(self) -> ReactionSystem: + """The reaction variables defined for this model. + + Concrete classes should implement this with the appropriate typing. + """ + raise NotImplementedError + + @abstractproperty + def network_data(self) -> NetworkData: + """The network-specific values added to this model. + + Concrete classes should implement this with the appropriate typing. + """ + raise NotImplementedError + + @abstractmethod + def to_dict(self) -> dict: + """Represent the model as a dictionary.""" + raise NotImplementedError + + @abstractclassmethod + def from_dict(self, data: dict) -> "AbstractModel": + """Create a new model from a dictionary.""" + raise NotImplementedError diff --git a/wntr/msx/elements.py b/wntr/msx/elements.py new file mode 100644 index 000000000..b3be0a463 --- /dev/null +++ b/wntr/msx/elements.py @@ -0,0 +1,693 @@ +# -*- coding: utf-8 -*- + +"""Water quality model implementations. +""" + + +import logging + +from typing import ( + Any, + Callable, + Dict, + Literal, + Tuple, + Union, +) + +from wntr.epanet.util import ENcomment +from wntr.utils.disjoint_mapping import KeyExistsError + +from .base import ( + VariableValues, + AbstractReaction, + ReactionSystem, + AbstractVariable, + ExpressionType, + ReactionType, + VariableType, + SpeciesType, +) + +has_sympy = False +try: + from sympy import Float, Symbol, init_printing, symbols + from sympy.parsing import parse_expr + from sympy.parsing.sympy_parser import convert_xor, standard_transformations + + has_sympy = True +except ImportError: + sympy = None + logging.critical("This python installation does not have SymPy installed. " "Certain functionality will be disabled.") + standard_transformations = (None,) + convert_xor = None + has_sympy = False + + +logger = logging.getLogger(__name__) + +__all__ = [ + 'Species', + 'Constant', + 'Parameter', + 'Term', + 'ReservedName', + 'HydraulicVariable', + 'MathFunction', + 'Reaction' +] + + +class Species(AbstractVariable): + """A biological or chemical species that impacts water quality. + + .. rubric:: Attributes + + .. autosummary:: + + ~Species.name + ~Species.species_type + ~Species.units + ~Species.note + ~Species.diffusivity + + .. rubric:: Methods + + .. autosummary:: + + ~Species.set_tolerances + ~Species.get_tolerances + ~Species.clear_tolerances + ~Species.to_dict + + .. rubric:: Read-only Attributes + + .. autosummary:: + + ~Species.atol + ~Species.rtol + ~Species.initial_quality + ~Species.pipe_reaction + ~Species.tank_reaction + + """ + + def __init__( + self, + name: str, + species_type: Union[SpeciesType, str], + units: str, + atol: float = None, + rtol: float = None, + *, + note: Union[str, dict, ENcomment]=None, + diffusivity: float = None, + _vars: ReactionSystem = None, + _vals: VariableValues = None, + ) -> None: + """A biological or chemical species. + + Parameters + ---------- + name : str + The species name + species_type : SpeciesType or str + The species type + units : str + The units of mass for this species, see :attr:`units` property. + atol : float, optional, requires rtol + The absolute tolerance when solving this species' equations, by default None + rtol : float, optional, requires atol + The relative tolerance when solving this species' equations, by default None + note : str or dict or ENcomment, optional + Supplementary information regarding this variable, by default None + diffusivity : float, optional + Diffusivity of the species in water, by default None + + Other Parameters + ---------------- + _vars : MsxReactionSystem, optional + the reaction system this species is a part of, by default None + _vals : InitialQuality, optional + the initial quality values for this species, by default None + + Raises + ------ + KeyExistsError + if the name has already been used + TypeError + if a tank reaction is provided for a wall species + """ + super().__init__(name, note=note) + if _vars is not None and not isinstance(_vars, ReactionSystem): + raise TypeError("Invalid type for _vars, {}".format(type(_vars))) + if _vals is not None and not isinstance(_vals, InitialQuality): + raise TypeError("Invalid type for _vals, {}".format(type(_vals))) + if _vars is not None and name in _vars: + raise KeyExistsError("This variable name is already taken") + species_type = SpeciesType.get(species_type) + if species_type is None: + raise TypeError("species_type cannot be None") + self._species_type = species_type + self._tolerances = None + self.set_tolerances(atol, rtol) + self.units: str = units + """The units of mass for this species. + For bulk species, concentration is this unit divided by liters, for wall species, concentration is this unit + divided by the model's area-unit (see options). + """ + self.diffusivity: float = diffusivity + """The diffusivity of this species in water, if being used, by default None""" + self._vars = _vars + self._vals = _vals + + def set_tolerances(self, atol: float, rtol: float): + """Set the absolute and relative tolerance for the solvers. + + The user must set both values, or neither value (None). Values must be + positive. + + Parameters + ---------- + atol : float + The absolute tolerance to use + rtol : float + The relative tolerance to use + + Raises + ------ + TypeError + if only one of `atol` or `rtol` is a float + ValueError + if either value is less-than-or-equal-to zero + """ + if (self.atol is None) ^ (self.rtol is None): + raise TypeError("atol and rtol must both be float or both be None") + if self.atol is None: + self._tolerances = None + elif atol <= 0 or rtol <= 0: + raise ValueError("atol and rtol must both be positive, got atol={}, rtol={}".format(atol, rtol)) + else: + self._tolerances = (atol, rtol) + + def get_tolerances(self) -> Union[Tuple[float, float], None]: + """Get the custom solver tolerances for this species. + + Returns + ------- + Union[Tuple[float, float], None] + absolute and relative tolerances, respectively, if they are set + """ + return self._tolerances + + def clear_tolerances(self): + """Set both tolerances to None, reverting to the global options value.""" + self._tolerances = None + + @property + def atol(self) -> float: + """The absolute tolerance. Must be set using :meth:`set_tolerances`""" + if self._tolerances is not None: + return self._tolerances[0] + return None + + @property + def rtol(self) -> float: + """The relative tolerance. Must be set using :meth:`set_tolerances`""" + if self._tolerances is not None: + return self._tolerances[1] + return None + + @property + def var_type(self) -> VariableType: + """This is a species""" + return VariableType.SPECIES + + @property + def species_type(self) -> SpeciesType: + """The type of species""" + return self._species_type + + @property + def initial_quality(self): + """If a specific network has been linked, then the initial quality values for the network""" + if self._vals is not None: + return self._vals + else: + raise TypeError("This species is not linked to a NetworkData obejct, please `relink` your model") + + @property + def pipe_reaction(self): + if self._vars is not None: + return self._vars.pipe_reactions[self.name] + else: + raise AttributeError('This species is not connected to a ReactionSystem') + + @property + def tank_reaction(self): + if self._vars is not None: + return self._vars.tank_reactions[self.name] + else: + raise AttributeError('This species is not connected to a ReactionSystem') + + def to_dict(self) -> Dict[str, Any]: + """Create a dictionary representation of the object + + The species dictionary has the following format, as described using a json schema. + + .. code:: json + + { + "title": "Species", + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "species_type": { + "enum": ["bulk", "wall"] + }, + "units": { + "type": "string" + }, + "atol": { + "type": "number", + "exclusiveMinimum": 0 + }, + "rtol": { + "type": "number", + "exclusiveMinimum": 0 + }, + "note": { + "type": "string" + }, + "diffusivity": { + "type": "number", + "minimum": 0 + } + }, + "required": ["name", "species_type", "units", "pipe_reaction", "tank_reaction"], + "dependentRequired": {"atol": ["rtol"], "rtol":["atol"]} + } + + """ + ret = dict( + name=self.name, species_type=self.species_type.name.lower(), units=self.units, atol=self.atol, rtol=self.rtol + ) + + if self.diffusivity: + ret["diffusivity"] = self.diffusivity + + if isinstance(self.note, ENcomment): + ret["note"] = self.note.to_dict() + elif isinstance(self.note, (str, dict, list)): + ret["note"] = self.note + + return ret + + +class Constant(AbstractVariable): + """A constant coefficient for use in reaction expressions.""" + + def __init__(self, name: str, value: float, *, units: str = None, note: Union[str, dict, ENcomment]=None, _vars: ReactionSystem = None) -> None: + """A variable representing a constant value. + + Parameters + ---------- + name : str + The name of the variable. + value : float + The constant value. + units : str, optional + Units for the variable, by default None + note : str or dict or ENcomment, optional + Supplementary information regarding this variable, by default None + + Other Parameters + ---------------- + _vars : MsxReactionSystem, optional + the reaction system this constant is a part of, by default None + """ + super().__init__(name, note=note) + if _vars is not None and not isinstance(_vars, ReactionSystem): + raise TypeError("Invalid type for _vars, {}".format(type(_vars))) + if _vars is not None and name in _vars: + raise KeyExistsError("This variable name is already taken") + self.value = float(value) + """The value of the constant""" + self.units = units + """The units of the constant""" + self._vars = _vars + + def __call__(self, *, t=None) -> Any: + return self.value + + @property + def var_type(self) -> VariableType: + """This is a constant coefficient.""" + return VariableType.CONSTANT + + def to_dict(self) -> Dict[str, Any]: + ret = dict(name=self.name, value=self.value) + if self.units: + ret["units"] = self.units + if isinstance(self.note, ENcomment): + ret["note"] = self.note.to_dict() + elif isinstance(self.note, (str, dict, list)): + ret["note"] = self.note + return ret + + +class Parameter(AbstractVariable): + """A coefficient that is parameterized by pipe/tank.""" + + def __init__(self, name: str, global_value: float, *, units: str = None, note: Union[str, dict, ENcomment]=None, _vars: ReactionSystem = None, _vals: VariableValues=None) -> None: + """A parameterized variable for use in expressions. + + Parameters + ---------- + name : str + The name of this parameter. + global_value : float + The global value for the parameter if otherwise unspecified. + units : str, optional + The units for this parameter, by default None + note : str or dict or ENcomment, optional + Supplementary information regarding this variable, by default None + + Other Parameters + ---------------- + _vars : MsxReactionSystem, optional + the reaction system this parameter is a part of, by default None + _vals : ParameterValues, optional + the netork-specific values for this parameter, by default None + """ + super().__init__(name, note=note) + if _vars is not None and not isinstance(_vars, ReactionSystem): + raise TypeError("Invalid type for _vars, {}".format(type(_vars))) + if _vals is not None and not isinstance(_vals, ParameterValues): + raise TypeError("Invalid type for _vals, {}".format(type(_vals))) + if _vars is not None and name in _vars: + raise KeyExistsError("This variable name is already taken") + self.global_value = float(global_value) + self.units = units + self._vars = _vars + self._vals = _vals + + def __call__(self, *, t=None, pipe: float = None, tank: float = None) -> Any: + if pipe is not None and tank is not None: + raise TypeError("Both pipe and tank cannot be specified at the same time") + elif self._vals is None and (pipe is not None or tank is not None): + raise ValueError("No link provided to network-specific parameter values") + if pipe: + return self._vals.pipe_values.get(pipe, self.global_value) + elif tank: + return self._vals.tank_values.get(pipe, self.global_value) + return self.global_value + + @property + def var_type(self) -> VariableType: + """This is a parameterized coefficient.""" + return VariableType.PARAMETER + + def to_dict(self) -> Dict[str, Any]: + ret = dict(name=self.name, global_value=self.global_value) + if self.units: + ret["units"] = self.units + if isinstance(self.note, ENcomment): + ret["note"] = self.note.to_dict() + elif isinstance(self.note, (str, dict, list)): + ret["note"] = self.note + return ret + + +class Term(AbstractVariable): + def __init__(self, name: str, expression: str, *, note: Union[str, dict, ENcomment]=None, _vars: ReactionSystem = None) -> None: + """A named expression that can be used as a term in other expressions. + + Parameters + ---------- + name : str + The variable name. + expression : str + The mathematical expression to be aliased + note : str or dict or ENcomment, optional + Supplementary information regarding this variable, by default None + + Other Parameters + ---------------- + _vars : MsxReactionSystem, optional + the reaction system this species is a part of, by default None + """ + super().__init__(name, note=note) + if _vars is not None and not isinstance(_vars, ReactionSystem): + raise TypeError("Invalid type for _vars, {}".format(type(_vars))) + if _vars is not None and name in _vars: + raise KeyExistsError("This variable name is already taken") + self.expression = expression + """The expression that is aliased by this term""" + self._vars = _vars + + @property + def var_type(self) -> VariableType: + """This is a term (named expression).""" + return VariableType.TERM + + def to_dict(self) -> Dict[str, Any]: + ret = dict(name=self.name, expression=self.expression) + if isinstance(self.note, ENcomment): + ret["note"] = self.note.to_dict() + elif isinstance(self.note, (str, dict, list)): + ret["note"] = self.note + return ret + + +class ReservedName(AbstractVariable): + def __init__(self, name: str, *, note: Union[str, dict, ENcomment]=None) -> None: + """An object representing a reserved name that should not be used by the user. + + Parameters + ---------- + name : str + The reserved name. + note : str or dict or ENcomment, optional + Supplementary information regarding this variable, by default None + + Other Parameters + ---------------- + _vars : MsxReactionSystem, optional + the reaction system this species is a part of, by default None + + Raises + ------ + KeyExistsError + _description_ + """ + self.name = name + self.note = note + + @property + def var_type(self) -> VariableType: + """Variable name is a reserved word in MSX""" + return VariableType.RESERVED + + def to_dict(self) -> Dict[str, Any]: + return '{}({})'.format(self.__class__.__name__, ', '.join(['name={}'.format(repr(self.name)), 'note={}'.format(repr(self.note))])) + + +class HydraulicVariable(ReservedName): + """A variable representing instantaneous hydraulics data.""" + + def __init__(self, name: str, units: str = None, *, note: Union[str, dict, ENcomment]=None) -> None: + """A variable representing instantaneous hydraulics data. + + The user should not need to create any variables using this class, they + are created automatically by the MultispeciesModel object during initialization. + + Parameters + ---------- + name : str + The name of the variable (predefined by MSX) + units : str, optional + The units for hydraulic variable, by default None + note : str or dict or ENcomment, optional + Supplementary information regarding this variable, by default None + """ + super().__init__(name, note=note) + self.units = units + """The hydraulic variable's units""" + + +class MathFunction(ReservedName): + """A variable that is actually a mathematical function defined by MSX.""" + + def __init__(self, name: str, func: Callable, *, note: Union[str, dict, ENcomment]=None) -> None: + """A variable that is actually a mathematical function defined by MSX. + + Parameters + ---------- + name : str + The function name + func : Callable + The callable function + note : str or dict or ENcomment, optional + Supplementary information regarding this variable, by default None + """ + super().__init__(name, note=note) + self.func = func + """A callable function or SymPy function""" + + def __call__(self, *args: Any, **kwds: Any) -> Any: + return self.func(*args, **kwds) + + +class Reaction(AbstractReaction): + """A water quality biochemical reaction dynamics definition for a specific species.""" + + def __init__( + self, species_name: str, reaction_type: ReactionType, expression_type: ExpressionType, expression: str, *, note: Union[str, dict, ENcomment]=None, _vars: ReactionSystem = None + ) -> None: + """A water quality biochemical reaction dynamics definition for a specific species. + + Parameters + ---------- + species_name : str + The species (object or name) this reaction is applicable to. + reaction_type : ReactionType + The type of reaction, either PIPE or TANK + expression_type : ExpressionType + The type of reaction dynamics being described by the expression: one of RATE, FORMULA, or EQUIL. + expression : str + The mathematical expression for the right-hand-side of the reaction equation. + note : str or dict or ENcomment, optional + Supplementary information regarding this variable, by default None + + Other Parameters + ---------------- + _vars : MsxReactionSystem, optional + the reaction system this species is a part of, by default None + """ + super().__init__(species_name=species_name, note=note) + if _vars is not None and not isinstance(_vars, ReactionSystem): + raise TypeError("Invalid type for _vars, {}".format(type(_vars))) + expression_type = ExpressionType.get(expression_type) + reaction_type = ReactionType.get(reaction_type) + if reaction_type is None: + raise TypeError("Required argument reaction_type cannot be None") + if expression_type is None: + raise TypeError("Required argument expression_type cannot be None") + self.__rxn_type = reaction_type + self._expr_type = expression_type + if not expression: + raise TypeError("expression cannot be None") + self.expression = expression + """The mathematical expression (right-hand-side)""" + self._vars = _vars + + @property + def expression_type(self) -> ExpressionType: + """The type of dynamics being described: RATE, EQUIL or FORMULA""" + return self._expr_type + + @property + def reaction_type(self) -> ReactionType: + """The type (i.e., location) of reaction: will be PIPE or TANK""" + return self.__rxn_type + + def to_dict(self) -> dict: + ret = dict( + species_name=str(self.species_name), expression_type=self.expression_type.name.lower(), expression=self.expression + ) + if isinstance(self.note, ENcomment): + ret["note"] = self.note.to_dict() + elif isinstance(self.note, (str, dict, list)): + ret["note"] = self.note + return ret + + +class InitialQuality(VariableValues): + """A container for initial quality values for a species in a specific network.""" + + def __init__(self, global_value: float = 0.0, node_values: dict = None, link_values: dict = None): + """The initial quality values for a species. + + Arguments + --------- + global_value : float, optional + _description_, by default 0.0 + node_values : dict[str, float], optional + _description_, by default None + link_values : dict[str, float], optional + _description_, by default None + """ + self.global_value = global_value + """The global initial quality for this species. + + Will be set to 0.0 when not explicitly specified, and can be overridden for + specific nodes and links using the other members of this class.""" + self._node_values = node_values if node_values is not None else dict() + self._link_values = link_values if link_values is not None else dict() + + def __repr__(self) -> str: + return self.__class__.__name__ + "(global_value={}, node_values=<{} entries>, link_values=<{} entries>)".format( + self.global_value, len(self._node_values), len(self._link_values) + ) + + @property + def var_type(self) -> VariableType: + """This is data for a species""" + return VariableType.SPECIES + + @property + def node_values(self) -> Dict[str, float]: + """A mapping that overrides the global_value of the initial quality at specific nodes""" + return self._node_values + + @property + def link_values(self) -> Dict[str, float]: + """A mapping that overrides the global_value of the initial quality in specific links""" + return self._link_values + + def to_dict(self) -> Dict[str, Dict[str, float]]: + return dict(global_value=self.global_value, node_values=self._node_values.copy(), link_values=self._link_values.copy()) + + +class ParameterValues(VariableValues): + """A container for pipe and tank specific values of a parameter for a specific network.""" + + def __init__(self, *, pipe_values: dict = None, tank_values: dict = None) -> None: + """The non-global values for a parameter. + + Arguments + --------- + pipe_values : dict, optional + _description_, by default None + tank_values : dict, optional + _description_, by default None + """ + self._pipe_values = pipe_values if pipe_values is not None else dict() + self._tank_values = tank_values if tank_values is not None else dict() + + def __repr__(self) -> str: + return self.__class__.__name__ + "(pipe_values=<{} entries>, tank_values=<{} entries>)".format( + len(self._pipe_values), len(self._tank_values) + ) + + @property + def var_type(self) -> VariableType: + """This is data for a parameter""" + return VariableType.PARAMETER + + @property + def pipe_values(self) -> Dict[str, float]: + """A mapping that overrides the global_value of a parameter for a specific pipe""" + return self._pipe_values + + @property + def tank_values(self) -> Dict[str, float]: + """A mapping that overrides the global_value of a parameter for a specific tank""" + return self._tank_values + + def to_dict(self) -> Dict[str, Dict[str, float]]: + return dict(pipe_values=self._pipe_values.copy(), tank_values=self._tank_values.copy()) + diff --git a/wntr/quality/library.py b/wntr/msx/library.py similarity index 94% rename from wntr/quality/library.py rename to wntr/msx/library.py index 482523877..9e9d4bcb6 100644 --- a/wntr/quality/library.py +++ b/wntr/msx/library.py @@ -13,7 +13,7 @@ path to search for quality model files, (files with an ".msx", ".yaml", or ".json" file extension). Multiple folders should be separated using the "``;``" character. - See :class:`~wntr.quality.library.ReactionLibrary` for more details. + See :class:`~wntr.msx.library.ReactionLibrary` for more details. """ @@ -22,8 +22,8 @@ from typing import Any, ItemsView, Iterator, KeysView, List, Tuple, Union, ValuesView from pkg_resources import resource_filename -from .multispecies import MultispeciesQualityModel -from .base import ReactionType, SpeciesType, DynamicsType +from .model import MsxModel +from .base import ReactionType, SpeciesType, ExpressionType import json @@ -39,9 +39,9 @@ TANK = ReactionType.TANK BULK = SpeciesType.BULK WALL = SpeciesType.WALL -RATE = DynamicsType.RATE -EQUIL = DynamicsType.EQUIL -FORMULA = DynamicsType.FORMULA +RATE = ExpressionType.RATE +EQUIL = ExpressionType.EQUIL +FORMULA = ExpressionType.FORMULA logger = logging.getLogger(__name__) @@ -143,7 +143,7 @@ def __init__(self, extra_paths: List[str] = None, include_builtins=True, include self.reset_and_reload() def __repr__(self) -> str: - if len(self.__library_paths > 3): + if len(self.__library_paths) > 3: return "{}(initial_paths=[{}, ..., {}])".format( self.__class__.__name__, repr(self.__library_paths[0]), repr(self.__library_paths[-1]) ) @@ -219,7 +219,7 @@ def reset_and_reload(self, duplicates: str = "error") -> List[Tuple[str, str, An load_errors.extend(errs) return load_errors - def add_models_from_dir(self, path_to_dir: str, duplicates: str = "error") -> List[Tuple[str, str, Union[MultispeciesQualityModel, Exception]]]: + def add_models_from_dir(self, path_to_dir: str, duplicates: str = "error") -> List[Tuple[str, str, Union[MsxModel, Exception]]]: """Load all valid model files in a folder. Note, this function is not recursive and does not 'walk' a directory tree. @@ -277,7 +277,7 @@ def add_models_from_dir(self, path_to_dir: str, duplicates: str = "error") -> Li continue if ext.lower() == ".msx": try: - new = MultispeciesQualityModel(file) + new = MsxModel(file) except Exception as e: logger.exception("Error reading file {}".format(os.path.join(folder, file))) load_errors.append((os.path.join(folder, file), "load-failed", e)) @@ -285,7 +285,7 @@ def add_models_from_dir(self, path_to_dir: str, duplicates: str = "error") -> Li elif ext.lower() == ".json": with open(os.path.join(folder, file), "r") as fin: try: - new = MultispeciesQualityModel.from_dict(json.load(fin)) + new = MsxModel.from_dict(json.load(fin)) except Exception as e: logger.exception("Error reading file {}".format(os.path.join(folder, file))) load_errors.append((os.path.join(folder, file), "load-failed", e)) @@ -297,7 +297,7 @@ def add_models_from_dir(self, path_to_dir: str, duplicates: str = "error") -> Li continue with open(os.path.join(folder, file), "r") as fin: try: - new = MultispeciesQualityModel.from_dict(yaml.safe_load(fin)) + new = MsxModel.from_dict(yaml.safe_load(fin)) except Exception as e: logger.exception("Error reading file {}".format(os.path.join(folder, file))) load_errors.append((os.path.join(folder, file), "load-failed", e)) @@ -350,15 +350,15 @@ def add_model_from_file(self, path_and_filename: str, name: str = None): if ext is None or ext.lower() not in [".msx", ".json", ".yaml"]: raise IOError("The file is in an unknown format, {}".format(ext)) if ext.lower() == ".msx": - new = MultispeciesQualityModel(path_and_filename) + new = MsxModel(path_and_filename) elif ext.lower() == ".json": with open(path_and_filename, "r") as fin: - new = MultispeciesQualityModel.from_dict(json.load(fin)) + new = MsxModel.from_dict(json.load(fin)) elif ext.lower() == ".yaml": if yaml is None: raise RuntimeError("Unable to import yaml") from yaml_err with open(path_and_filename, "r") as fin: - new = MultispeciesQualityModel.from_dict(yaml.safe_load(fin)) + new = MsxModel.from_dict(yaml.safe_load(fin)) else: # pragma: no cover raise RuntimeError("This should be impossible to reach, since ext is checked above") new._orig_file = path_and_filename @@ -368,7 +368,7 @@ def add_model_from_file(self, path_and_filename: str, name: str = None): new.name = name self.__data[new.name] = new - def get_model(self, name: str) -> MultispeciesQualityModel: + def get_model(self, name: str) -> MsxModel: """Get a reaction model from the library by model name Parameters diff --git a/wntr/msx/model.py b/wntr/msx/model.py new file mode 100644 index 000000000..18d6343ad --- /dev/null +++ b/wntr/msx/model.py @@ -0,0 +1,770 @@ +# -*- coding: utf-8 -*- + +"""Water quality model implementations. +""" + +import logging + +from typing import ( + Any, + Dict, + List, + Union, +) +import warnings + + +from wntr.msx.elements import Constant, HydraulicVariable, InitialQuality, MathFunction, Parameter, ParameterValues, Reaction, Species, Term +from wntr.utils.disjoint_mapping import KeyExistsError +from .base import ( + NetworkData, + AbstractModel, + AbstractReaction, + ReactionSystem, + AbstractVariable, + HYDRAULIC_VARIABLES, + EXPR_FUNCTIONS, + ExpressionType, + ReactionType, + VariableType, + SpeciesType, +) +from .options import MultispeciesOptions + +has_sympy = False +try: + from sympy import Float, Symbol, init_printing, symbols + from sympy.parsing import parse_expr + from sympy.parsing.sympy_parser import convert_xor, standard_transformations + + has_sympy = True +except ImportError: + sympy = None + logging.critical("This python installation does not have SymPy installed. " "Certain functionality will be disabled.") + standard_transformations = (None,) + convert_xor = None + has_sympy = False + + +logger = logging.getLogger(__name__) + +__all__ = [ + "MsxNetworkData", + "MsxReactionSystem", + "MsxModel", +] + + +class MsxReactionSystem(ReactionSystem): + """A registry for all the variables registered in the multispecies reactions model. + + This object can be used like an immutable mapping, with the ``__len__``, ``__getitem__``, + ``__iter__``, ``__contains__``, ``__eq__`` and ``__ne__`` functions being defined. + """ + + def __init__(self) -> None: + """Create a new reaction system.""" + super().__init__() + self._vars.add_disjoint_group("reserved") + self._species = self._vars.add_disjoint_group("species") + self._const = self._vars.add_disjoint_group("constant") + self._param = self._vars.add_disjoint_group("parameter") + self._term = self._vars.add_disjoint_group("term") + self._rxns = dict(pipe=dict(), tank=dict()) + self._pipes = self._rxns["pipe"] + self._tanks = self._rxns["tank"] + + @property + def species(self) -> Dict[str, Species]: + """The dictionary view onto only species""" + return self._species + + @property + def constants(self) -> Dict[str, Constant]: + """The dictionary view onto only constants""" + return self._const + + @property + def parameters(self) -> Dict[str, Parameter]: + """The dictionary view onto only parameters""" + return self._param + + @property + def terms(self) -> Dict[str, Term]: + """The dictionary view onto only named terms""" + return self._term + + @property + def pipe_reactions(self) -> Dict[str, AbstractReaction]: + """The dictionary view onto pipe reactions""" + return self._pipes + + @property + def tank_reactions(self) -> Dict[str, AbstractReaction]: + """The dictionary view onto tank reactions""" + return self._tanks + + def add_variable(self, obj: AbstractVariable) -> None: + """Add a variable object to the registry. + + The appropriate group is determined by querying the object's + var_type attribute. + + Arguments + --------- + obj : WaterQualityVariable + The variable to add. + + Raises + ------ + TypeError + if obj is not a WaterQualityVariable + KeyExistsError + if obj has a name that is already used in the registry + """ + if not isinstance(obj, AbstractVariable): + raise TypeError("Expected WaterQualityVariable object") + if obj.name in self: + raise KeyExistsError("Variable name {} already exists in model".format(obj.name)) + obj._vars = self + self._vars.add_item_to_group(obj.var_type.name.lower(), obj.name, obj) + + def add_reaction(self, obj: AbstractReaction) -> None: + """Add a reaction to the model + + Parameters + ---------- + obj : WaterQualityReaction + _description_ + + Raises + ------ + TypeError + _description_ + KeyError + _description_ + """ + if not isinstance(obj, AbstractReaction): + raise TypeError("Expected WaterQualityReaction object") + if obj.species_name not in self: + raise KeyError("Species {} does not exist in the model".format(obj.species_name)) + self._rxns[obj.reaction_type.name.lower()][obj.species_name] = obj + + def variables(self): + # FIXME: rename without "all_" for this + """A generator looping through all variables""" + for k, v in self._vars.items(): + yield k, v.var_type.name.lower(), v + + def reactions(self): + """A generator looping through all reactions""" + for k2, v in self._rxns.items(): + for k1, v1 in v.items(): + yield k1, k2, v1 + + def to_dict(self) -> dict: + return dict( + species=[v.to_dict() for v in self._species.values()], + constants=[v.to_dict() for v in self._const.values()], + parameters=[v.to_dict() for v in self._param.values()], + terms=[v.to_dict() for v in self._term.values()], + pipe_reactions=[v.to_dict() for v in self.pipe_reactions.values()], + tank_reactions=[v.to_dict() for v in self.tank_reactions.values()], + ) + + +class MsxNetworkData(NetworkData): + """A container for network-specific values associated with a multispecies water quality model.""" + + def __init__( + self, patterns: dict = None, sources: dict = None, initial_quality: dict = None, parameter_values: dict = None + ) -> None: + """A container for network-specific values associated with a multispecies water quality model. + + Data is copied from dictionaries passed in, so once created, the dictionaries passed are not connected + to this object. + + Parameters + ---------- + patterns : Dict[str, List[float]] + patterns to use for sources + sources : Dict[str, dict] + sources defined for the model + initial_quality : Dict[str, dict] + initial values for different species at different nodes, links, and the global value + parameter_values : Dict[str, dict] + parameter values for different pipes and tanks + """ + if sources is None: + sources = dict() + if initial_quality is None: + initial_quality = dict() + if patterns is None: + patterns = dict() + if parameter_values is None: + parameter_values = dict() + self._source_dict = dict() + self._pattern_dict = dict() + self._initial_quality_dict: Dict[str, InitialQuality] = dict() + self._parameter_value_dict: Dict[str, ParameterValues] = dict() + + self._source_dict = sources.copy() + self._pattern_dict = patterns.copy() + for k, v in initial_quality.items(): + self._initial_quality_dict[k] = InitialQuality(**v) + for k, v in parameter_values.items(): + self._parameter_value_dict[k] = ParameterValues(**v) + + @property + def sources(self): + """A dictionary of sources, keyed by species name""" + return self._source_dict + + @property + def initial_quality(self) -> Dict[str, InitialQuality]: + """A dictionary of initial quality values, keyed by species name""" + return self._initial_quality_dict + + @property + def patterns(self): + """A dictionary of patterns, specific for the water quality model, keyed by pattern name. + + .. note:: the WaterNetworkModel cannot see these patterns, so names can be reused, so be + careful. Likewise, this model cannot see the WaterNetworkModel patterns, so this could be + a source of some confusion. + """ + return self._pattern_dict + + @property + def parameter_values(self): + """A dictionary of parameter values, keyed by parameter name""" + return self._parameter_value_dict + + def add_pattern(self, name: str, multipliers: List[float]): + """Add a water-quality-model-specific pattern. + + Arguments + --------- + name : str + The pattern name + multipliers : List[float] + The pattern multipliers + """ + self._pattern_dict[name] = multipliers + + def init_new_species(self, species: Species): + """(Re)set the initial quality values for a species to a new container + + Arguments + --------- + species : Species + The species to (re) initialized. + + Returns + ------- + InitialQuality + the new initial quality values container + """ + self._initial_quality_dict[str(species)] = InitialQuality() + if isinstance(species, Species): + species._vals = self._initial_quality_dict[str(species)] + return self._initial_quality_dict[str(species)] + + def remove_species(self, species: Union[Species, str]): + """Remove a species from the network specific model. + + Arguments + --------- + species : Union[Species, str] + _description_ + """ + if isinstance(species, Species): + species._vals = None + try: + self._initial_quality_dict.__delitem__(str(species)) + except KeyError: + pass + + def init_new_parameter(self, param: Parameter): + """(Re)initialize parameter values for a parameter. + + Arguments + --------- + param : Parameter + _description_ + + Returns + ------- + _type_ + _description_ + """ + self._parameter_value_dict[str(param)] = ParameterValues() + if isinstance(param, Parameter): + param._vals = self._parameter_value_dict[str(param)] + return self._parameter_value_dict[str(param)] + + def remove_parameter(self, param: Union[Parameter, str]): + """Remove values associated with a specific parameter. + + Arguments + --------- + param : Union[Parameter, str] + _description_ + """ + if isinstance(param, Parameter): + param._vals = None + try: + self._parameter_value_dict.__delitem__(str(param)) + except KeyError: + pass + + def to_dict(self) -> dict: + ret = dict(initial_quality=dict(), parameter_values=dict(), sources=dict(), patterns=dict()) + for k, v in self._initial_quality_dict.items(): + ret["initial_quality"][k] = v.to_dict() + for k, v in self._parameter_value_dict.items(): + ret["parameter_values"][k] = v.to_dict() + ret["sources"] = self._source_dict.copy() + ret["patterns"] = self._pattern_dict.copy() + return ret + + +class MsxModel(AbstractModel): + """A multispecies water quality model for use with WNTR EPANET-MSX simulator.""" + + def __init__(self, msx_file_name=None) -> None: + """A full, multi-species water quality model. + + Arguments + --------- + msx_file_name : str, optional + an MSX file to read in, by default None + """ + super().__init__(msx_file_name) + self._references: List[Union[str, Dict[str, str]]] = list() + self._options = MultispeciesOptions() + self._rxn_system = MsxReactionSystem() + self._net_data = MsxNetworkData() + self._wn = None + + for v in HYDRAULIC_VARIABLES: + self._rxn_system.add_variable(HydraulicVariable(**v)) + for k, v in EXPR_FUNCTIONS.items(): + self._rxn_system.add_variable(MathFunction(name=k.lower(), func=v)) + self._rxn_system.add_variable(MathFunction(name=k.capitalize(), func=v)) + self._rxn_system.add_variable(MathFunction(name=k.upper(), func=v)) + + if msx_file_name is not None: + from wntr.epanet.msx.io import MsxFile + + MsxFile.read(msx_file_name, self) + + def __repr__(self) -> str: + ret = "{}(".format(self.__class__.__name__) + if self.name: + ret = ret + "name={}".format(repr(self.name)) + elif self.title: + ret = ret + "title={}".format(repr(self.title)) + elif self._orig_file: + ret = ret + "{}".format(repr(self._orig_file)) + ret = ret + ")" + return ret + + @property + def references(self) -> List[Union[str, Dict[str, str]]]: + """A list of strings or mappings that provide references for this model. + + .. note:: + This property is a list, and should be modified using append/insert/remove. + Members of the list should be json seriealizable (i.e., strings or dicts of strings). + """ + return self._references + + @property + def reaction_system(self) -> MsxReactionSystem: + """The reaction variables defined for this model.""" + return self._rxn_system + + @property + def network_data(self) -> MsxNetworkData: + """The network-specific values added to this model.""" + return self._net_data + + @property + def options(self) -> MultispeciesOptions: + """The MSX model options""" + return self._options + + @property + def species_name_list(self) -> List[str]: + """all defined species names""" + return list(self.reaction_system.species.keys()) + + @property + def constant_name_list(self) -> List[str]: + """all defined coefficient names""" + return list(self.reaction_system.constants.keys()) + + @property + def parameter_name_list(self) -> List[str]: + """all defined coefficient names""" + return list(self.reaction_system.parameters.keys()) + + @property + def term_name_list(self) -> List[str]: + """all defined function (MSX 'terms') names""" + return list(self.reaction_system.terms.keys()) + + @options.setter + def options(self, value): + if isinstance(value, dict): + self._options = MultispeciesOptions.factory(value) + elif not isinstance(value, MultispeciesOptions): + raise TypeError("Expected a MultispeciesOptions object, got {}".format(type(value))) + else: + self._options = value + + def add_species( + self, + name: str, + species_type: SpeciesType, + units: str, + atol: float = None, + rtol: float = None, + note: Any = None, + diffusivity: float = None, + ) -> Species: + """Add a species to the model + + Arguments + --------- + name : str + _description_ + species_type : SpeciesType + _description_ + units : str + _description_ + atol : float, optional + _description_, by default None + rtol : float, optional + _description_, by default None + note : str | dict | ENcomment, optional + Supplementary information regarding this variable, by default None + (see :class:`~wntr.epanet.util.ENcomment` for dict structure). + diffusivity : float, optional + Diffusivity in water for this species. + + Raises + ------ + KeyError + _description_ + + Returns + ------- + Species + _description_ + """ + if name in self._rxn_system: + raise KeyError( + "Variable named {} already exists in model as type {}".format( + name, self._rxn_system._vars.get_groupname(name) + ) + ) + species_type = SpeciesType.get(species_type, allow_none=False) + iq = self.network_data.init_new_species(name) + new = Species( + name=name, + species_type=species_type, + units=units, + atol=atol, + rtol=rtol, + note=note, + _vars=self._rxn_system, + _vals=iq, + diffusivity=diffusivity, + ) + self.reaction_system.add_variable(new) + return new + + def remove_species(self, species): + """Remove a species from the model. + + Removes from both the reaction_system and the network_data. + + Arguments + --------- + species : _type_ + _description_ + """ + name = str(species) + self.network_data.remove_species(name) + # FIXME: validate additional items + self.reaction_system.__delitem__(name) + + def add_constant(self, name: str, value: float, units: str = None, note: Any = None) -> Constant: + """Add a constant coefficient to the model. + + Arguments + --------- + name : str + _description_ + value : float + _description_ + units : str, optional + _description_, by default None + note : str | dict | ENcomment, optional + Supplementary information regarding this variable, by default None + (see :class:`~wntr.epanet.util.ENcomment` for dict structure). + + Raises + ------ + KeyError + _description_ + + Returns + ------- + Constant + _description_ + """ + if name in self._rxn_system: + raise KeyError( + "Variable named {} already exists in model as type {}".format( + name, self._rxn_system._vars.get_groupname(name) + ) + ) + new = Constant(name=name, value=value, units=units, note=note, _vars=self._rxn_system) + self.reaction_system.add_variable(new) + return new + + def remove_constant(self, const): + """Remove a constant coefficient from the model. + + Arguments + --------- + const : _type_ + _description_ + """ + name = str(const) + # FIXME: validate deletion + self.reaction_system.__delitem__(name) + + def add_parameter(self, name: str, global_value: float, units: str = None, note: Any = None) -> Parameter: + """Add a parameterized coefficient to the model. + + Arguments + --------- + name : str + _description_ + global_value : float + _description_ + units : str, optional + _description_, by default None + note : str | dict | ENcomment, optional + Supplementary information regarding this variable, by default None + (see :class:`~wntr.epanet.util.ENcomment` for dict structure). + + Raises + ------ + KeyError + _description_ + + Returns + ------- + Parameter + _description_ + """ + if name in self._rxn_system: + raise KeyError( + "Variable named {} already exists in model as type {}".format( + name, self._rxn_system._vars.get_groupname(name) + ) + ) + pv = self.network_data.init_new_parameter(name) + new = Parameter(name=name, global_value=global_value, units=units, note=note, _vars=self._rxn_system, _vals=pv) + self.reaction_system.add_variable(new) + return new + + def remove_parameter(self, param): + """Remove a parameterized coefficient from the model. + + Arguments + --------- + param : _type_ + _description_ + """ + name = str(param) + self.network_data.remove_parameter(name) + # FIXME: validate additional items + self.reaction_system.__delitem__(name) + + def add_term(self, name: str, expression: str, note: Any = None) -> Term: + """Add a named expression (term) to the model. + + Arguments + --------- + name : str + _description_ + expression : str + _description_ + note : str | dict | ENcomment, optional + Supplementary information regarding this variable, by default None + (see :class:`~wntr.epanet.util.ENcomment` for dict structure). + + Raises + ------ + KeyError + _description_ + + Returns + ------- + Term + _description_ + """ + if name in self._rxn_system: + raise KeyError( + "Variable named {} already exists in model as type {}".format( + name, self._rxn_system._vars.get_groupname(name) + ) + ) + new = Term(name=name, expression=expression, note=note, _vars=self._rxn_system) + self.reaction_system.add_variable(new) + return new + + def remove_term(self, term): + """Remove a named expression (term) from the model. + + Arguments + --------- + term : _type_ + _description_ + """ + name = str(term) + # FIXME: validate deletion + self.reaction_system.__delitem__(name) + + def add_reaction( + self, species_name: str, reaction_type: ReactionType, expression_type: ExpressionType, expression: str, note: Any = None + ) -> AbstractReaction: + """Add a reaction to a species in the model. + + Note that all species need to have both a pipe and tank reaction defined + unless all species are bulk species and + the tank reactions are identical to the pipe reactions. However, it is not + recommended that users take this approach. + + Once added, access the reactions from the species' object. + + Arguments + --------- + species_name : str + _description_ + location_type : LocationType + _description_ + expression_type : ExpressionType + _description_ + expression : str + _description_ + note : str | dict | ENcomment, optional + Supplementary information regarding this reaction, by default None + (see :class:`~wntr.epanet.util.ENcomment` for dict structure). + + Raises + ------ + TypeError + _description_ + + Returns + ------- + MultispeciesReaction + _description_ + """ + species_name = str(species_name) + species = self.reaction_system.species[species_name] + if species.var_type is not VariableType.SPECIES: + raise TypeError("Variable {} is not a Species, is a {}".format(species.name, species.var_type)) + reaction_type = ReactionType.get(reaction_type, allow_none=False) + expression_type = ExpressionType.get(expression_type, allow_none=False) + new = Reaction( + reaction_type=reaction_type, + expression_type=expression_type, + species_name=species_name, + expression=expression, + note=note, + ) + self.reaction_system.add_reaction(new) + return new + + def remove_reaction(self, species_name: str, reaction_type: ReactionType) -> None: + """Remove a reaction at a specified location from a species. + + Parameters + ---------- + species : str + the species name to remove the reaction from + location : LocationType + the location to remove the reaction from + """ + reaction_type = ReactionType.get(reaction_type, allow_none=False) + species_name = str(species_name) + del self.reaction_system.reactions[reaction_type.name.lower()][species_name] + + def to_dict(self) -> dict: + from wntr import __version__ + + return { + "wntr-version": "{}".format(__version__), + "name": self.name, + "title": self.title, + "description": self.description if self.description is None or "\n" not in self.description else self.description.splitlines(), + "references": self.references.copy(), + "reaction_system": self.reaction_system.to_dict(), + "network_data": self.network_data.to_dict(), + "options": self.options.to_dict(), + } + + @classmethod + def from_dict(cls, data) -> 'MsxModel': + from wntr import __version__ + + ver = data.get("wntr-version", None) + if ver != __version__: + logger.warn("Importing from a file created by a different version of wntr, compatibility not guaranteed") + warnings.warn("Importing from a file created by a different version of wntr, compatibility not guaranteed") + new = cls() + new.name = data.get("name", None) + new.title = data.get("title", None) + new.description = data.get("description", None) + if isinstance(new.description, (list, tuple)): + desc = "\n".join(new.description) + new.description = desc + new.references.extend(data.get("references", list())) + + rxn_sys = data.get("reaction_system", dict()) + for var in rxn_sys.get("species", list()): + new.add_species(**var) + for var in rxn_sys.get("constants", list()): + new.add_constant(**var) + for var in rxn_sys.get("parameters", list()): + new.add_parameter(**var) + for var in rxn_sys.get("terms", list()): + new.add_term(**var) + for rxn in rxn_sys.get("pipe_reactions", list()): + rxn["reaction_type"] = "pipe" + new.add_reaction(**rxn) + for rxn in rxn_sys.get("tank_reactions", list()): + rxn["reaction_type"] = "tank" + new.add_reaction(**rxn) + + new._net_data = MsxNetworkData(**data.get("network_data", dict())) + for species in new.reaction_system.species: + if species not in new.network_data.initial_quality: + new.network_data.init_new_species(species) + for param in new.reaction_system.parameters: + if param not in new.network_data.parameter_values: + new.network_data.init_new_parameter(param) + + opts = data.get("options", None) + if opts: + new.options = opts + + return new diff --git a/wntr/quality/options.py b/wntr/msx/options.py similarity index 100% rename from wntr/quality/options.py rename to wntr/msx/options.py diff --git a/wntr/network/model.py b/wntr/network/model.py index 47919dd09..f6c6cb2ae 100644 --- a/wntr/network/model.py +++ b/wntr/network/model.py @@ -336,14 +336,14 @@ def msx(self): def msx(self, msx): if msx is None: self._msx = None - from wntr.quality.base import AbstractQualityModel + from wntr.msx.base import AbstractQualityModel if not isinstance(msx, AbstractQualityModel): raise TypeError('Expected AbstractQualityModel (or derived), got {}'.format(type(msx))) def add_msx_model(self, msx_filename=None): """Add an msx model from a MSX input file (.msx extension)""" - from wntr.quality.multispecies import MultispeciesQualityModel - self._msx = MultispeciesQualityModel(msx_file_name=msx_filename) + from wntr.msx.model import MsxModel + self._msx = MsxModel(msx_file_name=msx_filename) def remove_msx_model(self): """Remove an msx model from the network""" diff --git a/wntr/quality/MSXPY_toolkit.py b/wntr/quality/MSXPY_toolkit.py deleted file mode 100644 index d7a9c374b..000000000 --- a/wntr/quality/MSXPY_toolkit.py +++ /dev/null @@ -1,876 +0,0 @@ -# # -*- coding: utf-8 -*- -# """ -# Created on Fri Jun 18 10:52:45 2021 - -# @author: Matthew -# """ - -# import numpy as np -# import epanet_toolkit as epa -# import msx_toolkit as msx -# import pandas as pd -# import os -# from sklearn.cluster import KMeans -# from sklearn.metrics import silhouette_score -# import wntr -# from scipy.linalg import cholesky -# from SALib.analyze import morris as morris_a - -# def MSXRunQual(species='all', nodes='all', links='all',by_species='yes',bin_read='no',t_start=-1): -# #Function to run a MSX model and extract timeseries of specified species, links, and nodes -# #Inputs are a list of the desired species, nodes, links, and whether the results -# #should be organized by species, or by model element (links and nodes) -# #if no nodes or links are desired, then an empty list [] should be used -# #The t_start option is a number in days which says when the results from the -# #simulation should start to be recorded. This is helpful if a model needs to run -# #to reach hydraulic equilbriums and the first X number of days of the simulation -# #are not needed for the results - -# #The bin_read option allows for the model to be run all at once and -# #then the binary file is read. The reporting timesteps are based on the -# #reporting timestep from the inp file. If not, the results -# #are read at each timestep from the msx model run. - -# if bin_read=='no': - -# #Extract the indicies and names for the species of interest -# if (species=='all'): -# species_names=[] -# #Get the number of species 3 for species -# species_num=msx.MSXgetcount(3) -# #Get a list for the species id's -# for i in range(species_num): -# species_names.append(msx.MSXgetID(3,i+1)) -# #get an array for the species indicies -# species_ind=np.linspace(1,species_num,species_num) - -# #If there is a user supplied list of species to be extracted -# else: -# #Make the user-input list the variable species_names -# species_names=species -# #Extract the indicies for the species being specified -# species_ind=[] -# for i in range(len(species_names)): -# species_ind.append(msx.MSXgetindex(3,species_names[i])) - -# #Extract the node indicies for the specified nodes -# if (nodes=='all'): -# node_names=[] -# #Get the number of nodes- 0 for nodes -# node_num=epa.ENgetcount(0) -# #Get a list for the node id's -# for i in range(node_num): -# node_names.append(epa.ENgetnodeid(i+1)) -# #Get an array for the node indicies -# node_ind=np.linspace(1,node_num,node_num) - -# #If there are actual nodes specified to be extracted -# else: -# #Make the user-input list the variable node_names -# node_names=nodes -# #Extract the indicies for the nodes being specified -# node_ind=[] -# for i in range(len(node_names)): -# node_ind.append(epa.ENgetnodeindex(node_names[i])) - -# #Do the same but for links - -# #Extract the link indicies for the specified nodes -# if (links=='all'): -# link_names=[] -# #Get the number of links- 2 for links -# link_num=epa.ENgetcount(2) -# #Get a list for the link id's -# for i in range(link_num): -# link_names.append(epa.ENgetlinkid(i+1)) -# #Get an array for the node indicies -# link_ind=np.linspace(1,link_num,link_num) - -# #If there are actual nodes specified to be extracted -# else: -# #Make the user-input list the variable node_names -# link_names=links -# #Extract the indicies for the nodes being specified -# link_ind=[] -# for i in range(len(link_names)): -# link_ind.append(epa.ENgetlinkindex(link_names[i])) - - - -# #Create array to extract the time of the simulation steps -# T=[] - -# #Initialize MSX for first timestep -# msx.MSXinit(0) - -# #Initialize time left -# t_left=1 - -# #Create overall results dictionary -# results={} - -# #If organized by species -# if (by_species=='yes'): -# #Create a new dictionary for each species and then within each species -# #make a node and link list -# for i in range(len(species_names)): -# results[species_names[i]]={} -# results[species_names[i]]['node']=[] -# results[species_names[i]]['link']=[] - -# #If organized by element -# if (by_species=='no'): -# #Create node key and another dictionary -# results['node']={} -# #Create link key and another dictionary -# results['link']={} - -# #Within each dictionary make a list to be populated later during model run -# #nodes -# for i in range(len(node_names)): -# results['node'][node_names[i]]=[] -# #links -# for i in range(len(link_names)): -# results['link'][link_names[i]]=[] - - -# #Change the input of t_start from days to seconds -# t_start=t_start*24*60*60 - - -# #Create loop to run model -# while (t_left>0): -# #Solve the quality for that timestep -# [t,t_left]=msx.MSXstep() - -# #If the results should be extracted based on t_start aka the simulation -# #time has passed the time when we care about the results -# if t>t_start: - -# #Append time for that step to the overall time list -# T.append(t) - -# #If the results are to be extracted by model element -# if (by_species=='no'): -# #Extract the results from each node into a different list -# for j in range(len(node_names)): -# #Create a row for the overall results list -# Q_row=[] -# #Extract the results for each desired species at that node -# for i in range(len(species_names)): -# #0 for node #node_ind and the species_ind -# Q_row.append(msx.MSXgetqual(0,int(node_ind[j]),int(species_ind[i]))) -# results['node'][node_names[j]].append(Q_row) - -# #Extract the results from each link into a different list -# for j in range(len(link_names)): -# #Create a row for the overall results list -# Q_row=[] -# #Extract the results for each desired species at that node -# for i in range(len(species_names)): -# #0 for link #node_ind and the species_ind -# Q_row.append(msx.MSXgetqual(1,int(link_ind[j]),int(species_ind[i]))) -# results['link'][link_names[j]].append(Q_row) - -# #If the results are to be extracted by species -# if (by_species=='yes'): -# for i in range(len(species_names)): -# #First extract the nodes and then the links -# #Create empty lists for each row to be added -# Q_row_node=[] -# Q_row_link=[] - -# #Extract results by node -# for j in range(len(node_names)): -# Q_row_node.append(msx.MSXgetqual(0,int(node_ind[j]),int(species_ind[i]))) -# results[species_names[i]]['node'].append(Q_row_node) - -# #Extract results by link -# for j in range(len(link_names)): -# Q_row_link.append(msx.MSXgetqual(1,int(link_ind[j]),int(species_ind[i]))) -# results[species_names[i]]['link'].append(Q_row_link) - - - -# #After the simulation is complete go through the results one more time and -# #convert the lists into dataframes -# if (by_species=='no'): -# #Nodes -# for i in range(len(node_names)): -# results['node'][node_names[i]]=pd.DataFrame(results['node'][node_names[i]],index=T,columns=species_names) - -# #Links -# for i in range(len(link_names)): -# results['link'][link_names[i]]=pd.DataFrame(results['link'][link_names[i]],index=T,columns=species_names) - -# if (by_species=='yes'): -# #Nodes -# for i in range(len(species_names)): -# results[species_names[i]]['node']=pd.DataFrame(results[species_names[i]]['node'],index=T,columns=node_names) - -# #links -# for i in range(len(species_names)): -# results[species_names[i]]['link']=pd.DataFrame(results[species_names[i]]['link'],index=T,columns=link_names) - -# if bin_read=='yes': - -# #Solve the quality of the model -# msx.MSXsolveQ() - -# #Save quality results to binary file -# #Add the process id to the binary file name so that multiple processes are -# #not trying to read from the same file if it is run in parallel -# filename='results_temp'+str(os.getpid())+'.bin' -# msx.MSXsaveoutfile(filename) - -# #def MSXBinReader(filename, epanetinpfile): - -# #This code is from Jon Buckhardt that I lightly edited -# duration=epa.ENgettimeparam(0) -# with open(filename, 'rb') as fin: -# ftype = '=f4' -# idlen = 32 -# prolog = np.fromfile(fin, dtype = np.int32, count = 6) -# magic1 = prolog[0] -# version = prolog[1] -# nnodes = prolog[2] -# nlinks = prolog[3] -# nspecies = prolog[4] -# reportstep = prolog[5] -# species_list = [] -# node_list = GetNodeNameList() -# link_list = GetLinkNameList() - -# for i in range(nspecies): -# species_len = int(np.fromfile(fin, dtype = np.int32, count = 1)) -# species_name = ''.join(chr(f) for f in np.fromfile(fin, dtype = np.uint8, count = species_len) if f!=0) -# species_list.append(species_name) - - -# species_mass = [] -# for i in range(nspecies): -# species_mass.append(''.join(chr(f) for f in np.fromfile(fin, dtype = np.uint8, count = 16) if f != 0)) -# timerange = range(0, duration+1, reportstep) - -# tr = len(timerange) - -# row1 = ['node']*nnodes*len(species_list)+['link']*nlinks*len(species_list) -# row2 = [] -# for i in [nnodes,nlinks]: -# for j in species_list: -# row2.append([j]*i) -# row2 = [y for x in row2 for y in x] -# row3 = [node_list for i in species_list] + [link_list for i in species_list] -# row3 = [y for x in row3 for y in x] - -# tuples = list(zip(row1, row2, row3)) -# index = pd.MultiIndex.from_tuples(tuples, names = ['type','species','name']) - -# try: -# data = np.fromfile(fin, dtype = np.dtype(ftype), count = tr*(len(species_list*(nnodes + nlinks)))) -# data = np.reshape(data, (tr, len(species_list*(nnodes + nlinks)))) -# except Exception as e: -# print(e) -# print ("oops") -# postlog = np.fromfile(fin, dtype = np.int32, count = 4) -# offset = postlog[0] -# numreport = postlog[1] -# errorcode = postlog[2] -# magicnew = postlog[3] -# if magic1 == magicnew: -# #print("Magic# Match") -# df_fin = pd.DataFrame(data.transpose(), index = index, columns = timerange) -# df_fin = df_fin.transpose() -# else: -# print("Magic#s do not match!") -# #return df_fin - -# #df is a multilevel index dataframe of all of the results - -# #Now I am going to repackage the results so that it fits with my struct structure -# #Of how I was doing the results before. This may take a bit of time but I want -# #things how I want them:) - -# #Create the dictionary -# results={} - -# #Go through all the nodes and put data from the dataframe into the correct place -# #in the results dictionary - -# if nodes=='all': -# nodes=GetNodeNameList() - -# if links=='all': -# links=GetLinkNameList() - -# if species=='all': -# species=GetSpeciesNameList() - - - -# if by_species=='no': - -# #Create a dictionary within the dictionary for nodes and links -# results['node']={} - -# results['link']={} - -# for i in range(len(nodes)): -# #Put the dataframe in the dictionary at the correct location -# results['node'][nodes[i]]=df_fin.loc[:,('node',species,nodes[i])] -# #Fix the index so it is no longer a multiindex -# results['node'][nodes[i]].columns=results['node'][nodes[i]].columns.droplevel(['type','name']) - -# for i in range(len(links)): -# #Put the dataframe in the dictionary at the correct location -# results['link'][links[i]]=df_fin.loc[:,('link',species,links[i])] -# #Fix the index so it is no longer a multiindex -# results['link'][links[i]].columns=results['link'][links[i]].columns.droplevel(['type','name']) - -# if by_species=='yes': - -# for i in range(len(species)): -# #Create a dictionary for that species -# results[species[i]]={} - -# #Put the concentrations of the nodes of that species in the right place -# results[species[i]]['node']=df_fin.loc[:,('node',species[i],nodes)] -# #Fix the index so it is no longer a multiindex -# results[species[i]]['node'].columns=results[species[i]]['node'].columns.droplevel(['type','species']) - -# #Put the concentrations of the links of that species in the right place -# results[species[i]]['link']=df_fin.loc[:,('link',species[i],links)] -# #Fix the index so it is no longer a multiindex -# results[species[i]]['link'].columns=results[species[i]]['link'].columns.droplevel(['type','species']) - -# #Remove the -# try: -# os.remove(filename) -# except: -# print('Error removing ' + filename) - -# return results - -# #Get a list of all the node names -# def GetNodeNameList(): -# node_names=[] -# #Get the number of nodes- 0 for nodes -# node_num=epa.ENgetcount(0) -# #Get a list for the node id's -# for i in range(node_num): -# node_names.append(epa.ENgetnodeid(i+1)) -# #Get an array for the node indicies -# #node_ind=np.linspace(1,node_num,node_num) -# return node_names - -# #Get a list of all link names -# def GetLinkNameList(): -# link_names=[] -# #Get the number of nodes- 2 for links -# link_num=epa.ENgetcount(2) -# #Get a list for the node id's -# for i in range(link_num): -# link_names.append(epa.ENgetlinkid(i+1)) -# #Get an array for the node indicies -# #node_ind=np.linspace(1,node_num,node_num) -# return link_names - - - -# #Get a list of all the species names -# def GetSpeciesNameList(): -# species_names=[] -# #Get the number of species 3 for species -# species_num=msx.MSXgetcount(3) -# #Get a list for the species id's -# for i in range(species_num): -# species_names.append(msx.MSXgetID(3,i+1)) -# return species_names - -# def GetConstantNameList(): -# #Get the name for each constant -# constant_names=[] -# #Get the number of constants -# constants_num=msx.MSXgetcount(6) -# for i in range(constants_num): -# #Get the name of each specific constant, 6 for constant -# constant_names.append(msx.MSXgetID(6,i+1)) -# return constant_names - -# def TimeToCriticalValue(results,element_type='node',element='1',species='cNH2CL',crit_val=1.46): -# #As currently written, assumes results are NOT by species and that the -# #critical value is decreasing, finding the value on the way down - -# element_results=results[element_type][element] -# chlor=element_results.loc[:,species] -# chlor=chlor[chlor>crit_val] -# t_crit=np.max(chlor.index) -# return t_crit - -# def TimeToCriticalValueSeries(chlor,crit_val=1.46): -# #Same as function above but takes a series as an input instead of the overall results dictionary - -# #As currently written, assumes results are NOT by species and that the -# #critical value is decreasing, finding the value on the way down - -# chlor=chlor[chlor>crit_val] -# t_crit=np.max(chlor.index) -# return t_crit - -# def GetConstants(con_get): -# #Returns a numpy array with the constants of a model - -# #Get the indicies of the constants of interest -# inds=[] -# for i in range(len(con_get)): -# inds.append(msx.MSXgetindex(6,con_get[i])) - -# #Make an array holding the initial value for each constant -# constants=np.zeros((len(inds),1)) -# #Populate that array with the initial value of each constant -# #IMPORTANT: Requires that the input vector is the indicies starting from 1 -# #not starting from 0 which is done in the previous for loop -# for i in range(len(inds)): -# constants[i] = msx.MSXgetconstant(inds[i]) - -# return constants - -# def GetInitialConcentration(node,species): -# #Inputs: Nodes of interest and species of interest -# #The node input is the ID of the node not the index number -# #Returns a numpy array with the initial concentration of the specified -# #Species at the specified node - - -# #Get the index of the specified node -# node_ind=epa.ENgetnodeindex(node) - - -# #Get the indicies of the species of interest -# inds=[] -# #Get the indicies of the species of interest -# for i in range(len(species)): -# inds.append(msx.MSXgetindex(3,species[i])) - -# #Make an array holding the initial value for each species -# initial_con=np.zeros((len(inds),1)) - -# #Populate that array with the initial value of each initial species at the -# #specified node, input to the function -# for i in range(len(inds)): -# initial_con[i] = msx.MSXgetinitqual(0,node_ind,inds[i]) - -# return initial_con - - -# def SetConstants(con_get,given_constants): -# #Set constants to specific values -# #con_get is a list with the IDs of the constants to be varied -# #given_constants is a numpy array of the values of the constants to be changed -# #the order of IDs in con_get must be the same as the order of the values in -# #given_constants - -# #Get the indicies of the constants of interest -# inds=[] -# for i in range(len(con_get)): -# inds.append(msx.MSXgetindex(6,con_get[i])) - -# #Populate that array with the initial value of each constant -# for i in range(len(inds)): -# msx.MSXsetconstant(inds[i],given_constants[i]) - -# def SetInitialConcentration(node,species,init_val): -# #Inputs: Nodes of interest and species of interest, and vector of species values -# #The node input is the ID of the node not the index number - -# if (len(species)!=len(init_val)): -# raise Exception('The length of species IDs list and species value array are not equal') - -# #Get the index of the specified node -# node_ind=epa.ENgetnodeindex(node) - -# #Get the indicies of the species of interest -# inds=[] -# for i in range(len(species)): -# inds.append(msx.MSXgetindex(3,species[i])) - -# #Set the species of interest to the specified values -# for i in range(len(inds)): -# msx.MSXsetinitqual(0,node_ind,inds[i],init_val[i]) - -# def SetGlobalInitialConcentration(species,init_val): - - -# #Get the number of nodes in the model -# node_num=epa.ENgetcount(0) - -# #Get the number of links- 2 for links -# link_num=epa.ENgetcount(2) - -# #Get the indicies of the species of interest -# inds=[] -# for i in range(len(species)): -# inds.append(msx.MSXgetindex(3,species[i])) - -# #Loop through each node -# #Set the species of interest to the specified values -# #For each species -# for i in range(len(inds)): -# #For each node -# for j in range(node_num): -# #j+1 because epanet indicies start from 1 not 0 like python -# msx.MSXsetinitqual(0,j+1,inds[i],init_val[i]) - -# #Loop through each species -# #Set the species of interest to the specified values -# #For each species -# for i in range(len(inds)): -# #For each link -# for j in range(link_num): -# #j+1 because epanet indicies start from 1 not 0 like python -# msx.MSXsetinitqual(1,j+1,inds[i],init_val[i]) - - - -# def GetAllNodeDemands(): -# #Get the base demands for each node -# #Get the number of nodes -# node_num=epa.ENgetcount(0) -# #Create a list to put the values -# node_demands=[] -# #Extract the demands from the model -# for i in range(node_num): -# node_demands.append(epa.ENgetnodevalue(i+1, 1)) -# #Turn the list into an array -# node_demands=np.array(node_demands) -# return node_demands - -# def SetAllNodeDemands(given_demands): -# #Get the number of nodes -# node_num=epa.ENgetcount(0) -# #Raise an error if the number of demands supplied does not match the -# #number of nodes in the model -# if (node_num!=len(given_demands)): -# raise Exception('The number of demands provided dose not match the total number of nodes in the model') -# #Set the demands in the model -# for i in range(len(given_demands)): -# epa.ENsetnodevalue(i+1, 1, given_demands[i]) - -# def SetNodeDemands(nodes,given_demands): -# #Set baseline demands in specific nodes -# for i in range(len(nodes)): -# epa.ENsetnodevalue(epa.ENgetnodeindex(nodes[i]), 1, given_demands[i]) - -# def MonochloramineSetTemp(Temp,unit,temp_cons): -# #This function changes the temperature-dependant model constants in the -# #Monochloramine Decay model (found in Wahman 2018, developed by others) - -# if unit=='F': -# #Convert to Kelvin -# Temp_k=(Temp-32)*(5/9)+273.15 -# if unit=='C': -# #Convert to Kelvin -# Temp_k=Temp+273.15 -# if unit=='K': -# #It already is in Kelvin but change the variable name -# Temp_k=Temp - -# #Set constants based on the temperature - -# #Create a list of the acceptable constants to be varied -# temp_cons_acceptable=['k1','k2','k3','AC1','AC2','AC3','KNH4','KHOCL','KH2CO3','KHCO3','KW'] - -# #Check to make sure the constants supplied are in that list -# for k in range(len(temp_cons)): -# if temp_cons[k] not in temp_cons_acceptable: -# raise Exception('One of the supplied constant names does not exist in the model') - -# #Create a list which is the same length as temp_cons -# temp_con_val_list=[None]*len(temp_cons) - -# #Loop through each value of temp_cons and populate temp_con_val_list -# for i in range(len(temp_cons)): - -# #Formule for each temperature-dependant constant are found in Wahman 2018 - -# if temp_cons[i]=='k1': -# temp_con_val_list[i]=6.6*10**8*np.exp(-1510/Temp_k) -# if temp_cons[i]=='k2': -# temp_con_val_list[i]=1.38*10**8*np.exp(-8800/Temp_k) -# if temp_cons[i]=='k3': -# temp_con_val_list[i]=3.0*10**5*np.exp(-2010/Temp_k) -# if temp_cons[i]=='AC1': -# temp_con_val_list[i]=1.05*10**7*np.exp(-2169/Temp_k) -# if temp_cons[i]=='AC2': -# temp_con_val_list[i]=8.19*10**6*np.exp(-4026/Temp_k) -# if temp_cons[i]=='AC3': -# temp_con_val_list[i]=4.2*10**31*np.exp(-22144/Temp_k) -# if temp_cons[i]=='KNH4': -# temp_con_val_list[i]=10**-(1.03*10**-4*Temp_k**2-9.21*10**-2*Temp_k+27.6) -# if temp_cons[i]=='KHOCL': -# temp_con_val_list[i]=10**-(1.18*10**-4*Temp_k**2-7.86*10**-2*Temp_k+20.5) -# if temp_cons[i]=='KH2CO3': -# temp_con_val_list[i]=10**-(1.48*10**-4*Temp_k**2-9.39*10**-2*Temp_k+21.2) -# if temp_cons[i]=='KHCO3': -# temp_con_val_list[i]=10**-(1.19*10**-4*Temp_k**2-7.99*10**-2*Temp_k+23.6) -# if temp_cons[i]=='KW': -# temp_con_val_list[i]=10**-(1.5*10**-4*Temp_k**2-1.23*10**-1*Temp_k+37.3) - -# #Take the individual values and put them in an array -# temp_con_vals=np.array(temp_con_val_list) - -# #Set the constants in the model -# SetConstants(temp_cons,temp_con_vals) - -# def MonochloramineGetTempCon(Temp,unit,con): -# #This function changes the temperature-dependant model constants in the -# #Monochloramine Decay model (found in Wahman 2018, developed by others) - -# #Input a vector of temperatures and get a vector of the desired constant - -# if unit=='F': -# #Convert to Kelvin -# Temp_k=(Temp-32)*(5/9)+273.15 -# if unit=='C': -# #Convert to Kelvin -# Temp_k=Temp+273.15 -# if unit=='K': -# #It already is in Kelvin but change the variable name -# Temp_k=Temp - -# #Set constants based on the temperature - -# #Formule for each temperature-dependant constant are found in Wahman 2018 -# if con=='k1': -# out=6.6*10**8*np.exp(-1510/Temp_k) -# if con=='k2': -# out=1.38*10**8*np.exp(-8800/Temp_k) -# if con=='k3': -# out=3.0*10**5*np.exp(-2010/Temp_k) -# if con=='AC1': -# out=1.05*10**7*np.exp(-2169/Temp_k) -# if con=='AC2': -# out=8.19*10**6*np.exp(-4026/Temp_k) -# if con=='AC3': -# out=4.2*10**31*np.exp(-22144/Temp_k) -# if con=='KNH4': -# out=10**-(1.03*10**-4*Temp_k**2-9.21*10**-2*Temp_k+27.6) -# if con=='KHOCL': -# out=10**-(1.18*10**-4*Temp_k**2-7.86*10**-2*Temp_k+20.5) -# if con=='KH2CO3': -# out=10**-(1.48*10**-4*Temp_k**2-9.39*10**-2*Temp_k+21.2) -# if con=='KHCO3': -# out=10**-(1.19*10**-4*Temp_k**2-7.99*10**-2*Temp_k+23.6) -# if con=='KW': -# out=10**-(1.5*10**-4*Temp_k**2-1.23*10**-1*Temp_k+37.3) - -# return out - -# def GenerateNormal(problem,n_sims): -# #Takes a problem (defined by the SALib package) and generates parameters for -# #model runs based on normal distributions of each parameter where the -# #mean is the mean/median of the upper/lower bounds specified and the standard -# #deviation is set so that 2 standard deviations from the mean is the upper/lower bound -# #of the value for the specified parameter - - -# #Create an empty array of the size needed -# norm_input=np.zeros((n_sims,problem['num_vars'])) -# rng=np.random.default_rng() - -# for i in range(problem['num_vars']): - -# #Mean is the middle of the upper and lower bounds specified by the problem -# mean=problem['bounds'][i].mean() -# #The standard deviation is set so that 2 standard deviations away from the -# #mean is the upper and lower bounds of the range specified by the problem -# sigma=(problem['bounds'][i].mean()-problem['bounds'][i][0])/2 -# norm_input[:,i]=rng.normal(mean,sigma,n_sims) - -# return norm_input - -# def ScaleMatrixAll(X): -# #Scales a matrix using the min/max over all of the columns instead of by each column individually -# return (X - X.min()) / (X.max() - X.min()) - -# def KMeansBestNum(scaled_2d,clust_num_test=10): -# #Find best number of kmeans clusters -# sil=[None]*(clust_num_test-1) -# random_state=170 -# for i in range(1,clust_num_test): -# n=i+1 -# #do kmeans clustering -# y_pred = KMeans(n_clusters=n, random_state=random_state).fit_predict(scaled_2d) -# #Calculate the silhouette scores -# sil[i-1]=silhouette_score(scaled_2d,y_pred) -# #Find the index where the sil score is the highest -# z=np.where(sil==np.max(sil))[0] -# num_clust_best=z[0]+2 -# #Do the clustering one more time with that number of clusters -# y_pred = KMeans(n_clusters=num_clust_best, random_state=random_state).fit_predict(scaled_2d) -# return y_pred - -# def Network2DPlot(network,color_var,size_var,title,nodes,min_scale=30,max_scale=80,show_inds='all'): - -# #Scale Information -# mult=max_scale-min_scale -# #doing the plotting -# if show_inds=='all': -# show_inds=list(np.arange(0,len(nodes))) -# node_sizes=(ScaleMatrixAll(size_var[show_inds])*mult)+min_scale -# node_sizes=node_sizes.astype(float) -# wntr.graphics.plot_network(network, pd.Series(color_var,index=nodes)[show_inds], node_size=node_sizes,title=title) - - -# def GenerateCorrDemands(group,n,n_samples,mean_group,corr_m): - -# #Assuming the same standard deviation for all nodes -# std_all=np.ones((n_samples,1))*.1 - -# #The correlation among nodes becomes: -# corr_node=np.ones((n_samples,n_samples)) - -# #Create correlation matrix for each node -# for i in range(n_samples): -# for j in range(n_samples): -# if i!=j: -# corr_node[i,j]=corr_m[group[i],group[j]] - -# #Create array for the means to add to the results -# group_arr=np.array(group) -# mean_all=np.ones((n_samples,1)) -# for i in range(np.max(np.unique(group))+1): -# mean_all[np.where(group_arr==i)[0]]=mean_group[i] - - -# signal=[] -# for i in range(len(std_all)): -# signal.append(np.random.default_rng().normal(0,1,n)) - -# # signal=np.random.default_rng().normal(0,1,(n,2)) -# # signal01=np.random.default_rng().normal(0,1,n) -# # signal02=np.random.default_rng().normal(0,1,n) - - -# std_m = np.identity(len(std_all))*std_all - -# # calc desired covariance (vc matrix) -# cov_m = np.dot(std_m, np.dot(corr_node, std_m)) -# cky = cholesky(cov_m, lower=True) - -# corr_data = np.dot(cky,signal) -# corr_data=corr_data+mean_all - -# #Transpose output so each row is each simulation and each column is a node -# corr_data=corr_data.T -# return corr_data - -# def MorrisWallEvaluate(model_pickle,species): - -# results_model=model_pickle['results'] -# nodes=model_pickle['nodes'] -# links=model_pickle['links'] -# problem=model_pickle['problem'] -# param_values_model=model_pickle['param_values'] -# inp_file=model_pickle['inp_file'] - - - -# #Extract the number of timesteps for which the model was computed -# timesteps=len(results_model[0]['node'][nodes[0]].index) -# timesteps_index=results_model[0]['node'][nodes[0]].index - -# #Create a dictionary to store the mu_star and sigma results for the model -# morris_results={} -# morris_results['mu_star']={} -# morris_results['sigma']={} - -# morris_results['mu_star']['node']={} -# morris_results['mu_star']['link']={} - -# morris_results['sigma']['node']={} -# morris_results['sigma']['link']={} - - - -# age_results={} -# age_mean={} -# age_mean['node']=pd.DataFrame() -# age_mean['link']=pd.DataFrame() - -# for l in range(len(nodes)): -# print('Evaluating Node ' + str(l+1) + ' of ' +str(len(nodes))) -# #Compute the morris values for each parameter for each timestep of the model -# #Create an array to store the mu_star values at each timestep -# mu_star_timestep=np.zeros((timesteps,problem['num_vars'])) -# sigma_timestep=np.zeros((timesteps,problem['num_vars'])) - -# #Extract the model output results for that specific timestep -# con_out=np.zeros((len(results_model),1)) -# for j in range(timesteps): -# for i in range(len(results_model)): -# con_out[i]=results_model[i]['node'][nodes[l]].loc[timesteps_index[j],species] - -# #Compute morris results -# a=morris_a.analyze(problem,param_values_model,con_out) - -# mu_star_timestep[j,:]=a['mu_star'] -# sigma_timestep[j,:]=a['sigma'] - -# #Convert mu_star_timestep into a dataframe -# mu_star_df=pd.DataFrame(mu_star_timestep,index=timesteps_index,columns=problem['names']) -# sigma_df=pd.DataFrame(sigma_timestep,index=timesteps_index,columns=problem['names']) - -# morris_results['mu_star']['node'][nodes[l]]=mu_star_df -# morris_results['sigma']['node'][nodes[l]]=sigma_df - -# #Loop through all of the simulation results and get the average -# #water age for each timestep and each node - -# #Create a dataframe to put the results into -# age_results[nodes[l]]=pd.DataFrame() -# for i in range(len(results_model)): -# age_results[nodes[l]]['S'+str(i+1)]=results_model[i]['node'][nodes[l]]['AGE'] - -# age_mean['node'][nodes[l]]=age_results[nodes[l]].mean(axis=1) - -# for l in range(len(links)): -# print('Evaluating Link ' + str(l+1) + ' of ' + str(len(links))) -# #Compute the morris values for each parameter for each timestep of the model -# #Create an array to store the mu_star values at each timestep -# mu_star_timestep=np.zeros((timesteps,problem['num_vars'])) -# sigma_timestep=np.zeros((timesteps,problem['num_vars'])) - -# #Extract the model output results for that specific timestep -# con_out=np.zeros((len(results_model),1)) -# for j in range(timesteps): -# for i in range(len(results_model)): -# con_out[i]=results_model[i]['link'][links[l]].loc[timesteps_index[j],species] - -# #Compute morris results -# a=morris_a.analyze(problem,param_values_model,con_out) - -# mu_star_timestep[j,:]=a['mu_star'] -# sigma_timestep[j,:]=a['sigma'] - -# #Convert mu_star_timestep into a dataframe -# mu_star_df=pd.DataFrame(mu_star_timestep,index=timesteps_index,columns=problem['names']) -# sigma_df=pd.DataFrame(sigma_timestep,index=timesteps_index,columns=problem['names']) - -# morris_results['mu_star']['link'][links[l]]=mu_star_df -# morris_results['sigma']['link'][links[l]]=sigma_df - -# #Loop through all of the simulation results and get the average -# #water age for each timestep and each node - -# #Create a dataframe to put the results into -# age_results[links[l]]=pd.DataFrame() -# for i in range(len(results_model)): -# age_results[links[l]]['S'+str(i+1)]=results_model[i]['link'][links[l]]['AGE'] - -# age_mean['link'][links[l]]=age_results[links[l]].mean(axis=1) - -# return morris_results,age_mean - - - \ No newline at end of file diff --git a/wntr/quality/multispecies.py b/wntr/quality/multispecies.py deleted file mode 100644 index d96897b08..000000000 --- a/wntr/quality/multispecies.py +++ /dev/null @@ -1,1452 +0,0 @@ -# -*- coding: utf-8 -*- - -"""Water quality model implementations. -""" - - -from abc import abstractproperty -import logging - -from typing import ( - Any, - Callable, - Dict, - List, - Tuple, - Union, -) -import warnings - - -from wntr.epanet.util import ENcomment -from wntr.network.elements import Source -from wntr.network.model import PatternRegistry, SourceRegistry, WaterNetworkModel -from wntr.utils.disjoint_mapping import DisjointMapping, KeyExistsError - -from .base import ( - WaterQualityReaction, - WaterQualityReactionSystem, - WaterQualityVariable, - EXPR_TRANSFORMS, - HYDRAULIC_VARIABLES, - EXPR_FUNCTIONS, - DynamicsType, - ReactionType, - QualityVarType, - SpeciesType, - AnnotatedFloat, -) -from .options import MultispeciesOptions - -has_sympy = False -try: - from sympy import Float, Symbol, init_printing, symbols - from sympy.parsing import parse_expr - from sympy.parsing.sympy_parser import convert_xor, standard_transformations - - has_sympy = True -except ImportError: - sympy = None - logging.critical("This python installation does not have SymPy installed. " "Certain functionality will be disabled.") - standard_transformations = (None,) - convert_xor = None - has_sympy = False - - -logger = logging.getLogger(__name__) - -__all__ = [ - "Species", - "Constant", - "Parameter", - "Term", - "ReservedName", - "HydraulicVariable", - "MathFunction", - "Reaction", - "MultispeciesReactionSystem", - "InitialQuality", - "ParameterValues", - "NetworkSpecificData", - "MultispeciesQualityModel", -] - - -class Species(WaterQualityVariable): - """A biological or chemical species that impacts water quality. - - Attributes - ---------- - name : str - The name of the species - species_type : SpeciesType | str - The type of species, either "bulk" or "wall" - units : str - The units of mass used in expressions of concentration - diffusivity : float - The bulk diffusivity in water for bulk species - """ - - def __init__( - self, - name: str, - species_type: Union[SpeciesType, str], - units: str, - atol: float = None, - rtol: float = None, - *, - note=None, - diffusivity: float = None, - _vars=None, - _vals=None, - ) -> None: - """A biological or chemical species. - - Parameters - ---------- - name : str - The species name - species_type : SpeciesType | str - The species type - units : str - The units of mass for this species, see :attr:`units` property. - atol : float, optional - The absolute tolerance when solving this species' equations, by default None [1]_ - rtol : float, optional - The relative tolerance when solving this species' equations, by default None [1]_ - - Keyword Arguments - ----------------- - note : str | dict | ENcomment, optional - Supplementary information regarding this variable, by default None - (see :class:`~wntr.epanet.util.ENcomment` for dict structure) - diffusivity : float, optional - Diffusivity of the species in water, by default None - pipe_reaction : dict | MultispeciesReaction, optional - Reaction dynamics of the species in pipes, by default None - tank_reaction : dict | MultispeciesReaction, optional - Reaction dynamics of the species in tanks, by default None - _vars : VariableRegistry, optional - the variables registry object of the model this variable was added to, by default None - _vals : _type_, optional - _description_, by default None - - Raises - ------ - KeyExistsError - if the name has already been used - TypeError - if mandatory arguments are passed as None; if a tank reaction is provided for a - wall species; if an invalid type is passed for a pipe or tank reaction - - - .. [1] - The `atol` and `rtol` arguments must both be None, or both be a float greater than 0. - """ - super().__init__(name, note=note) - if _vars is not None and name in _vars: - raise KeyExistsError("This variable name is already taken") - species_type = SpeciesType.get(species_type) - if species_type is None: - raise TypeError("species_type cannot be None") - self._species_type = species_type - self._tolerances = None - self.set_tolerances(atol, rtol) - self.units: str = units - """The units of mass for this species. - For bulk species, concentration is this unit divided by liters, for wall species, concentration is this unit - divided by the model's area-unit (see options). - """ - self.diffusivity: float = diffusivity - """The diffusivity of this species in water, if being used, by default None""" - if _vars is not None and isinstance(_vars, MultispeciesReactionSystem): - self._vars = _vars - else: - self._vars = None - if _vals is not None and isinstance(_vals, InitialQuality): - self._vals = _vals - else: - self._vals = None - - def set_tolerances(self, atol: float, rtol: float): - """Set the absolute and relative tolerance for the solvers. - - The user must set both values, or neither value (None). Values must be - positive. - - Arguments - --------- - atol : float - The absolute tolerance to use - rtol : float - The relative tolerance to use - - Raises - ------ - TypeError - if only one of `atol` or `rtol` is a float - ValueError - if either value is less-than-or-equal-to zero - """ - if (self.atol is None) ^ (self.rtol is None): - raise TypeError("atol and rtol must both be float or both be None") - if self.atol is None: - self._tolerances = None - elif atol <= 0 or rtol <= 0: - raise ValueError("atol and rtol must both be positive, got atol={}, rtol={}".format(atol, rtol)) - else: - self._tolerances = (atol, rtol) - - def get_tolerances(self) -> Union[Tuple[float, float], None]: - """Get the custom solver tolerances for this species. - - Returns - ------- - Union[Tuple[float, float], None] - absolute and relative tolerances, respectively, if they are set - """ - return self._tolerances - - def clear_tolerances(self): - """Set both tolerances to None, reverting to the global options value.""" - self._tolerances = None - - @property - def atol(self) -> float: - """The absolute tolerance. Must be set using :meth:`set_tolerances`""" - if self._tolerances is not None: - return self._tolerances[0] - return None - - @property - def rtol(self) -> float: - """The relative tolerance. Must be set using :meth:`set_tolerances`""" - if self._tolerances is not None: - return self._tolerances[1] - return None - - @property - def var_type(self) -> QualityVarType: - """This is a species""" - return QualityVarType.SPECIES - - @property - def species_type(self) -> SpeciesType: - """The type of species""" - return self._species_type - - @property - def initial_quality(self) -> "NetworkSpecificData": - """If a specific network has been linked, then the initial quality values for the network""" - if self._vals is not None: - return self._vals - else: - raise TypeError("This species is not linked to a NetworkSpecificValues obejct, please `relink` your model") - - @property - def pipe_reaction(self): - if self._vars is not None: - return self._vars.pipe_reactions[self.name] - else: - raise AttributeError('This species is not connected to a ReactionSystem') - - @property - def tank_reaction(self): - if self._vars is not None: - return self._vars.tank_reactions[self.name] - else: - raise AttributeError('This species is not connected to a ReactionSystem') - - def to_dict(self) -> Dict[str, Any]: - """Create a dictionary representation of the object - - The species dictionary has the following format, as described using a json schema. - - .. code:: json - - { - "title": "Species", - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "species_type": { - "enum": ["bulk", "wall"] - }, - "units": { - "type": "string" - }, - "atol": { - "type": "number", - "exclusiveMinimum": 0 - }, - "rtol": { - "type": "number", - "exclusiveMinimum": 0 - }, - "note": { - "type": "string" - }, - "diffusivity": { - "type": "number", - "minimum": 0 - } - }, - "required": ["name", "species_type", "units", "pipe_reaction", "tank_reaction"], - "dependentRequired": {"atol": ["rtol"], "rtol":["atol"]} - } - - """ - ret = dict( - name=self.name, species_type=self.species_type.name.lower(), units=self.units, atol=self.atol, rtol=self.rtol - ) - - if self.diffusivity: - ret["diffusivity"] = self.diffusivity - - if isinstance(self.note, ENcomment): - ret["note"] = self.note.to_dict() - elif isinstance(self.note, (str, dict, list)): - ret["note"] = self.note - - return ret - - -class Constant(WaterQualityVariable): - """A constant coefficient for use in reaction expressions.""" - - def __init__(self, name: str, value: float, *, units: str = None, note=None, _vars=None) -> None: - """A variable representing a constant value. - - Arguments - --------- - name : str - The name of the variable. - value : float - The constant value. - - Keyword Arguments - ----------------- - units : str, optional - Units for the variable, by default None - note : str | dict | ENcomment, optional - Supplementary information regarding this variable, by default None - (see :class:`~wntr.epanet.util.ENcomment` for dict structure). - - Other Parameters - ---------------- - _vars : VariablesRegistry, optional - the variables registry object of the model this variable was added to, by default None - """ - super().__init__(name, note=note) - if _vars is not None and name in _vars: - raise KeyExistsError("This variable name is already taken") - self.value = float(value) - """The value of the constant""" - self.units = units - """The units of the constant""" - if _vars is not None and isinstance(_vars, MultispeciesReactionSystem): - self._vars = _vars - elif _vars is None: - self._vars = None - else: - raise TypeError("Invalid type for _vars") - - def __call__(self, *, t=None) -> Any: - return self.value - - @property - def var_type(self) -> QualityVarType: - """This is a constant coefficient.""" - return QualityVarType.CONSTANT - - def to_dict(self) -> Dict[str, Any]: - ret = dict(name=self.name, value=self.value) - if self.units: - ret["units"] = self.units - if isinstance(self.note, ENcomment): - ret["note"] = self.note.to_dict() - elif isinstance(self.note, (str, dict, list)): - ret["note"] = self.note - return ret - - -class Parameter(WaterQualityVariable): - """A coefficient that is parameterized by pipe/tank.""" - - def __init__(self, name: str, global_value: float, *, units: str = None, note=None, _vars=None, _vals=None) -> None: - """A parameterized variable for use in expressions. - - Arguments - --------- - name : str - The name of this parameter. - global_value : float - The global value for the parameter if otherwise unspecified. - - Keyword Arguments - ----------------- - units : str, optional - The units for this parameter, by default None - note : str | dict | ENcomment, optional - Supplementary information regarding this variable, by default None - (see :class:`~wntr.epanet.util.ENcomment` for dict structure). - - Other Parameters - ---------------- - _vars : VariablesRegistry, optional - the variables registry object of the model this variable was added to, by default None - _vals : ParameterValues, optional - Values for specific tanks or pipes, by default None. This argument should - be passed by the MultispeciesModel during variable creation. - """ - super().__init__(name, note=note) - if _vars is not None and name in _vars: - raise KeyExistsError("This variable name is already taken") - self.global_value = float(global_value) - self.units = units - if _vars is not None and isinstance(_vars, MultispeciesReactionSystem): - self._vars = _vars - elif _vars is None: - self._vars = None - else: - raise TypeError("Invalid type for _vars") - self._vals = _vals - - def __call__(self, *, t=None, pipe: float = None, tank: float = None) -> Any: - if pipe is not None and tank is not None: - raise TypeError("Both pipe and tank cannot be specified at the same time") - elif self._vals is None and (pipe is not None or tank is not None): - raise ValueError("No link provided to network-specific parameter values") - if pipe: - return self._vals.pipe_values.get(pipe, self.global_value) - elif tank: - return self._vals.tank_values.get(pipe, self.global_value) - return self.global_value - - @property - def var_type(self) -> QualityVarType: - """This is a parameterized coefficient.""" - return QualityVarType.PARAMETER - - def link_values(self, values: "ParameterValues"): - """Link the paraemterized values to a model object. - - Note, this should not be necessary if the user uses the MultispeciesModel - add_parameter function. - - Arguments - --------- - values : ParameterValues - The parameter values object. - """ - self._vals = values - - def to_dict(self) -> Dict[str, Any]: - ret = dict(name=self.name, global_value=self.global_value) - if self.units: - ret["units"] = self.units - if isinstance(self.note, ENcomment): - ret["note"] = self.note.to_dict() - elif isinstance(self.note, (str, dict, list)): - ret["note"] = self.note - return ret - - -class Term(WaterQualityVariable): - def __init__(self, name: str, expression: str, *, note=None, _vars=None) -> None: - """A named expression that can be used as a term in other expressions. - - Arguments - --------- - name : str - The variable name. - expression : str - The mathematical expression to be aliased - - Keyword Arguments - ----------------- - note : str | dict | ENcomment, optional - Supplementary information regarding this variable, by default None - (see :class:`~wntr.epanet.util.ENcomment` for dict structure). - - Other Parameters - ---------------- - _vars : VariablesRegistry, optional - the variables registry object of the model this variable was added to, by default None - """ - super().__init__(name, note=note) - if _vars is not None and name in _vars: - raise KeyExistsError("This variable name is already taken") - self.expression = expression - """The expression that is aliased by this term""" - if _vars is not None and isinstance(_vars, MultispeciesReactionSystem): - self._vars = _vars - elif _vars is None: - self._vars = None - else: - raise TypeError("Invalid type for _vars") - - @property - def var_type(self) -> QualityVarType: - """This is a term (named expression).""" - return QualityVarType.TERM - - def to_dict(self) -> Dict[str, Any]: - ret = dict(name=self.name, expression=self.expression) - if isinstance(self.note, ENcomment): - ret["note"] = self.note.to_dict() - elif isinstance(self.note, (str, dict, list)): - ret["note"] = self.note - return ret - - -class ReservedName(WaterQualityVariable): - def __init__(self, name: str, *, note=None) -> None: - """An object representing a reserved name that should not be used by the user. - - Arguments - --------- - name : str - The reserved name. - - Keyword Arguments - ----------------- - note : str | dict | ENcomment, optional - Supplementary information regarding this variable, by default None - (see :class:`~wntr.epanet.util.ENcomment` for dict structure). - - Other Parameters - ---------------- - _vars : VariablesRegistry, optional - the variables registry object of the model this variable was added to, by default None - - Raises - ------ - KeyExistsError - _description_ - """ - self.name = name - self.note = note - - @property - def var_type(self) -> QualityVarType: - """Variable name is a reserved word in MSX""" - return QualityVarType.RESERVED - - def to_dict(self) -> Dict[str, Any]: - raise NotImplementedError("You cannot convert a reserved word to a dictionary representation") - - -class HydraulicVariable(ReservedName): - """A variable representing instantaneous hydraulics data.""" - - def __init__(self, name: str, units: str = None, *, note=None) -> None: - """A variable representing instantaneous hydraulics data. - - The user should not need to create any variables using this class, they - are created automatically by the MultispeciesModel object during initialization. - - Arguments - --------- - name : str - The name of the variable (predefined by MSX) - units : str, optional - The units for hydraulic variable, by default None - - Keyword Arguments - ----------------- - note : str | dict | ENcomment, optional - Supplementary information regarding this variable, by default None - (see :class:`~wntr.epanet.util.ENcomment` for dict structure). - """ - super().__init__(name, note=note) - self.units = units - """The hydraulic variable's units""" - - -class MathFunction(ReservedName): - """A variable that is actually a mathematical function defined by MSX.""" - - def __init__(self, name: str, func: Callable, *, note=None) -> None: - """A variable that is actually a mathematical function defined by MSX. - - Arguments - --------- - name : str - The function name - func : Callable - The callable function - - Keyword Arguments - ----------------- - note : str | dict | ENcomment, optional - Supplementary information regarding this variable, by default None - (see :class:`~wntr.epanet.util.ENcomment` for dict structure). - """ - super().__init__(name, note=note) - self.func = func - """A callable function or SymPy function""" - - def __call__(self, *args: Any, **kwds: Any) -> Any: - return self.func(*args, **kwds) - - - -class Reaction(WaterQualityReaction): - """A water quality biochemical reaction dynamics definition for a specific species.""" - - def __init__(self, species_name: str, reaction_type: ReactionType, dynamics_type: DynamicsType, expression: str, *, note=None) -> None: - """A water quality biochemical reaction dynamics definition for a specific species. - - Arguments - --------- - species_name : Species | str - The species (object or name) this reaction is applicable to. - dynamics_type : DynamicsType - The type of reaction dynamics being described by the expression: one of RATE, FORMULA, or EQUIL. - expression : str - The mathematical expression for the right-hand-side of the reaction equation. - - Keyword Arguments - ----------------- - note : str | dict | ENcomment, optional - Supplementary information regarding this reaction, by default None - (see :class:`~wntr.epanet.util.ENcomment` for dict structure). - """ - super().__init__(species_name=species_name, note=note) - dynamics_type = DynamicsType.get(dynamics_type) - reaction_type = ReactionType.get(reaction_type) - if reaction_type is None: - raise TypeError("Required argument reaction_type cannot be None") - if dynamics_type is None: - raise TypeError("Required argument dynamics_type cannot be None") - self.__reaction_type = reaction_type - self._dynamics_type = dynamics_type - if not expression: - raise TypeError("expression cannot be None") - self.expression = expression - """The mathematical expression (right-hand-side)""" - - @property - def dynamics_type(self) -> DynamicsType: - """The type of dynamics being described. - See :class:`DynamicsType` for valid values. - """ - return self._dynamics_type - - @property - def reaction_type(self) -> ReactionType: - """The type of reaction""" - return self.__reaction_type - - def to_dict(self) -> dict: - ret = dict(species_name=str(self.species_name), dynamics_type=self.dynamics_type.name.lower(), expression=self.expression) - if isinstance(self.note, ENcomment): - ret["note"] = self.note.to_dict() - elif isinstance(self.note, (str, dict, list)): - ret["note"] = self.note - return ret - - -class MultispeciesReactionSystem(WaterQualityReactionSystem): - """A registry for all the variables registered in the multispecies reactions model. - - This object can be used like an immutable mapping, with the ``__len__``, ``__getitem__``, - ``__iter__``, ``__contains__``, ``__eq__`` and ``__ne__`` functions being defined. - """ - - def __init__(self) -> None: - """Create a new reaction system. - """ - super().__init__() - self._vars.add_disjoint_group("reserved") - self._species = self._vars.add_disjoint_group("species") - self._const = self._vars.add_disjoint_group("constant") - self._param = self._vars.add_disjoint_group("parameter") - self._term = self._vars.add_disjoint_group("term") - self._rxns = dict(pipe=dict(), tank=dict()) - self._pipes = self._rxns['pipe'] - self._tanks = self._rxns['tank'] - - @property - def species(self) -> Dict[str, Species]: - """The dictionary view onto only species""" - return self._species - - @property - def constants(self) -> Dict[str, Constant]: - """The dictionary view onto only constants""" - return self._const - - @property - def parameters(self) -> Dict[str, Parameter]: - """The dictionary view onto only parameters""" - return self._param - - @property - def terms(self) -> Dict[str, Term]: - """The dictionary view onto only named terms""" - return self._term - - @property - def pipe_reactions(self) -> Dict[str, WaterQualityReaction]: - """The dictionary view onto pipe reactions""" - return self._pipes - - @property - def tank_reactions(self) -> Dict[str, WaterQualityReaction]: - """The dictionary view onto tank reactions""" - return self._tanks - - def add_variable(self, obj: WaterQualityVariable) -> None: - """Add a variable object to the registry. - - The appropriate group is determined by querying the object's - var_type attribute. - - Arguments - --------- - obj : WaterQualityVariable - The variable to add. - - Raises - ------ - TypeError - if obj is not a WaterQualityVariable - KeyExistsError - if obj has a name that is already used in the registry - """ - if not isinstance(obj, WaterQualityVariable): - raise TypeError("Expected WaterQualityVariable object") - if obj.name in self: - raise KeyExistsError("Variable name {} already exists in model".format(obj.name)) - obj._vars = self - self._vars.add_item_to_group(obj.var_type.name.lower(), obj.name, obj) - - def add_reaction(self, obj: WaterQualityReaction) -> None: - """Add a reaction to the model - - Parameters - ---------- - obj : WaterQualityReaction - _description_ - - Raises - ------ - TypeError - _description_ - KeyError - _description_ - """ - if not isinstance(obj, WaterQualityReaction): - raise TypeError("Expected WaterQualityReaction object") - if obj.species_name not in self: - raise KeyError("Species {} does not exist in the model".format(obj.species_name)) - self._rxns[obj.reaction_type.name.lower()][obj.species_name] = obj - - def all_variables(self): - """A generator looping through all variables""" - for k, v in self._vars.items(): - yield k, v.var_type.name.lower(), v - - def all_reactions(self): - """A generator looping through all reactions""" - for k2, v in self._rxns.items(): - for k1, v1 in v.items(): - yield k1, k2, v1 - - def to_dict(self): - return dict( - species=[v.to_dict() for v in self._species.values()], - constants=[v.to_dict() for v in self._const.values()], - parameters=[v.to_dict() for v in self._param.values()], - terms=[v.to_dict() for v in self._term.values()], - pipe_reactions=[v.to_dict() for v in self.pipe_reactions.values()], - tank_reactions=[v.to_dict() for v in self.tank_reactions.values()], - ) - - -class InitialQuality: - """A container for initial quality values for a species in a specific network.""" - - def __init__(self, global_value: float = 0.0, node_values: dict = None, link_values: dict = None): - """The initial quality values for a species. - - Arguments - --------- - global_value : float, optional - _description_, by default 0.0 - node_values : dict[str, float], optional - _description_, by default None - link_values : dict[str, float], optional - _description_, by default None - """ - self.global_value = global_value - """The global value for this species, if unspecified""" - self._node_values = node_values if node_values is not None else dict() - self._link_values = link_values if link_values is not None else dict() - - def __repr__(self) -> str: - return self.__class__.__name__ + "(global_value={}, node_values=<{} entries>, link_values=<{} entries>)".format( - self.global_value, len(self._node_values), len(self._link_values) - ) - - @property - def node_values(self) -> Dict[str, float]: - """A mapping of node names to initial quality values for this species""" - return self._node_values - - @property - def link_values(self) -> Dict[str, float]: - """A mapping of link names to initial quality values for this species""" - return self._link_values - - def to_dict(self) -> Dict[str, Dict[str, float]]: - return dict(global_value=self.global_value, node_values=self._node_values.copy(), link_values=self._link_values.copy()) - - -class ParameterValues: - """A container for pipe and tank specific values of a parameter for a specific network.""" - - def __init__(self, *, pipe_values: dict = None, tank_values: dict = None) -> None: - """The non-global values for a parameter. - - Arguments - --------- - pipe_values : dict, optional - _description_, by default None - tank_values : dict, optional - _description_, by default None - """ - self._pipe_values = pipe_values if pipe_values is not None else dict() - self._tank_values = tank_values if tank_values is not None else dict() - - def __repr__(self) -> str: - return self.__class__.__name__ + "(pipe_values=<{} entries>, tank_values=<{} entries>)".format( - len(self._pipe_values), len(self._tank_values) - ) - - @property - def pipe_values(self) -> Dict[str, float]: - """View onto the pipe values dictionary""" - return self._pipe_values - - @property - def tank_values(self) -> Dict[str, float]: - """View onto the tank values dictionary""" - return self._tank_values - - def to_dict(self) -> Dict[str, Dict[str, float]]: - return dict(pipe_values=self._pipe_values.copy(), tank_values=self._tank_values.copy()) - - -class NetworkSpecificData: - """A container for network-specific values associated with a multispecies water quality model.""" - - def __init__(self, patterns: dict = None, sources: dict = None, initial_quality: dict = None, parameter_values: dict = None) -> None: - """A container for network-specific values associated with a multispecies water quality model. - - Data is copied from dictionaries passed in, so once created, the dictionaries passed are not connected - to this object. - - Parameters - ---------- - patterns : Dict[str, List[float]] - patterns to use for sources - sources : Dict[str, dict] - sources defined for the model - initial_quality : Dict[str, dict] - initial values for different species at different nodes, links, and the global value - parameter_values : Dict[str, dict] - parameter values for different pipes and tanks - """ - if sources is None: - sources = dict() - if initial_quality is None: - initial_quality = dict() - if patterns is None: - patterns = dict() - if parameter_values is None: - parameter_values = dict() - self._source_dict = dict() - self._pattern_dict = dict() - self._initial_quality_dict: Dict[str, InitialQuality] = dict() - self._parameter_value_dict: Dict[str, ParameterValues] = dict() - - self._source_dict = sources.copy() - self._pattern_dict = patterns.copy() - for k, v in initial_quality.items(): - self._initial_quality_dict[k] = InitialQuality(**v) - for k, v in parameter_values.items(): - self._parameter_value_dict[k] = ParameterValues(**v) - - @property - def sources(self): - """A dictionary of sources, keyed by species name""" - return self._source_dict - - @property - def initial_quality(self) -> Dict[str, InitialQuality]: - """A dictionary of initial quality values, keyed by species name""" - return self._initial_quality_dict - - @property - def patterns(self): - """A dictionary of patterns, specific for the water quality model, keyed by pattern name. - - .. note:: the WaterNetworkModel cannot see these patterns, so names can be reused, so be - careful. Likewise, this model cannot see the WaterNetworkModel patterns, so this could be - a source of some confusion. - """ - return self._pattern_dict - - @property - def parameter_values(self): - """A dictionary of parameter values, keyed by parameter name""" - return self._parameter_value_dict - - def add_pattern(self, name: str, multipliers: List[float]): - """Add a water-quality-model-specific pattern. - - Arguments - --------- - name : str - The pattern name - multipliers : List[float] - The pattern multipliers - """ - self._pattern_dict[name] = multipliers - - def init_new_species(self, species: Species): - """(Re)set the initial quality values for a species to a new container - - Arguments - --------- - species : Species - The species to (re) initialized. - - Returns - ------- - InitialQuality - the new initial quality values container - """ - self._initial_quality_dict[str(species)] = InitialQuality() - if isinstance(species, Species): - species._vals = self._initial_quality_dict[str(species)] - return self._initial_quality_dict[str(species)] - - def remove_species(self, species: Union[Species, str]): - """Remove a species from the network specific model. - - Arguments - --------- - species : Union[Species, str] - _description_ - """ - if isinstance(species, Species): - species._vals = None - try: - self._initial_quality_dict.__delitem__(str(species)) - except KeyError: - pass - - def init_new_parameter(self, param: Parameter): - """(Re)initialize parameter values for a parameter. - - Arguments - --------- - param : Parameter - _description_ - - Returns - ------- - _type_ - _description_ - """ - self._parameter_value_dict[str(param)] = ParameterValues() - if isinstance(param, Parameter): - param._vals = self._parameter_value_dict[str(param)] - return self._parameter_value_dict[str(param)] - - def remove_parameter(self, param: Union[Parameter, str]): - """Remove values associated with a specific parameter. - - Arguments - --------- - param : Union[Parameter, str] - _description_ - """ - if isinstance(param, Parameter): - param._vals = None - try: - self._parameter_value_dict.__delitem__(str(param)) - except KeyError: - pass - - def to_dict(self): - ret = dict(initial_quality=dict(), parameter_values=dict(), sources=dict(), patterns=dict()) - for k, v in self._initial_quality_dict.items(): - ret["initial_quality"][k] = v.to_dict() - for k, v in self._parameter_value_dict.items(): - ret["parameter_values"][k] = v.to_dict() - ret["sources"] = self._source_dict.copy() - ret["patterns"] = self._pattern_dict.copy() - return ret - - -class MultispeciesQualityModel: - """A multispecies water quality model for use with WNTR EPANET-MSX simulator.""" - - def __init__(self, msx_file_name=None) -> None: - """A full, multi-species water quality model. - - Arguments - --------- - msx_file_name : str, optional - an MSX file to read in, by default None - """ - self.name: str = None - """A name for the model, or the MSX model filename (no spaces allowed)""" - self.title: str = None - """The title line from the MSX file, must be a single line""" - self.desc: str = None - """A longer description, note that multi-line descriptions may not be - represented well in dictionary form.""" - self._orig_file: str = None - """The original filename""" - self._references: List[Union[str, Dict[str, str]]] = list() - self._options = MultispeciesOptions() - self._reaction_system = MultispeciesReactionSystem() - self._network_data = NetworkSpecificData() - self._wn = None - - for v in HYDRAULIC_VARIABLES: - self._reaction_system.add_variable(HydraulicVariable(**v)) - for k, v in EXPR_FUNCTIONS.items(): - self._reaction_system.add_variable(MathFunction(name=k.lower(), func=v)) - self._reaction_system.add_variable(MathFunction(name=k.capitalize(), func=v)) - self._reaction_system.add_variable(MathFunction(name=k.upper(), func=v)) - - if msx_file_name is not None: - from wntr.epanet.msx.io import MsxFile - MsxFile.read(msx_file_name, self) - - def __repr__(self) -> str: - ret = '{}('.format(self.__class__.__name__) - if self.name: - ret = ret + 'name={}'.format(repr(self.name)) - elif self.title: - ret = ret + 'title={}'.format(repr(self.title)) - elif self._orig_file: - ret = ret + 'msx_file_name={}'.format(repr(self._orig_file)) - ret = ret + ')' - return ret - - @property - def references(self) -> List[Union[str, Dict[str, str]]]: - """A list of strings or mappings that provide references for this model. - This property should be modified using append/insert/remove. Members of - the list should be json seriealizable (i.e., strings or dicts of strings). - """ - return self._references - - @property - def reaction_system(self) -> MultispeciesReactionSystem: - """The reaction variables defined for this model.""" - return self._reaction_system - - @property - def rxn_sys(self) -> MultispeciesReactionSystem: - """Alias for the reaction_system property for ease of programming""" - return self._reaction_system - - @property - def network_data(self) -> NetworkSpecificData: - """The network-specific values added to this model.""" - return self._network_data - - @property - def net_data(self) -> NetworkSpecificData: - """Alias for the reaction_system property for ease of programming""" - return self._network_data - - @property - def options(self) -> MultispeciesOptions: - """The MSX model options""" - return self._options - - @property - def species_name_list(self) -> List[str]: - """all defined species names""" - return list(self.reaction_system.species.keys()) - - @property - def constant_name_list(self) -> List[str]: - """all defined coefficient names""" - return list(self.reaction_system.constants.keys()) - - @property - def parameter_name_list(self) -> List[str]: - """all defined coefficient names""" - return list(self.reaction_system.parameters.keys()) - - @property - def term_name_list(self) -> List[str]: - """all defined function (MSX 'terms') names""" - return list(self.reaction_system.terms.keys()) - - @options.setter - def options(self, value): - if isinstance(value, dict): - self._options = MultispeciesOptions.factory(value) - elif not isinstance(value, MultispeciesOptions): - raise TypeError("Expected a MultispeciesOptions object, got {}".format(type(value))) - else: - self._options = value - - def add_species( - self, - name: str, - species_type: SpeciesType, - units: str, - atol: float = None, - rtol: float = None, - *, - note: Any = None, - diffusivity: float = None, - ) -> Species: - """Add a species to the model - - Arguments - --------- - name : str - _description_ - species_type : SpeciesType - _description_ - units : str - _description_ - atol : float, optional - _description_, by default None - rtol : float, optional - _description_, by default None - - Keyword Arguments - ----------------- - note : str | dict | ENcomment, optional - Supplementary information regarding this variable, by default None - (see :class:`~wntr.epanet.util.ENcomment` for dict structure). - diffusivity : float, optional - Diffusivity in water for this species. - - Raises - ------ - KeyError - _description_ - - Returns - ------- - Species - _description_ - """ - if name in self._reaction_system: - raise KeyError( - "Variable named {} already exists in model as type {}".format(name, self._reaction_system._vars.get_groupname(name)) - ) - species_type = SpeciesType.get(species_type, allow_none=False) - iq = self.network_data.init_new_species(name) - new = Species( - name=name, - species_type=species_type, - units=units, - atol=atol, - rtol=rtol, - note=note, - _vars=self._reaction_system, - _vals=iq, - diffusivity=diffusivity, - ) - self.reaction_system.add_variable(new) - return new - - def remove_species(self, species): - """Remove a species from the model. - - Arguments - --------- - species : _type_ - _description_ - """ - name = str(species) - self.network_data.remove_species(name) - # FIXME: validate additional items - self.reaction_system.__delitem__(name) - - def add_constant(self, name: str, value: float, *, units: str = None, note: Any = None) -> Constant: - """Add a constant coefficient to the model. - - Arguments - --------- - name : str - _description_ - value : float - _description_ - - Keyword Arguments - ----------------- - units : str, optional - _description_, by default None - note : str | dict | ENcomment, optional - Supplementary information regarding this variable, by default None - (see :class:`~wntr.epanet.util.ENcomment` for dict structure). - - Raises - ------ - KeyError - _description_ - - Returns - ------- - Constant - _description_ - """ - if name in self._reaction_system: - raise KeyError( - "Variable named {} already exists in model as type {}".format(name, self._reaction_system._vars.get_groupname(name)) - ) - new = Constant(name=name, value=value, units=units, note=note, _vars=self._reaction_system) - self.reaction_system.add_variable(new) - return new - - def remove_constant(self, const): - """Remove a constant coefficient from the model. - - Arguments - --------- - const : _type_ - _description_ - """ - name = str(const) - # FIXME: validate deletion - self.reaction_system.__delitem__(name) - - def add_parameter(self, name: str, global_value: float, *, units: str = None, note: Any = None) -> Parameter: - """Add a parameterized coefficient to the model. - - Arguments - --------- - name : str - _description_ - global_value : float - _description_ - - Keyword Arguments - ----------------- - units : str, optional - _description_, by default None - note : str | dict | ENcomment, optional - Supplementary information regarding this variable, by default None - (see :class:`~wntr.epanet.util.ENcomment` for dict structure). - - Raises - ------ - KeyError - _description_ - - Returns - ------- - Parameter - _description_ - """ - if name in self._reaction_system: - raise KeyError( - "Variable named {} already exists in model as type {}".format(name, self._reaction_system._vars.get_groupname(name)) - ) - pv = self.network_data.init_new_parameter(name) - new = Parameter(name=name, global_value=global_value, units=units, note=note, _vars=self._reaction_system, _vals=pv) - self.reaction_system.add_variable(new) - return new - - def remove_parameter(self, param): - """Remove a parameterized coefficient from the model. - - Arguments - --------- - param : _type_ - _description_ - """ - name = str(param) - self.network_data.remove_parameter(name) - # FIXME: validate additional items - self.reaction_system.__delitem__(name) - - def add_term(self, name: str, expression: str, *, note: Any = None) -> Term: - """Add a named expression (term) to the model. - - Arguments - --------- - name : str - _description_ - expression : str - _description_ - - Keyword Arguments - ----------------- - note : str | dict | ENcomment, optional - Supplementary information regarding this variable, by default None - (see :class:`~wntr.epanet.util.ENcomment` for dict structure). - - Raises - ------ - KeyError - _description_ - - Returns - ------- - Term - _description_ - """ - if name in self._reaction_system: - raise KeyError( - "Variable named {} already exists in model as type {}".format(name, self._reaction_system._vars.get_groupname(name)) - ) - new = Term(name=name, expression=expression, note=note, _vars=self._reaction_system) - self.reaction_system.add_variable(new) - return new - - def remove_term(self, term): - """Remove a named expression (term) from the model. - - Arguments - --------- - term : _type_ - _description_ - """ - name = str(term) - # FIXME: validate deletion - self.reaction_system.__delitem__(name) - - def add_reaction( - self, species_name: str, reaction_type: ReactionType, dynamics_type: DynamicsType, expression: str, *, note: Any = None - ) -> WaterQualityReaction: - """Add a reaction to a species in the model. - - Note that all species need to have both a pipe and tank reaction defined - unless all species are bulk species and - the tank reactions are identical to the pipe reactions. However, it is not - recommended that users take this approach. - - Once added, access the reactions from the species' object. - - Arguments - --------- - species_name : str - _description_ - location_type : LocationType - _description_ - dynamics_type : DynamicsType - _description_ - expression : str - _description_ - - Keyword Arguments - ----------------- - note : str | dict | ENcomment, optional - Supplementary information regarding this reaction, by default None - (see :class:`~wntr.epanet.util.ENcomment` for dict structure). - - Raises - ------ - TypeError - _description_ - - Returns - ------- - MultispeciesReaction - _description_ - """ - species_name = str(species_name) - species = self.reaction_system.species[species_name] - if species.var_type is not QualityVarType.SPECIES: - raise TypeError("Variable {} is not a Species, is a {}".format(species.name, species.var_type)) - reaction_type = ReactionType.get(reaction_type, allow_none=False) - dynamics_type = DynamicsType.get(dynamics_type, allow_none=False) - new = Reaction(reaction_type=reaction_type, dynamics_type=dynamics_type, species_name=species_name, expression=expression, note=note) - self.reaction_system.add_reaction(new) - return new - - def remove_reaction(self, species_name: str, reaction_type: ReactionType) -> None: - """Remove a reaction at a specified location from a species. - - Parameters - ---------- - species : str - the species name to remove the reaction from - location : LocationType - the location to remove the reaction from - """ - reaction_type = ReactionType.get(reaction_type, allow_none=False) - species_name = str(species_name) - del self.reaction_system.all_reactions[reaction_type.name.lower()][species_name] - - def to_dict(self): - from wntr import __version__ - - return { - 'wntr-version': "{}".format(__version__), - 'name': self.name, - 'title': self.title, - 'desc': self.desc if self.desc is None or '\n' not in self.desc else self.desc.splitlines(), - 'references': self.references.copy(), - 'reaction_system': self.reaction_system.to_dict(), - 'network_data': self.network_data.to_dict(), - 'options': self.options.to_dict(), - } - - @classmethod - def from_dict(cls, data): - from wntr import __version__ - - ver = data.get('wntr-version', None) - if ver > __version__: - logger.warn('Importing from a file created by a newer version of wntr, compatibility not guaranteed') - warnings.warn('Importing from a file created by a newer version of wntr, compatibility not guaranteed') - new = cls() - new.name = data.get('name', None) - new.title = data.get('title', None) - new.desc = data.get('desc', None) - if isinstance(new.desc, (list, tuple)): - desc = '\n'.join(new.desc) - new.desc = desc - new.references.extend(data.get('references', list())) - - rxn_sys = data.get('reaction_system', dict()) - for var in rxn_sys.get('species', list()): - new.add_species(**var) - for var in rxn_sys.get('constants', list()): - new.add_constant(**var) - for var in rxn_sys.get('parameters', list()): - new.add_parameter(**var) - for var in rxn_sys.get('terms', list()): - new.add_term(**var) - for rxn in rxn_sys.get('pipe_reactions', list()): - rxn['reaction_type'] = 'pipe' - new.add_reaction(**rxn) - for rxn in rxn_sys.get('tank_reactions', list()): - rxn['reaction_type'] = 'tank' - new.add_reaction(**rxn) - - new._network_data = NetworkSpecificData(**data.get('network_data', dict())) - for species in new.rxn_sys.species: - if species not in new.net_data.initial_quality: - new.net_data.init_new_species(species) - for param in new.rxn_sys.parameters: - if param not in new.net_data.parameter_values: - new.net_data.init_new_parameter(param) - - opts = data.get('options', None) - if opts: - new.options = opts - - return new diff --git a/wntr/sim/epanet.py b/wntr/sim/epanet.py index c74905b45..329cd6134 100644 --- a/wntr/sim/epanet.py +++ b/wntr/sim/epanet.py @@ -130,6 +130,7 @@ def run_sim(self, file_prefix='temp', save_hyd=False, use_hyd=False, hydfile=Non results = self.reader.read(outfile, convergence_error, self._wn.options.hydraulic.headloss=='D-W') if self._wn._msx is not None: + # Attributed to Matthew's package msxfile = file_prefix + '.msx' rptfile = file_prefix + '.msx-rpt' binfile = file_prefix + '.msx-bin' diff --git a/wntr/tests/test_epanet_msx_io.py b/wntr/tests/test_epanet_msx_io.py index 0bcf73a2e..09cb38625 100644 --- a/wntr/tests/test_epanet_msx_io.py +++ b/wntr/tests/test_epanet_msx_io.py @@ -5,7 +5,7 @@ import numpy as np import pandas as pd import wntr -import wntr.quality +import wntr.msx import wntr.epanet.msx import sympy @@ -26,10 +26,10 @@ def tearDownClass(self): def test_msx_io(self): wn_model = wntr.network.WaterNetworkModel(inp_file_name=inp_filename) - msx_model = wntr.quality.MultispeciesQualityModel(msx_file_name=msx_filename) + msx_model = wntr.msx.MsxModel(msx_file_name=msx_filename) wntr.epanet.InpFile().write("test.inp", wn_model) wntr.epanet.msx.MsxFile().write("test.msx", msx_model) - msx_model2 = wntr.quality.MultispeciesQualityModel(msx_file_name="test.msx") + msx_model2 = wntr.msx.MsxModel(msx_file_name="test.msx") true_vars = ["AS3", "AS5", "AS5s", "AStot", "Av", "D", "Ff", "K1", "K2", "Ka", "Kb", "Kc", "Ks", "Len", "NH2CL", "Q", "Re", "Smax", "U", "Us"] in_vars = msx_model.variable_name_list in_vars.sort() diff --git a/wntr/tests/test_epanet_msx_tooklit.py b/wntr/tests/test_epanet_msx_tooklit.py index 3191d3f0e..71cef63fe 100644 --- a/wntr/tests/test_epanet_msx_tooklit.py +++ b/wntr/tests/test_epanet_msx_tooklit.py @@ -5,7 +5,7 @@ import numpy as np import pandas as pd import wntr -import wntr.quality +import wntr.msx import wntr.epanet.msx import wntr.epanet.msx.toolkit import sympy @@ -26,7 +26,7 @@ def tearDownClass(self): def test_msx_io(self): wn_model = wntr.network.WaterNetworkModel(inp_file_name=inp_filename) - msx_model = wntr.quality.MultispeciesQualityModel(msx_file_name=msx_filename) + msx_model = wntr.msx.MsxModel(msx_file_name=msx_filename) wntr.epanet.msx.toolkit.MSXepanet(inp_filename, msxfile=msx_filename) diff --git a/wntr/tests/test_quality_variables.py b/wntr/tests/test_quality_variables.py index 7deb011cc..142e33049 100644 --- a/wntr/tests/test_quality_variables.py +++ b/wntr/tests/test_quality_variables.py @@ -5,7 +5,7 @@ import numpy as np import pandas as pd import wntr -import wntr.quality +import wntr.msx import sympy testdir = dirname(abspath(str(__file__))) @@ -24,35 +24,35 @@ def tearDownClass(self): pass def test_ReactionVariable_reserved_name_exception(self): - self.assertRaises(ValueError, wntr.quality.Species, 'bulk', "D", "mg") - self.assertRaises(ValueError, wntr.quality.Species, 'wall', "Q", "mg") - self.assertRaises(ValueError, wntr.quality.Constant, "Re", 0.52) - self.assertRaises(ValueError, wntr.quality.Parameter, "Re", 0.52) - self.assertRaises(ValueError, wntr.quality.OtherTerm, "Re", 0.52) + self.assertRaises(ValueError, wntr.msx.Species, 'bulk', "D", "mg") + self.assertRaises(ValueError, wntr.msx.Species, 'wall', "Q", "mg") + self.assertRaises(ValueError, wntr.msx.Constant, "Re", 0.52) + self.assertRaises(ValueError, wntr.msx.Parameter, "Re", 0.52) + self.assertRaises(ValueError, wntr.msx.OtherTerm, "Re", 0.52) def test_RxnVariable_symbols_and_sympy(self): - species1 = wntr.quality.Species('BULK', "Cl", "mg") + species1 = wntr.msx.Species('BULK', "Cl", "mg") symbol1 = sympy.symbols("Cl") self.assertEqual(species1.symbol, symbol1) - const1 = wntr.quality.Constant("Kb", 0.482) + const1 = wntr.msx.Constant("Kb", 0.482) symbol2 = sympy.symbols("Kb") self.assertEqual(const1.symbol, symbol2) - param1 = wntr.quality.Constant("Ka", 0.482) + param1 = wntr.msx.Constant("Ka", 0.482) symbol3 = sympy.symbols("Ka") self.assertEqual(param1.symbol, symbol3) - term1 = wntr.quality.OtherTerm("T0", "-3.2 * Kb * Cl^2", note="bar") + term1 = wntr.msx.OtherTerm("T0", "-3.2 * Kb * Cl^2", note="bar") symbol4 = sympy.symbols("T0") self.assertEqual(term1.symbol, symbol4) def test_RxnVariable_values(self): - const1 = wntr.quality.Constant("Kb", 0.482, note="test") + const1 = wntr.msx.Constant("Kb", 0.482, note="test") self.assertEqual(const1.get_value(), const1.global_value) test_pipe_dict = {"PIPE": 0.38} test_tank_dict = {"TANK": 222.23} - param2 = wntr.quality.Parameter("Kb", 0.482, note="test", pipe_values=test_pipe_dict, tank_values=test_tank_dict) + param2 = wntr.msx.Parameter("Kb", 0.482, note="test", pipe_values=test_pipe_dict, tank_values=test_tank_dict) self.assertEqual(param2.get_value(), param2.global_value) self.assertEqual(param2.get_value(pipe="PIPE"), test_pipe_dict["PIPE"]) self.assertEqual(param2.get_value(pipe="FOO"), param2.global_value) @@ -60,11 +60,11 @@ def test_RxnVariable_values(self): self.assertRaises(TypeError, param2.get_value, pipe="PIPE", tank="TANK") def test_RxnVariable_string_functions(self): - species1 = wntr.quality.Species('BULK', "Cl", "mg") - species2 = wntr.quality.Species('WALL', "Cl", "mg", 0.01, 0.0001, note="Testing stuff") - const1 = wntr.quality.Constant("Kb", 0.482) - param1 = wntr.quality.Parameter("Ka", 0.482, note="foo") - term1 = wntr.quality.OtherTerm("T0", "-3.2 * Kb * Cl^2", note="bar") + species1 = wntr.msx.Species('BULK', "Cl", "mg") + species2 = wntr.msx.Species('WALL', "Cl", "mg", 0.01, 0.0001, note="Testing stuff") + const1 = wntr.msx.Constant("Kb", 0.482) + param1 = wntr.msx.Parameter("Ka", 0.482, note="foo") + term1 = wntr.msx.OtherTerm("T0", "-3.2 * Kb * Cl^2", note="bar") self.assertEqual(str(species1), "Cl") self.assertEqual(str(const1), "Kb") @@ -73,8 +73,8 @@ def test_RxnVariable_string_functions(self): def test_Species_tolerances(self): # """RxnSpecies(*s) tolerance settings""" - species1 = wntr.quality.Species("B", "Cl", "mg") - species2 = wntr.quality.Species("W", "Cl", "mg", 0.01, 0.0001, note="Testing stuff") + species1 = wntr.msx.Species("B", "Cl", "mg") + species2 = wntr.msx.Species("W", "Cl", "mg", 0.01, 0.0001, note="Testing stuff") self.assertIsNone(species1.get_tolerances()) self.assertIsNotNone(species2.get_tolerances()) self.assertTupleEqual(species2.get_tolerances(), (0.01, 0.0001)) @@ -94,19 +94,19 @@ def test_Species_tolerances(self): def test_BulkSpecies_creation(self): # """BlukSpecies object creation (direct instantiation)""" - self.assertRaises(TypeError, wntr.quality.Species, "b", "Re") - self.assertRaises(ValueError, wntr.quality.Species, "B", "Re", "mg") - self.assertRaises(TypeError, wntr.quality.Species, 1, "Cl", "mg", 0.01) - self.assertRaises(TypeError, wntr.quality.Species, wntr.quality.base.SpeciesType.BULK, "Cl", "mg", None, 0.01) - species = wntr.quality.Species(1, "Cl", "mg") + self.assertRaises(TypeError, wntr.msx.Species, "b", "Re") + self.assertRaises(ValueError, wntr.msx.Species, "B", "Re", "mg") + self.assertRaises(TypeError, wntr.msx.Species, 1, "Cl", "mg", 0.01) + self.assertRaises(TypeError, wntr.msx.Species, wntr.msx.base.SpeciesType.BULK, "Cl", "mg", None, 0.01) + species = wntr.msx.Species(1, "Cl", "mg") self.assertEqual(species.name, "Cl") self.assertEqual(species.units, "mg") - self.assertEqual(species.var_type, wntr.quality.SpeciesType.BULK) + self.assertEqual(species.var_type, wntr.msx.SpeciesType.BULK) self.assertIsNone(species._atol) self.assertIsNone(species._rtol) self.assertIsNone(species.note) - species = wntr.quality.Species('b', "Cl", "mg", 0.01, 0.0001, note="Testing stuff") - self.assertEqual(species.var_type, wntr.quality.SpeciesType.BULK) + species = wntr.msx.Species('b', "Cl", "mg", 0.01, 0.0001, note="Testing stuff") + self.assertEqual(species.var_type, wntr.msx.SpeciesType.BULK) self.assertEqual(species.name, "Cl") self.assertEqual(species.units, "mg") self.assertEqual(species._atol, 0.01) @@ -115,19 +115,19 @@ def test_BulkSpecies_creation(self): def test_WallSpecies_creation(self): # """WallSpecies object creation (direct instantiation)""" - self.assertRaises(TypeError, wntr.quality.Species, 'W', "Re") - self.assertRaises(ValueError, wntr.quality.Species, 'Wall', "Re", "mg") - self.assertRaises(TypeError, wntr.quality.Species, 2, "Cl", "mg", 0.01) - self.assertRaises(TypeError, wntr.quality.Species, 'W', "Cl", "mg", None, 0.01) - species = wntr.quality.Species('w', "Cl", "mg") + self.assertRaises(TypeError, wntr.msx.Species, 'W', "Re") + self.assertRaises(ValueError, wntr.msx.Species, 'Wall', "Re", "mg") + self.assertRaises(TypeError, wntr.msx.Species, 2, "Cl", "mg", 0.01) + self.assertRaises(TypeError, wntr.msx.Species, 'W', "Cl", "mg", None, 0.01) + species = wntr.msx.Species('w', "Cl", "mg") self.assertEqual(species.name, "Cl") self.assertEqual(species.units, "mg") - self.assertEqual(species.var_type, wntr.quality.SpeciesType.WALL) + self.assertEqual(species.var_type, wntr.msx.SpeciesType.WALL) self.assertIsNone(species._atol) self.assertIsNone(species._rtol) self.assertIsNone(species.note) - species = wntr.quality.Species('w', "Cl", "mg", 0.01, 0.0001, note="Testing stuff") - self.assertEqual(species.var_type, wntr.quality.SpeciesType.WALL) + species = wntr.msx.Species('w', "Cl", "mg", 0.01, 0.0001, note="Testing stuff") + self.assertEqual(species.var_type, wntr.msx.SpeciesType.WALL) self.assertEqual(species.name, "Cl") self.assertEqual(species.units, "mg") self.assertEqual(species._atol, 0.01) @@ -135,75 +135,75 @@ def test_WallSpecies_creation(self): self.assertEqual(species.note, "Testing stuff") def test_Constant_creation(self): - self.assertRaises(TypeError, wntr.quality.Constant, "Re") - self.assertRaises(ValueError, wntr.quality.Constant, "Re", 2.48) - const1 = wntr.quality.Constant("Kb", 0.482, note="test") + self.assertRaises(TypeError, wntr.msx.Constant, "Re") + self.assertRaises(ValueError, wntr.msx.Constant, "Re", 2.48) + const1 = wntr.msx.Constant("Kb", 0.482, note="test") # FIXME: Find a way to suppress warning printing # self.assertWarns(RuntimeWarning, wntr.reaction.Constant, 'Kb1', 0.83, pipe_values={'a',1}) self.assertEqual(const1.name, "Kb") self.assertEqual(const1.global_value, 0.482) self.assertEqual(const1.get_value(), const1.global_value) - self.assertEqual(const1.var_type, wntr.quality.QualityVarType.CONST) + self.assertEqual(const1.var_type, wntr.msx.VariableType.CONST) self.assertEqual(const1.note, "test") def test_Parameter_creation(self): - self.assertRaises(TypeError, wntr.quality.Parameter, "Re") - self.assertRaises(ValueError, wntr.quality.Parameter, "Re", 2.48) - param1 = wntr.quality.Parameter("Kb", 0.482, note="test") + self.assertRaises(TypeError, wntr.msx.Parameter, "Re") + self.assertRaises(ValueError, wntr.msx.Parameter, "Re", 2.48) + param1 = wntr.msx.Parameter("Kb", 0.482, note="test") self.assertEqual(param1.name, "Kb") self.assertEqual(param1.global_value, 0.482) self.assertEqual(param1.get_value(), param1.global_value) - self.assertEqual(param1.var_type, wntr.quality.QualityVarType.PARAM) + self.assertEqual(param1.var_type, wntr.msx.VariableType.PARAM) self.assertEqual(param1.note, "test") test_pipe_dict = {"PIPE": 0.38} test_tank_dict = {"TANK": 222.23} - param2 = wntr.quality.Parameter("Kb", 0.482, note="test", pipe_values=test_pipe_dict, tank_values=test_tank_dict) + param2 = wntr.msx.Parameter("Kb", 0.482, note="test", pipe_values=test_pipe_dict, tank_values=test_tank_dict) self.assertDictEqual(param2.pipe_values, test_pipe_dict) self.assertDictEqual(param2.tank_values, test_tank_dict) def test_RxnTerm_creation(self): - self.assertRaises(TypeError, wntr.quality.OtherTerm, "Re") - self.assertRaises(ValueError, wntr.quality.OtherTerm, "Re", "1.0*Re") - term1 = wntr.quality.OtherTerm("T0", "-3.2 * Kb * Cl^2", note="bar") + self.assertRaises(TypeError, wntr.msx.OtherTerm, "Re") + self.assertRaises(ValueError, wntr.msx.OtherTerm, "Re", "1.0*Re") + term1 = wntr.msx.OtherTerm("T0", "-3.2 * Kb * Cl^2", note="bar") self.assertEqual(term1.name, "T0") self.assertEqual(term1.expression, "-3.2 * Kb * Cl^2") - self.assertEqual(term1.var_type, wntr.quality.QualityVarType.TERM) + self.assertEqual(term1.var_type, wntr.msx.VariableType.TERM) self.assertEqual(term1.note, "bar") def test_RxnExpression_strings(self): - equil1 = wntr.quality.EquilibriumDynamics("Cl", wntr.quality.ReactionType.PIPE, "-Ka + Kb * Cl + T0") - rate1 = wntr.quality.TankReaction("Cl", wntr.quality.ReactionType.TANK, "-Ka + Kb * Cl + T0", note="Foo Bar") - formula1 = wntr.quality.PipeReaction("Cl", wntr.quality.ReactionType.PIPE, "-Ka + Kb * Cl + T0") + equil1 = wntr.msx.EquilibriumDynamics("Cl", wntr.msx.ReactionType.PIPE, "-Ka + Kb * Cl + T0") + rate1 = wntr.msx.TankReaction("Cl", wntr.msx.ReactionType.TANK, "-Ka + Kb * Cl + T0", note="Foo Bar") + formula1 = wntr.msx.PipeReaction("Cl", wntr.msx.ReactionType.PIPE, "-Ka + Kb * Cl + T0") def test_Equilibrium_creation(self): - equil1 = wntr.quality.EquilibriumDynamics("Cl", wntr.quality.ReactionType.PIPE, "-Ka + Kb * Cl + T0") + equil1 = wntr.msx.EquilibriumDynamics("Cl", wntr.msx.ReactionType.PIPE, "-Ka + Kb * Cl + T0") self.assertEqual(equil1.species, "Cl") self.assertEqual(equil1.expression, "-Ka + Kb * Cl + T0") - self.assertEqual(equil1.dynamics, wntr.quality.DynamicsType.EQUIL) + self.assertEqual(equil1.dynamics, wntr.msx.ExpressionType.EQUIL) def test_Rate_creation(self): - rate1 = wntr.quality.TankReaction("Cl", wntr.quality.ReactionType.TANK, "-Ka + Kb * Cl + T0", note="Foo Bar") + rate1 = wntr.msx.TankReaction("Cl", wntr.msx.ReactionType.TANK, "-Ka + Kb * Cl + T0", note="Foo Bar") self.assertEqual(rate1.species_name, "Cl") self.assertEqual(rate1.expression, "-Ka + Kb * Cl + T0") - self.assertEqual(rate1.dynamics, wntr.quality.DynamicsType.RATE) + self.assertEqual(rate1.dynamics, wntr.msx.ExpressionType.RATE) self.assertEqual(rate1.note, "Foo Bar") def test_Formula_creation(self): - formula1 = wntr.quality.FormulaDynamics("Cl", wntr.quality.ReactionType.PIPE, "-Ka + Kb * Cl + T0") + formula1 = wntr.msx.FormulaDynamics("Cl", wntr.msx.ReactionType.PIPE, "-Ka + Kb * Cl + T0") self.assertEqual(formula1.species, "Cl") self.assertEqual(formula1.expression, "-Ka + Kb * Cl + T0") - self.assertEqual(formula1.dynamics, wntr.quality.DynamicsType.FORMULA) + self.assertEqual(formula1.dynamics, wntr.msx.ExpressionType.FORMULA) def test_WaterQualityReactionsModel_creation_specific_everything(self): - rxn_model1 = wntr.quality.MultispeciesQualityModel() - bulk1 = wntr.quality.Species('b',"Cl", "mg") - wall1 = wntr.quality.Species('w', "ClOH", "mg", 0.01, 0.0001, note="Testing stuff") - const1 = wntr.quality.Constant("Kb", 0.482) - param1 = wntr.quality.Parameter("Ka", 0.482, note="foo") - term1 = wntr.quality.OtherTerm("T0", "-3.2 * Kb * Cl^2", note="bar") - equil1 = wntr.quality.EquilibriumDynamics(bulk1, wntr.quality.ReactionType.PIPE, "-Ka + Kb * Cl + T0") - rate1 = wntr.quality.TankReaction(bulk1, wntr.quality.ReactionType.TANK, "-Ka + Kb * Cl + T0", note="Foo Bar") - formula1 = wntr.quality.FormulaDynamics(wall1, wntr.quality.ReactionType.PIPE, "-Ka + Kb * Cl + T0") + rxn_model1 = wntr.msx.MsxModel() + bulk1 = wntr.msx.Species('b',"Cl", "mg") + wall1 = wntr.msx.Species('w', "ClOH", "mg", 0.01, 0.0001, note="Testing stuff") + const1 = wntr.msx.Constant("Kb", 0.482) + param1 = wntr.msx.Parameter("Ka", 0.482, note="foo") + term1 = wntr.msx.OtherTerm("T0", "-3.2 * Kb * Cl^2", note="bar") + equil1 = wntr.msx.EquilibriumDynamics(bulk1, wntr.msx.ReactionType.PIPE, "-Ka + Kb * Cl + T0") + rate1 = wntr.msx.TankReaction(bulk1, wntr.msx.ReactionType.TANK, "-Ka + Kb * Cl + T0", note="Foo Bar") + formula1 = wntr.msx.FormulaDynamics(wall1, wntr.msx.ReactionType.PIPE, "-Ka + Kb * Cl + T0") bulk2 = rxn_model1.add_bulk_species("Cl", "mg") wall2 = rxn_model1.add_wall_species("ClOH", "mg", 0.01, 0.0001, note="Testing stuff") @@ -211,7 +211,7 @@ def test_WaterQualityReactionsModel_creation_specific_everything(self): param2 = rxn_model1.add_parameter("Ka", 0.482, note="foo") term2 = rxn_model1.add_other_term("T0", "-3.2 * Kb * Cl^2", note="bar") equil2 = rxn_model1.add_pipe_reaction("Cl", "equil", "-Ka + Kb * Cl + T0") - rate2 = rxn_model1.add_tank_reaction("Cl", wntr.quality.DynamicsType.R, "-Ka + Kb * Cl + T0", note="Foo Bar") + rate2 = rxn_model1.add_tank_reaction("Cl", wntr.msx.ExpressionType.R, "-Ka + Kb * Cl + T0", note="Foo Bar") formula2 = rxn_model1.add_reaction("PIPE", "ClOH", "formula", "-Ka + Kb * Cl + T0") self.assertEqual(bulk1, bulk2) self.assertEqual(wall1, wall2) @@ -223,22 +223,22 @@ def test_WaterQualityReactionsModel_creation_specific_everything(self): # self.assertEqual(formula1, formula2) def test_WaterQualityReactionsModel_creation_generic_species_coeffs(self): - bulk1 = wntr.quality.Species('b', "Cl", "mg") - wall1 = wntr.quality.Species(2, "ClOH", "mg", 0.01, 0.0001, note="Testing stuff") - const1 = wntr.quality.Constant("Kb", 0.482) - param1 = wntr.quality.Parameter("Ka", 0.482, note="foo") - term1 = wntr.quality.OtherTerm("T0", "-3.2 * Kb * Cl^2", note="bar") + bulk1 = wntr.msx.Species('b', "Cl", "mg") + wall1 = wntr.msx.Species(2, "ClOH", "mg", 0.01, 0.0001, note="Testing stuff") + const1 = wntr.msx.Constant("Kb", 0.482) + param1 = wntr.msx.Parameter("Ka", 0.482, note="foo") + term1 = wntr.msx.OtherTerm("T0", "-3.2 * Kb * Cl^2", note="bar") - rxn_model2 = wntr.quality.MultispeciesQualityModel() + rxn_model2 = wntr.msx.MsxModel() - self.assertRaises(ValueError, rxn_model2.add_species, wntr.quality.QualityVarType.CONST, "Cl", "mg") + self.assertRaises(ValueError, rxn_model2.add_species, wntr.msx.VariableType.CONST, "Cl", "mg") self.assertRaises(TypeError, rxn_model2.add_coefficient, None, "Kb", 0.482) self.assertRaises(ValueError, rxn_model2.add_coefficient, "Wall", "Kb", 0.482) bulk3 = rxn_model2.add_species("BULK", "Cl", "mg") - wall3 = rxn_model2.add_species(wntr.quality.QualityVarType.WALL, "ClOH", "mg", 0.01, 0.0001, note="Testing stuff") + wall3 = rxn_model2.add_species(wntr.msx.VariableType.WALL, "ClOH", "mg", 0.01, 0.0001, note="Testing stuff") const3 = rxn_model2.add_coefficient("Consolation", "Kb", 0.482) - param3 = rxn_model2.add_coefficient(wntr.quality.QualityVarType.P, "Ka", 0.482, note="foo") + param3 = rxn_model2.add_coefficient(wntr.msx.VariableType.P, "Ka", 0.482, note="foo") self.assertEqual(bulk3, bulk1) self.assertEqual(wall3, wall1) From 0bc2088bbb7738b6bf435ee4e15dd67aa4acd2a2 Mon Sep 17 00:00:00 2001 From: dbhart Date: Mon, 6 Nov 2023 10:06:38 -0700 Subject: [PATCH 35/75] Updates to naming, documentation --- documentation/conf.py | 2 +- wntr/epanet/exceptions.py | 124 +--------- wntr/epanet/msx/enums.py | 36 +-- wntr/epanet/msx/exceptions.py | 84 +------ wntr/epanet/msx/toolkit.py | 39 ++-- wntr/epanet/toolkit.py | 338 ++++++++++++++------------- wntr/epanet/util.py | 22 +- wntr/msx/__init__.py | 19 +- wntr/msx/base.py | 414 ++++++++++++++++++++++------------ wntr/msx/elements.py | 394 +++++++++++++++----------------- wntr/msx/library.py | 144 ++++++------ wntr/msx/model.py | 396 +++++++++++++++++--------------- wntr/msx/options.py | 14 +- 13 files changed, 985 insertions(+), 1041 deletions(-) diff --git a/documentation/conf.py b/documentation/conf.py index 6520b0233..f9eef5dfc 100644 --- a/documentation/conf.py +++ b/documentation/conf.py @@ -108,7 +108,7 @@ # If true, '()' will be appended to :func: etc. cross-reference text. #add_function_parentheses = True -autodoc_type_aliases = {'Literal': 'Literal', 'Name':'Name', 'NameList':'NameList', 'LiteralList':'LiteralList', 'Key':'Key', 'KeyList':'KeyList','Verbatim': 'Verbatim', 'URI': 'URI', 'Date':'Date', 'Range':'Range', 'SeparatedValues':'SeparatedValues'} +autodoc_type_aliases = {'DataFrame': 'pandas DataFrame', 'MsxVariable': ':class:`~wntr.msx.model.MsxVariable`', 'NoteType': ':class:`~wntr.epanet.util.NoteType`'} # If true, the current module name will be prepended to all description # unit titles (such as .. function::). diff --git a/wntr/epanet/exceptions.py b/wntr/epanet/exceptions.py index ede847c16..82ce50f61 100644 --- a/wntr/epanet/exceptions.py +++ b/wntr/epanet/exceptions.py @@ -82,129 +82,7 @@ 309: "cannot save results to report file %s", } """A dictionary of the error codes and their meanings from the EPANET toolkit. - -.. table:: EPANET warnings - - =========== ============================================================================================================================================================================== - *Err No.* *Description* - ----------- ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ - **1-6** **Simulation warnings** - ----------- ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ - 1 At `time`, system hydraulically unbalanced - convergence to a hydraulic solution was not achieved in the allowed number of trials - 2 At `time`, system may be hydraulically unstable - hydraulic convergence was only achieved after the status of all links was held fixed - 3 At `time`, system disconnected - one or more nodes with positive demands were disconnected for all supply sources - 4 At `time`, pumps cannot deliver enough flow or head - one or more pumps were forced to either shut down (due to insufficient head) or operate beyond the maximum rated flow - 5 At `time`, valves cannot deliver enough flow - one or more flow control valves could not deliver the required flow even when fully open - 6 At `time`, system has negative pressures - negative pressures occurred at one or more junctions with positive demand - =========== ============================================================================================================================================================================== - -.. table:: EPANET runtime errors - - =========== ================================================================= - *Err No.* *Description* - ----------- ----------------------------------------------------------------- - **101-120** **Runtime and simulation errors** - ----------- ----------------------------------------------------------------- - 101 insufficient memory available - 102 no network data available - 103 hydraulics not initialized - 104 no hydraulics for water quality analysis - 105 water quality not initialized - 106 no results saved to report on - 107 hydraulics supplied from external file - 108 cannot use external file while hydraulics solver is active - 109 cannot change time parameter when solver is active - 110 cannot solve network hydraulic equations - 120 cannot solve water quality transport equations - =========== ================================================================= - -.. table:: EPANET network errors - - =========== ================================================================= - *Err No.* *Description* - ----------- ----------------------------------------------------------------- - **200-201** **Input file errors (exclusively for input files)** - ----------- ----------------------------------------------------------------- - 200 one or more errors in input file - 201 syntax error - ----------- ----------------------------------------------------------------- - **202-222** **Input file and toolkit errors** - ----------- ----------------------------------------------------------------- - 202 illegal numeric value - 203 undefined node - 204 undefined link - 205 undefined time pattern - 206 undefined curve - 207 attempt to control a CV/GPV link - 208 illegal PDA pressure limits - 209 illegal node property value - 211 illegal link property value - 212 undefined trace node - 213 invalid option value - 214 too many characters in input line - 215 duplicate ID label - 216 reference to undefined pump - 217 pump has no head curve or power defined - 218 `note: error number 218 is undefined in the EPANET 2.2 toolkit` - 219 illegal valve connection to tank node - 220 illegal valve connection to another valve - 221 misplaced rule clause in rule-based control - 222 link assigned same start and end nodes - ----------- ----------------------------------------------------------------- - **223-234** **Network consistency errors (INP-file and/or toolkit)** - ----------- ----------------------------------------------------------------- - 223 not enough nodes in network - 224 no tanks or reservoirs in network - 225 invalid lower/upper levels for tank - 226 no head curve or power rating for pump - 227 invalid head curve for pump - 230 nonincreasing x-values for curve - 233 network has unconnected node - 234 network has an unconnected node with ID `id` - ----------- ----------------------------------------------------------------- - **240-263** **Toolkit-only errors** - ----------- ----------------------------------------------------------------- - 240 nonexistent water quality source - 241 nonexistent control - 250 invalid format (e.g. too long an ID name) - 251 invalid parameter code - 252 invalid ID name - 253 nonexistent demand category - 254 node with no coordinates - 255 invalid link vertex - 257 nonexistent rule - 258 nonexistent rule clause - 259 attempt to delete a node that still has links connected to it - 260 attempt to delete node assigned as a Trace Node - 261 attempt to delete a node or link contained in a control - 262 attempt to modify network structure while a solver is open - 263 node is not a tank - =========== ================================================================= - -.. table:: EPANET file/system errors - - =========== ================================================================= - *Err No.* *Description* - ----------- ----------------------------------------------------------------- - **301-305** **Filename errors** - ----------- ----------------------------------------------------------------- - 301 identical file names used for different types of files - 302 cannot open input file - 303 cannot open report file - 304 cannot open binary output file - 305 cannot open hydraulics file - ----------- ----------------------------------------------------------------- - **306-307** **File structure errors** - ----------- ----------------------------------------------------------------- - 306 hydraulics file does not match network data - 307 cannot read hydraulics file - ----------- ----------------------------------------------------------------- - **308-309** **Filesystem errors** - ----------- ----------------------------------------------------------------- - 308 cannot save results to binary file - 309 cannot save results to report file - =========== ================================================================= - +Please see :doc:`/errors` for a tables of these values. :meta hide-value: """ diff --git a/wntr/epanet/msx/enums.py b/wntr/epanet/msx/enums.py index 6a94ca483..e2a77fead 100644 --- a/wntr/epanet/msx/enums.py +++ b/wntr/epanet/msx/enums.py @@ -4,7 +4,7 @@ from wntr.utils.enumtools import add_get @add_get(prefix='MSX_') -class ObjectType(IntEnum): +class TkObjectType(IntEnum): """The enumeration for object type used in EPANET-MSX. .. warning:: These enum values start with 0. @@ -47,7 +47,7 @@ class ObjectType(IntEnum): @add_get(prefix='MSX_') -class SourceType(IntEnum): +class TkSourceType(IntEnum): """The enumeration for source type used in EPANET-MSX. .. warning:: These enum values start with -1. @@ -77,7 +77,7 @@ class SourceType(IntEnum): @add_get(prefix='MSX_') -class UnitSystemType(IntEnum): +class TkUnitSystem(IntEnum): """The enumeration for the units system used in EPANET-MSX. .. warning:: These enum values start with 0. @@ -98,7 +98,7 @@ class UnitSystemType(IntEnum): @add_get(prefix='MSX_') -class FlowUnitsType(IntEnum): +class TkFlowUnits(IntEnum): """The enumeration for the flow units used in EPANET-MSX (determined from EPANET INP file read in with the toolkit). .. warning:: These enum values start with 0. @@ -143,7 +143,7 @@ class FlowUnitsType(IntEnum): @add_get(prefix='MSX_') -class MixType(IntEnum): +class TkMixType(IntEnum): """The enumeration for the mixing model used in EPANET-MSX. .. warning:: These enum values start with 0. @@ -170,7 +170,7 @@ class MixType(IntEnum): @add_get(prefix='MSX_') -class SpeciesType(IntEnum): +class TkSpeciesType(IntEnum): """The enumeration for species type used in EPANET-MSX. .. warning:: These enum values start with 0. @@ -191,7 +191,7 @@ class SpeciesType(IntEnum): @add_get(prefix='MSX_') -class ExpressionType(IntEnum): +class TkExpressionType(IntEnum): """The enumeration for the expression type used in EPANET-MSX. .. warning:: These enum values start with 0. @@ -218,7 +218,7 @@ class ExpressionType(IntEnum): @add_get(prefix='MSX_') -class SolverType(IntEnum): +class TkSolverType(IntEnum): """The enumeration for the solver type used in EPANET-MSX. .. warning:: These enum values start with 0. @@ -242,7 +242,7 @@ class SolverType(IntEnum): @add_get(prefix='MSX_') -class CouplingType(IntEnum): +class TkCouplingType(IntEnum): """The enumeration for the coupling type option used in EPANET-MSX. .. warning:: These enum values start with 0. @@ -263,7 +263,7 @@ class CouplingType(IntEnum): @add_get(prefix='MSX_') -class MassUnitsType(IntEnum): +class TkMassUnits(IntEnum): """The enumeration for mass units used in EPANET-MSX. .. warning:: These enum values start with 0. @@ -290,7 +290,7 @@ class MassUnitsType(IntEnum): @add_get(prefix='MSX_') -class AreaUnitsType(IntEnum): +class TkAreaUnits(IntEnum): """The enumeration for area units used in EPANET-MSX. .. warning:: These enum values start with 0. @@ -314,7 +314,7 @@ class AreaUnitsType(IntEnum): @add_get(prefix='MSX_') -class RateUnitsType(IntEnum): +class TkRateUnits(IntEnum): """The enumeration for rate units used in EPANET-MSX. .. warning:: These enum values start with 0. @@ -341,7 +341,7 @@ class RateUnitsType(IntEnum): @add_get(prefix='MSX_') -class UnitsType(IntEnum): +class TkUnits(IntEnum): """The position for units used in EPANET-MSX. .. warning:: These enum values start with 0. @@ -378,7 +378,7 @@ class UnitsType(IntEnum): @add_get(prefix='MSX_') -class HydVarType(IntEnum): +class TkHydVar(IntEnum): """The enumeration for hydraulic variable used in EPANET-MSX. .. warning:: These enum values start with 0. @@ -421,7 +421,7 @@ class HydVarType(IntEnum): @add_get(prefix='MSX_') -class TstatType(IntEnum): +class TkTstat(IntEnum): """The enumeration used for time statistic in EPANET-MSX. .. warning:: These enum values start with 0. @@ -451,7 +451,7 @@ class TstatType(IntEnum): @add_get(prefix='MSX_') -class OptionType(IntEnum): +class TkOption(IntEnum): """The enumeration used for choosing an option in EPANET-MSX toolkit. .. warning:: These enum values start with 0. @@ -496,7 +496,7 @@ class OptionType(IntEnum): @add_get(prefix='MSX_') -class CompilerType(IntEnum): +class TkCompiler(IntEnum): """The enumeration used for specifying compiler options in EPANET-MSX. .. warning:: These enum values start with 0. @@ -520,7 +520,7 @@ class CompilerType(IntEnum): @add_get(prefix='MSX_') -class FileModeType(IntEnum): +class TkFileMode(IntEnum): """The enumeration for file model used in EPANET-MSX. .. warning:: These enum values start with 0. diff --git a/wntr/epanet/msx/exceptions.py b/wntr/epanet/msx/exceptions.py index 0faeeac71..2ed33e506 100644 --- a/wntr/epanet/msx/exceptions.py +++ b/wntr/epanet/msx/exceptions.py @@ -52,82 +52,6 @@ :meta hide-value: """ - -@add_get(prefix="ERR_") -class MsxErrorEnum(IntEnum): - """The EPANET-MSX input and toolkit error numbers, keys, and descriptions. - """ - - MAX_CHARS = 401 - "too many characters" - NUM_ITEMS = 402 - "too few input items" - INVALID_KEYWORD = 403 - "invalid keyword" - INVALID_NUMBER = 404 - "invalid numeric value" - UNDEFINED_OBJECT_TYPE = 405 - "reference to undefined object" - RESERVED_NAME = 406 - "illegal use of reserved name" - NAME = 407 - "name already used by another object" - SPECIES_EXPR = 408 - "species already assigned an expression" - ILLEGAL_MATH_EXPR = 409 - "illegal math expression" - DEPRECATED = 410 - "option no longer supported" - CYCLIC_REFERENCE = 411 - "term contains a cyclic reference" - MEMORY = 501 - "insufficient memory available" - NO_EPANET_FILE = 502 - "no EPANET data file supplied" - OPEN_MSX_FILE = 503 - "could not open MSX input file" - OPEN_HYD_FILE = 504 - "could not open hydraulic results file" - READ_HYD_FILE = 505 - "could not read hydraulic results file" - MSX_INPUT = 506 - "could not read MSX input file" - NUM_PIPE_EXPR = 507 - "too few pipe reaction expressions" - NUM_TANK_EXPR = 508 - "too few tank reaction expressions" - INTEGRATOR_OPEN = 509 - """could not open differential equation solver""" - NEWTON_OPEN = 510 - "could not open algebraic equation solver" - OPEN_OUT_FILE = 511 - """could not open binary results file""" - IO_OUT_FILE = 512 - """read/write error on binary results file""" - INTEGRATION = 513 - """could not integrate reaction rate expressions""" - NEWTON = 514 - """could not solve reaction equilibrium expressions""" - INVALID_OBJECT_TYPE = 515 - """reference made to an unknown type of object""" - INVALID_OBJECT_INDEX = 516 - """reference made to an illegal object index""" - UNDEFINED_OBJECT_ID = 517 - """reference made to an undefined object ID""" - INVALID_OBJECT_PARAMS = 518 - """invalid property values were specified""" - MSX_NOT_OPENED = 519 - """an MSX project was not opened""" - MSX_OPENED = 520 - """an MSX project is already opened""" - COMPILE_FAILED = 522 - """could not compile chemistry functions""" - COMPLED_LOAD = 523 - """could not load functions from compiled chemistry file""" - ILLEGAL_MATH = 524 - """illegal math operation""" - - class EpanetMsxException(EpanetException): def __init__(self, code: int, *args: List[object], line_num=None, line=None) -> None: """An Exception class for EPANET-MSX Toolkit and IO exceptions. @@ -144,13 +68,9 @@ def __init__(self, code: int, *args: List[object], line_num=None, line=None) -> line : str, optional The contents of the line, by default None """ - try: - code = MsxErrorEnum.get(code) - except: - return super().__init__(code, *args, line_num=line_num, line=line) - if int(code) < 400: + if not code or int(code) < 400: return super().__init__(code, *args, line_num=line_num, line=line) - msg = MSX_ERROR_CODES.get(code, "unknown error") + msg = MSX_ERROR_CODES.get(code, "unknown MSX error number {}".format(code)) if args is not None: args = [*args] if r"%" in msg and len(args) > 0: diff --git a/wntr/epanet/msx/toolkit.py b/wntr/epanet/msx/toolkit.py index 84fdcd9f2..b45056d47 100644 --- a/wntr/epanet/msx/toolkit.py +++ b/wntr/epanet/msx/toolkit.py @@ -8,7 +8,6 @@ licensed under the BSD license. See LICENSE.txt for details. """ import ctypes -from enum import IntEnum import os import os.path import platform @@ -18,11 +17,11 @@ from pkg_resources import resource_filename -from wntr.epanet.msx.enums import ObjectType, SourceType +from wntr.epanet.msx.enums import TkObjectType, TkSourceType from ..toolkit import ENepanet from ..util import SizeLimits -from .exceptions import EpanetMsxException, MSX_ERROR_CODES, MSXKeyError, MSXValueError +from .exceptions import MSX_ERROR_CODES, EpanetMsxException, MSXKeyError, MSXValueError epanet_toolkit = "wntr.epanet.toolkit" @@ -216,7 +215,7 @@ def MSXreport(self): raise EpanetMsxException(ierr) # ---------get parameters--------------------------------------------------------------- - def MSXgetindex(self, _type: Union[int, ObjectType], name): + def MSXgetindex(self, _type: Union[int, TkObjectType], name): """Retrieves the internal index of an MSX object given its name. Parameters @@ -239,7 +238,7 @@ def MSXgetindex(self, _type: Union[int, ObjectType], name): if _type is not a valid MSX object type """ try: - _type = ObjectType.get(_type) + _type = TkObjectType.get(_type) except KeyError: raise MSXKeyError(515, repr(_type)) type_ind = int(_type) @@ -265,7 +264,7 @@ def MSXgetIDlen(self, _type, index): the length of the object ID """ try: - _type = ObjectType.get(_type) + _type = TkObjectType.get(_type) except KeyError: raise MSXKeyError(515, repr(_type)) type_ind = int(_type) @@ -291,7 +290,7 @@ def MSXgetID(self, _type, index): the object ID """ try: - _type = ObjectType.get(_type) + _type = TkObjectType.get(_type) except KeyError: raise MSXKeyError(515, repr(_type)) type_ind = int(_type) @@ -331,10 +330,10 @@ def MSXgetinitqual(self, _type, node_link_index, species_index): any other error from the C-API """ try: - _type = ObjectType.get(_type) + _type = TkObjectType.get(_type) except KeyError: raise MSXKeyError(515, repr(_type)) - if _type not in [ObjectType.NODE, ObjectType.LINK]: + if _type not in [TkObjectType.NODE, TkObjectType.LINK]: raise MSXValueError(515, repr(_type)) type_ind = int(_type) iniqual = ctypes.c_double() @@ -370,10 +369,10 @@ def MSXgetqual(self, _type, node_link_index, species_index): any other error from the C-API """ try: - _type = ObjectType.get(_type) + _type = TkObjectType.get(_type) except KeyError: raise MSXKeyError(515, repr(_type)) - if _type not in [ObjectType.NODE, ObjectType.LINK]: + if _type not in [TkObjectType.NODE, TkObjectType.LINK]: raise MSXValueError(515, repr(_type)) type_ind = int(_type) qual = ctypes.c_double() @@ -433,10 +432,10 @@ def MSXgetparameter(self, _type, node_link_index, param_index): _description_ """ try: - _type = ObjectType.get(_type) + _type = TkObjectType.get(_type) except KeyError: raise MSXKeyError(515, repr(_type)) - if _type not in [ObjectType.NODE, ObjectType.LINK]: + if _type not in [TkObjectType.NODE, TkObjectType.LINK]: raise MSXValueError(515, repr(_type)) type_ind = int(_type) param = ctypes.c_double() @@ -456,7 +455,7 @@ def MSXgetsource(self, node_index, species_index): ierr = self.ENlib.MSXgetsource(ctypes.c_int(node_index), ctypes.c_int(species_index), ctypes.byref(_type), ctypes.byref(level), ctypes.byref(pat)) if ierr != 0: raise EpanetMsxException(ierr, repr(dict(node_index=node_index, species_index=species_index))) - src_out = [SourceType.get(_type.value), level.value, pat.value] + src_out = [TkSourceType.get(_type.value), level.value, pat.value] return src_out def MSXgetpatternlen(self, pat): @@ -530,7 +529,7 @@ def MSXgetcount(self, _type): _description_ """ try: - _type = ObjectType.get(_type) + _type = TkObjectType.get(_type) except KeyError: raise MSXKeyError(515, repr(_type)) type_ind = int(_type) @@ -633,10 +632,10 @@ def MSXsetparameter(self, _type, ind, param, value): _description_ """ try: - _type = ObjectType.get(_type) + _type = TkObjectType.get(_type) except KeyError: raise MSXKeyError(515, repr(_type)) - if _type not in [ObjectType.NODE, ObjectType.LINK]: + if _type not in [TkObjectType.NODE, TkObjectType.LINK]: raise MSXValueError(515, repr(_type)) type_ind = int(_type) ierr = self.ENlib.MSXsetparameter(ctypes.c_int(type_ind), ctypes.c_int(ind), ctypes.c_int(param), ctypes.c_double(value)) @@ -668,10 +667,10 @@ def MSXsetinitqual(self, _type, ind, spe, value): _description_ """ try: - _type = ObjectType.get(_type) + _type = TkObjectType.get(_type) except KeyError: raise MSXKeyError(515, repr(_type)) - if _type not in [ObjectType.NODE, ObjectType.LINK]: + if _type not in [TkObjectType.NODE, TkObjectType.LINK]: raise MSXValueError(515, repr(_type)) type_ind = int(_type) ierr = self.ENlib.MSXsetinitqual(ctypes.c_int(type_ind), ctypes.c_int(ind), ctypes.c_int(spe), ctypes.c_double(value)) @@ -702,7 +701,7 @@ def MSXsetsource(self, node, spe, _type, level, pat): _description_ """ try: - _type = SourceType.get(_type) + _type = TkSourceType.get(_type) except KeyError: raise MSXKeyError(515, repr(_type)) type_ind = int(_type) diff --git a/wntr/epanet/toolkit.py b/wntr/epanet/toolkit.py index 21ffb67a5..c368e2a28 100644 --- a/wntr/epanet/toolkit.py +++ b/wntr/epanet/toolkit.py @@ -13,14 +13,20 @@ """ import ctypes +import logging import os import os.path import platform import sys from ctypes import byref -from .util import SizeLimits + from pkg_resources import resource_filename +from .exceptions import EN_ERROR_CODES, EpanetException +from .util import SizeLimits + +logger = logging.getLogger(__name__) + epanet_toolkit = "wntr.epanet.toolkit" if os.name in ["nt", "dos"]: @@ -30,15 +36,6 @@ else: libepanet = resource_filename(__name__, "Linux/libepanet2.so") -import logging - -logger = logging.getLogger(__name__) - - -# import warnings - -from .exceptions import EpanetException, EN_ERROR_CODES - def ENgetwarning(code, sec=-1): if sec >= 0: @@ -50,20 +47,20 @@ def ENgetwarning(code, sec=-1): else: header = "{}".format(code) if code < 100: - msg = EN_ERROR_CODES.get(code, 'Unknown warning %s') + msg = EN_ERROR_CODES.get(code, "Unknown warning %s") else: raise EpanetException(code) - + return msg % header + def runepanet(inpfile, rptfile=None, binfile=None): """Run an EPANET command-line simulation - + Parameters ---------- inpfile : str The input file name - """ file_prefix, file_ext = os.path.splitext(inpfile) if rptfile is None: @@ -98,11 +95,9 @@ class ENepanet: Results file to generate version : float EPANET version to use (either 2.0 or 2.2) - """ def __init__(self, inpfile="", rptfile="", binfile="", version=2.2): - self.ENlib = None self.errcode = 0 self.errcodelist = [] @@ -127,19 +122,13 @@ def __init__(self, inpfile="", rptfile="", binfile="", version=2.2): for lib in libnames: try: if os.name in ["nt", "dos"]: - libepanet = resource_filename( - epanet_toolkit, "Windows/%s.dll" % lib - ) + libepanet = resource_filename(epanet_toolkit, "Windows/%s.dll" % lib) self.ENlib = ctypes.windll.LoadLibrary(libepanet) elif sys.platform in ["darwin"]: - libepanet = resource_filename( - epanet_toolkit, "Darwin/lib%s.dylib" % lib - ) + libepanet = resource_filename(epanet_toolkit, "Darwin/lib%s.dylib" % lib) self.ENlib = ctypes.cdll.LoadLibrary(libepanet) else: - libepanet = resource_filename( - epanet_toolkit, "Linux/lib%s.so" % lib - ) + libepanet = resource_filename(epanet_toolkit, "Linux/lib%s.so" % lib) self.ENlib = ctypes.cdll.LoadLibrary(libepanet) return except Exception as E1: @@ -147,7 +136,7 @@ def __init__(self, inpfile="", rptfile="", binfile="", version=2.2): raise E1 pass finally: - if version >= 2.2 and '32' not in lib: + if version >= 2.2 and "32" not in lib: self._project = ctypes.c_uint64() elif version >= 2.2: self._project = ctypes.c_uint32() @@ -164,8 +153,8 @@ def _error(self, *args): if not self.errcode: return # errtxt = self.ENlib.ENgeterror(self.errcode) - errtext = EN_ERROR_CODES.get(self.errcode, 'unknown error') - if '%' in errtext and len(args) == 1: + errtext = EN_ERROR_CODES.get(self.errcode, "unknown error") + if "%" in errtext and len(args) == 1: errtext % args if self.errcode >= 100: self.Errflag = True @@ -174,7 +163,7 @@ def _error(self, *args): else: self.Warnflag = True # warnings.warn(ENgetwarning(self.errcode)) - logger.warning('EPANET warning {} - {}'.format(self.errcode, ENgetwarning(self.errcode, self.cur_time))) + logger.warning("EPANET warning {} - {}".format(self.errcode, ENgetwarning(self.errcode, self.cur_time))) self.errcodelist.append(ENgetwarning(self.errcode, self.cur_time)) return @@ -190,7 +179,6 @@ def ENopen(self, inpfile=None, rptfile=None, binfile=None): Output file to create (default to constructor value) binfile : str Binary output file to create (default to constructor value) - """ if self._project is not None: if self.fileLoaded: @@ -260,7 +248,6 @@ def ENsaveH(self): Must be called before ENreport() if no water quality simulation made. Should not be called if ENsolveQ() will be used. - """ if self._project is not None: self.errcode = self.ENlib.EN_saveH(self._project) @@ -288,7 +275,6 @@ def ENinitH(self, iFlag): if link flows should be re-initialized (1) or not (0) and 2nd digit indicates if hydraulic results should be saved to file (1) or not (0) - """ if self._project is not None: self.errcode = self.ENlib.EN_initH(self._project, iFlag) @@ -299,16 +285,15 @@ def ENinitH(self, iFlag): def ENrunH(self): """Solves hydraulics for conditions at time t - + This function is used in a loop with ENnextH() to run an extended period hydraulic simulation. See ENsolveH() for an example. - + Returns -------- int Current simulation time (seconds) - """ lT = ctypes.c_long() if self._project is not None: @@ -321,16 +306,15 @@ def ENrunH(self): def ENnextH(self): """Determines time until next hydraulic event - + This function is used in a loop with ENrunH() to run an extended period hydraulic simulation. See ENsolveH() for an example. - + Returns --------- int Time (seconds) until next hydraulic event (0 marks end of simulation period) - """ lTstep = ctypes.c_long() if self._project is not None: @@ -356,7 +340,6 @@ def ENsavehydfile(self, filename): ------------- filename : str Name of hydraulics file to output - """ if self._project is not None: self.errcode = self.ENlib.EN_savehydfile(self._project, filename.encode("latin-1")) @@ -372,7 +355,6 @@ def ENusehydfile(self, filename): ------------- filename : str Name of hydraulics file to use - """ if self._project is not None: self.errcode = self.ENlib.EN_usehydfile(self._project, filename.encode("latin-1")) @@ -406,7 +388,6 @@ def ENinitQ(self, iSaveflag): ------------- iSaveflag : int EN_SAVE (1) if results saved to file, EN_NOSAVE (0) if not - """ if self._project is not None: self.errcode = self.ENlib.EN_initQ(self._project, iSaveflag) @@ -417,16 +398,15 @@ def ENinitQ(self, iSaveflag): def ENrunQ(self): """Retrieves hydraulic and water quality results at time t - + This function is used in a loop with ENnextQ() to run an extended period water quality simulation. See ENsolveQ() for an example. - + Returns ------- int Current simulation time (seconds) - """ lT = ctypes.c_long() if self._project is not None: @@ -442,12 +422,11 @@ def ENnextQ(self): This function is used in a loop with ENrunQ() to run an extended period water quality simulation. See ENsolveQ() for an example. - + Returns -------- int Time (seconds) until next hydraulic event (0 marks end of simulation period) - """ lTstep = ctypes.c_long() if self._project is not None: @@ -487,7 +466,7 @@ def ENgetcount(self, iCode): --------- int Number of components in network - + """ iCount = ctypes.c_int() if self._project is not None: @@ -503,7 +482,7 @@ def ENgetflowunits(self): Returns ----------- Code of flow units in use (see toolkit.optFlowUnits) - + """ iCode = ctypes.c_int() if self._project is not None: @@ -513,6 +492,27 @@ def ENgetflowunits(self): self._error() return iCode.value + def ENgetnodeid(self, iIndex): + """Gets the ID name of a node given its index. + + Parameters + ---------- + iIndex : int + a node's index (starting from 1). + + Returns + ------- + str + the node name + """ + fValue = ctypes.create_string_buffer(SizeLimits.EN_MAX_ID.value) + if self._project is not None: + self.errcode = self.ENlib.EN_getnodeid(self._project, iIndex, byref(fValue)) + else: + self.errcode = self.ENlib.ENgetnodeid(iIndex, byref(fValue)) + self._error() + return str(fValue.value, "UTF-8") + def ENgetnodeindex(self, sId): """Retrieves index of a node with specific ID @@ -524,7 +524,7 @@ def ENgetnodeindex(self, sId): Returns --------- Index of node in list of nodes - + """ iIndex = ctypes.c_int() if self._project is not None: @@ -534,9 +534,29 @@ def ENgetnodeindex(self, sId): self._error() return iIndex.value - def ENgetnodevalue(self, iIndex, iCode): + def ENgetnodetype(self, iIndex): + """Retrieves a node's type given its index. + + Parameters + ---------- + iIndex : int + The index of the node + + Returns + ------- + int + the node type as an integer """ - Retrieves parameter value for a node + fValue = ctypes.c_int() + if self._project is not None: + self.errcode = self.ENlib.EN_getnodetype(self._project, iIndex, byref(fValue)) + else: + self.errcode = self.ENlib.ENgetnodetype(iIndex, byref(fValue)) + self._error() + return fValue.value + + def ENgetnodevalue(self, iIndex, iCode): + """Retrieves parameter value for a node Parameters ------------- @@ -559,6 +579,27 @@ def ENgetnodevalue(self, iIndex, iCode): self._error() return fValue.value + def ENgetlinktype(self, iIndex): + """Retrieves a link's type given its index. + + Parameters + ---------- + iIndex : int + The index of the link + + Returns + ------- + int + the link type as an integer + """ + fValue = ctypes.c_int() + if self._project is not None: + self.errcode = self.ENlib.EN_getlinktype(self._project, iIndex, byref(fValue)) + else: + self.errcode = self.ENlib.EN_getlinktype(iIndex, byref(fValue)) + self._error() + return fValue.value + def ENgetlinkindex(self, sId): """Retrieves index of a link with specific ID @@ -605,8 +646,7 @@ def ENgetlinkvalue(self, iIndex, iCode): return fValue.value def ENsetlinkvalue(self, iIndex, iCode, fValue): - """ - Set the value on a link + """Set the value on a link Parameters ---------- @@ -618,13 +658,11 @@ def ENsetlinkvalue(self, iIndex, iCode, fValue): the value to set on the link """ if self._project is not None: - self.errcode = self.ENlib.EN_setlinkvalue(self._project, - ctypes.c_int(iIndex), ctypes.c_int(iCode), ctypes.c_double(fValue) + self.errcode = self.ENlib.EN_setlinkvalue( + self._project, ctypes.c_int(iIndex), ctypes.c_int(iCode), ctypes.c_double(fValue) ) else: - self.errcode = self.ENlib.ENsetlinkvalue( - ctypes.c_int(iIndex), ctypes.c_int(iCode), ctypes.c_float(fValue) - ) + self.errcode = self.ENlib.ENsetlinkvalue(ctypes.c_int(iIndex), ctypes.c_int(iCode), ctypes.c_float(fValue)) self._error() def ENsetnodevalue(self, iIndex, iCode, fValue): @@ -641,18 +679,15 @@ def ENsetnodevalue(self, iIndex, iCode, fValue): the value to set on the node """ if self._project is not None: - self.errcode = self.ENlib.EN_setnodevalue(self._project, - ctypes.c_int(iIndex), ctypes.c_int(iCode), ctypes.c_double(fValue) + self.errcode = self.ENlib.EN_setnodevalue( + self._project, ctypes.c_int(iIndex), ctypes.c_int(iCode), ctypes.c_double(fValue) ) else: - self.errcode = self.ENlib.ENsetnodevalue( - ctypes.c_int(iIndex), ctypes.c_int(iCode), ctypes.c_float(fValue) - ) + self.errcode = self.ENlib.ENsetnodevalue(ctypes.c_int(iIndex), ctypes.c_int(iCode), ctypes.c_float(fValue)) self._error() def ENsettimeparam(self, eParam, lValue): - """ - Set a time parameter value + """Set a time parameter value Parameters ---------- @@ -662,18 +697,13 @@ def ENsettimeparam(self, eParam, lValue): the value to set, in seconds """ if self._project is not None: - self.errcode = self.ENlib.EN_settimeparam( - self._project, ctypes.c_int(eParam), ctypes.c_long(lValue) - ) + self.errcode = self.ENlib.EN_settimeparam(self._project, ctypes.c_int(eParam), ctypes.c_long(lValue)) else: - self.errcode = self.ENlib.ENsettimeparam( - ctypes.c_int(eParam), ctypes.c_long(lValue) - ) + self.errcode = self.ENlib.ENsettimeparam(ctypes.c_int(eParam), ctypes.c_long(lValue)) self._error() def ENgettimeparam(self, eParam): - """ - Get a time parameter value + """Get a time parameter value Parameters ---------- @@ -687,69 +717,63 @@ def ENgettimeparam(self, eParam): """ lValue = ctypes.c_long() if self._project is not None: - self.errcode = self.ENlib.EN_gettimeparam( - self._project, ctypes.c_int(eParam), byref(lValue) - ) + self.errcode = self.ENlib.EN_gettimeparam(self._project, ctypes.c_int(eParam), byref(lValue)) else: - self.errcode = self.ENlib.ENgettimeparam( - ctypes.c_int(eParam), byref(lValue) - ) + self.errcode = self.ENlib.ENgettimeparam(ctypes.c_int(eParam), byref(lValue)) self._error() return lValue.value def ENaddcontrol(self, iType: int, iLinkIndex: int, dSetting: float, iNodeIndex: int, dLevel: float) -> int: - """ - Add a new simple control + """Add a new simple control Parameters ---------- iType : int - _description_ + the type of control iLinkIndex : int - _description_ + the index of the link dSetting : float - _description_ + the new link setting value iNodeIndex : int Set to 0 for time of day or timer dLevel : float - _description_ + the level to compare against Returns ------- int - _description_ + the new control number """ lValue = ctypes.c_int() if self._project is not None: self.errcode = self.ENlib.EN_addcontrol( - self._project, - ctypes.c_int(iType), - ctypes.c_int(iLinkIndex), - ctypes.c_double(dSetting), - ctypes.c_int(iNodeIndex), + self._project, + ctypes.c_int(iType), + ctypes.c_int(iLinkIndex), + ctypes.c_double(dSetting), + ctypes.c_int(iNodeIndex), ctypes.c_double(dLevel), - byref(lValue) + byref(lValue), ) else: self.errcode = self.ENlib.ENaddcontrol( - ctypes.c_int(iType), - ctypes.c_int(iLinkIndex), - ctypes.c_double(dSetting), - ctypes.c_int(iNodeIndex), + ctypes.c_int(iType), + ctypes.c_int(iLinkIndex), + ctypes.c_double(dSetting), + ctypes.c_int(iNodeIndex), ctypes.c_double(dLevel), - byref(lValue) + byref(lValue), ) self._error() return lValue.value def ENgetcontrol(self, iIndex: int): - """ - Add a new simple control + """Get values defined by a control. Parameters ---------- iIndex : int - _description_ + the control number """ iType = ctypes.c_int() iLinkIndex = ctypes.c_int() @@ -758,111 +782,99 @@ def ENgetcontrol(self, iIndex: int): dLevel = ctypes.c_double() if self._project is not None: self.errcode = self.ENlib.EN_getcontrol( - self._project, - ctypes.c_int(iIndex), + self._project, + ctypes.c_int(iIndex), byref(iType), - byref(iLinkIndex), - byref(dSetting), - byref(iNodeIndex), - byref(dLevel) + byref(iLinkIndex), + byref(dSetting), + byref(iNodeIndex), + byref(dLevel), ) else: self.errcode = self.ENlib.ENgetcontrol( - ctypes.c_int(iIndex), - byref(iType), - byref(iLinkIndex), - byref(dSetting), - byref(iNodeIndex), - byref(dLevel) + ctypes.c_int(iIndex), byref(iType), byref(iLinkIndex), byref(dSetting), byref(iNodeIndex), byref(dLevel) ) self._error() - return dict(index=iIndex, type=iType.value, linkindex=iLinkIndex.value, setting=dSetting.value, nodeindex=iNodeIndex.value, level=dLevel.value) + return dict( + index=iIndex, + type=iType.value, + linkindex=iLinkIndex.value, + setting=dSetting.value, + nodeindex=iNodeIndex.value, + level=dLevel.value, + ) def ENsetcontrol(self, iIndex: int, iType: int, iLinkIndex: int, dSetting: float, iNodeIndex: int, dLevel: float): - """ - Add a new simple control + """Change values on a simple control Parameters ---------- iIndex : int - _description_ + the control index iType : int - _description_ + the type of control comparison iLinkIndex : int - _description_ + the link being changed dSetting : float - _description_ + the setting to change to iNodeIndex : int - Set to 0 for time of day or timer + the node being compared against, Set to 0 for time of day or timer dLevel : float - _description_ + the level being checked Warning - ------- - There is an error in EPANET 2.2 that sets the :param:`dLevel` to 0.0 on Macs + ------- + There is an error in EPANET 2.2 that sets the `dLevel` parameter to 0.0 on Macs regardless of the value the user passes in. This means that to use this toolkit functionality on a Mac, the user must delete and create a new control to change the level. - + """ if self._project is not None: try: self.errcode = self.ENlib.EN_setcontrol( - self._project, - ctypes.c_int(iIndex), - ctypes.c_int(iType), - ctypes.c_int(iLinkIndex), - ctypes.c_double(dSetting), - ctypes.c_int(iNodeIndex), - ctypes.c_double(dLevel) + self._project, + ctypes.c_int(iIndex), + ctypes.c_int(iType), + ctypes.c_int(iLinkIndex), + ctypes.c_double(dSetting), + ctypes.c_int(iNodeIndex), + ctypes.c_double(dLevel), ) except: self.errcode = self.ENlib.EN_setcontrol( - self._project, - ctypes.c_int(iIndex), - ctypes.c_int(iType), - ctypes.c_int(iLinkIndex), - ctypes.c_double(dSetting), - ctypes.c_int(iNodeIndex), - ctypes.c_float(dLevel) + self._project, + ctypes.c_int(iIndex), + ctypes.c_int(iType), + ctypes.c_int(iLinkIndex), + ctypes.c_double(dSetting), + ctypes.c_int(iNodeIndex), + ctypes.c_float(dLevel), ) else: self.errcode = self.ENlib.ENsetcontrol( - ctypes.c_int(iIndex), - ctypes.c_int(iType), - ctypes.c_int(iLinkIndex), - ctypes.c_double(dSetting), - ctypes.c_int(iNodeIndex), - ctypes.c_double(dLevel) + ctypes.c_int(iIndex), + ctypes.c_int(iType), + ctypes.c_int(iLinkIndex), + ctypes.c_double(dSetting), + ctypes.c_int(iNodeIndex), + ctypes.c_double(dLevel), ) self._error() def ENdeletecontrol(self, iControlIndex): - """ - Get a time parameter value + """Delete a control. Parameters ---------- iControlIndex : int - the time parameter to get - - Returns - ------- - int - the index of the new control + the simple control to delete """ - lValue = ctypes.c_long() if self._project is not None: - self.errcode = self.ENlib.EN_deletecontrol( - self._project, - ctypes.c_int(iControlIndex) - ) + self.errcode = self.ENlib.EN_deletecontrol(self._project, ctypes.c_int(iControlIndex)) else: - self.errcode = self.ENlib.ENdeletecontrol( - ctypes.c_int(iControlIndex) - ) + self.errcode = self.ENlib.ENdeletecontrol(ctypes.c_int(iControlIndex)) self._error() - return lValue.value def ENsaveinpfile(self, inpfile): """Saves EPANET input file @@ -870,7 +882,7 @@ def ENsaveinpfile(self, inpfile): Parameters ------------- inpfile : str - EPANET INP output file + EPANET INP output file """ @@ -881,4 +893,4 @@ def ENsaveinpfile(self, inpfile): self.errcode = self.ENlib.ENsaveinpfile(inpfile) self._error() - return \ No newline at end of file + return diff --git a/wntr/epanet/util.py b/wntr/epanet/util.py index ab6038276..4dc74df3c 100644 --- a/wntr/epanet/util.py +++ b/wntr/epanet/util.py @@ -1,11 +1,13 @@ """ The wntr.epanet.util module contains unit conversion utilities based on EPANET units. """ +from __future__ import annotations + import dataclasses import enum import logging from dataclasses import dataclass, field -from typing import List +from typing import List, Optional, Union, TypedDict import numpy as np import pandas as pd @@ -1387,6 +1389,15 @@ def from_si( @dataclass class ENcomment: + """A class for storing EPANET configuration file comments with objects. + + Attributes + ---------- + pre : list of str + a list of comments to put before the output of a configuration line + post : str + a single comment that is attached to the end of the line + """ pre: List[str] = field(default_factory=list) post: str = None @@ -1402,4 +1413,11 @@ def wrap_msx_string(self, string) -> str: return '\n; ' + '\n\n; '.join(self.pre) + '\n\n ' + string + ' ; ' + self.post def to_dict(self): - return dataclasses.asdict(self) \ No newline at end of file + return dataclasses.asdict(self) + +NoteType = Union[str, dict, ENcomment] +"""An object that stores EPANET compatible annotation data. + +A note (or comment) can be a string, a dictionary of the form :code:`{'pre': List[str], 'post': str}`, +or an :class:`wntr.epanet.util.ENcomment` object. +""" diff --git a/wntr/msx/__init__.py b/wntr/msx/__init__.py index 3cc6669e1..5937536fd 100644 --- a/wntr/msx/__init__.py +++ b/wntr/msx/__init__.py @@ -1,12 +1,15 @@ # -*- coding: utf-8 -*- -"""Contains definitions for water quality chemistry objects and reactions""" +"""Contains definitions for EPANET Multispecies Extension (MSX) water quality modeling. +""" # Dependencies: -# pyomo.dae -# sympy +# pyomo.dae? +# sympy? -from ..epanet.msx.exceptions import EpanetMsxException -from .base import * -from .model import * -from .options import MultispeciesOptions -from . import library +from .base import VariableType, SpeciesType, ReactionType, ExpressionType +from .elements import Species, Constant, Parameter, Term, Reaction, HydraulicVariable, MathFunction +from .model import MsxModel +from .options import MsxSolverOptions +from .library import ReactionLibrary, cite_msx + +from . import base, elements, library, model, options diff --git a/wntr/msx/base.py b/wntr/msx/base.py index 80b3b8d72..75bff8f31 100644 --- a/wntr/msx/base.py +++ b/wntr/msx/base.py @@ -5,54 +5,55 @@ and/or mixin classes, and should not be instantiated directly. """ -from abc import ABC, abstractclassmethod, abstractmethod, abstractproperty import logging -from enum import Enum, IntEnum import os -from typing import Any, Dict, Iterator, List, Union -from wntr.utils.disjoint_mapping import DisjointMapping +from abc import ABC, abstractclassmethod, abstractmethod, abstractproperty +from enum import Enum +from typing import Any, Dict, Iterator, List, Union, Generator +from wntr.epanet.util import ENcomment, NoteType +from wntr.utils.disjoint_mapping import DisjointMapping from wntr.utils.enumtools import add_get has_sympy = False try: from sympy import ( + Add, Float, - Symbol, - init_printing, - symbols, Function, + Integer, Mul, - Add, Pow, - Integer, + Symbol, + init_printing, + symbols, ) from sympy.functions import ( - cos, - sin, - tan, - cot, Abs, - sign, - sqrt, - log, - exp, - asin, + Heaviside, acos, - atan, acot, - sinh, + asin, + atan, + cos, cosh, - tanh, + cot, coth, - Heaviside, + exp, + log, + sign, + sin, + sinh, + sqrt, + tan, + tanh, ) from sympy.parsing import parse_expr from sympy.parsing.sympy_parser import ( - convert_xor, - standard_transformations, auto_number, auto_symbol, + convert_xor, + standard_transformations, ) class _log10(Function): @@ -69,22 +70,22 @@ def eval(cls, x): convert_xor = None if not has_sympy: from numpy import ( - cos, - sin, - tan, abs, - sign, - sqrt, - log, - exp, - arcsin, arccos, + arcsin, arctan, - sinh, + cos, cosh, - tanh, + exp, heaviside, + log, log10, + sign, + sin, + sinh, + sqrt, + tan, + tanh, ) def _cot(x): @@ -110,22 +111,6 @@ def _coth(x): logger = logging.getLogger(__name__) -__all__ = [ - "HYDRAULIC_VARIABLES", - "EXPR_FUNCTIONS", - "RESERVED_NAMES", - "EXPR_TRANSFORMS", - "VariableType", - "SpeciesType", - "ReactionType", - "ExpressionType", - "AbstractVariable", - "AbstractReaction", - "ReactionSystem", - "VariableValues", - "AbstractModel", -] - HYDRAULIC_VARIABLES = [ {"name": "D", "note": "pipe diameter (feet or meters) "}, { @@ -289,7 +274,7 @@ def _coth(x): """ -class AnnotatedFloat(float): +class _AnnotatedFloat(float): def __new__(self, value, note=None): return float.__new__(self, value) @@ -299,7 +284,7 @@ def __init__(self, value, note=None): @add_get(abbrev=True) -class VariableType(IntEnum): +class VariableType(Enum): """The type of reaction variable. The following types are defined, and aliases of just the first character @@ -325,13 +310,14 @@ class VariableType(IntEnum): SPECIES = 3 """A chemical or biological water quality species""" TERM = 4 - """A functional term - ie named expression - for use in reaction expressions""" + """A functional term, or named expression, for use in reaction expressions""" PARAMETER = 5 """A reaction expression coefficient that is parameterized by tank or pipe""" CONSTANT = 6 """A constant coefficient for use in reaction expressions""" RESERVED = 9 - """A 'variable' that is either a hydraulic variable or other reserved word""" + """A variable that is either a hydraulic variable or other reserved word""" + S = SPEC = SPECIES T = TERM P = PARAM = PARAMETER @@ -340,10 +326,10 @@ class VariableType(IntEnum): @add_get(abbrev=True) -class SpeciesType(IntEnum): +class SpeciesType(Enum): """The enumeration for species type. - .. warning:: These enum values are note the same as the MSX SpeciesType. + .. warning:: These enum values are not the same as the MSX SpeciesType. .. rubric:: Enum Members @@ -363,6 +349,7 @@ class SpeciesType(IntEnum): """bulk species""" WALL = 2 """wall species""" + B = BULK W = WALL @@ -420,7 +407,8 @@ class ExpressionType(Enum): EQUIL = 1 """used for equilibrium expressions where it is assumed that the expression supplied is being equated to zero""" RATE = 2 - """used to supply the equation that expresses the rate of change of the given species with respect to time as a function of the other species in the model""" + """used to supply the equation that expresses the rate of change of the given species with respect to time as a function + of the other species in the model""" FORMULA = 3 """used when the concentration of the named species is a simple function of the remaining species""" @@ -429,23 +417,56 @@ class ExpressionType(Enum): F = FORMULA -class AbstractReaction(ABC): - def __init__(self, species_name: str, *, note=None) -> None: +class ReactionBase(ABC): + """A water quality reaction class. + + This is an abstract class for water quality reactions with partial concrete + attribute and method definitions. All parameters + and methods documented here must be defined by a subclass except for the following: + + .. rubric:: Concrete attribtues + + The :meth:`__init__` method defines the following attributes concretely. Thus, + a subclass should call :code:`super().__init__(species_name, note=note)` at the beginning of its own + initialization. + + .. autosummary:: + + ~ReactionBase._species_name + ~ReactionBase.note + + .. rubric:: Concrete properies + + The species name is protected, and a reaction cannot be manually assigned a new species. + Therefore, the following property is defined concretely. + + .. autosummary:: + + species_name + + .. rubric:: Concrete methods + + The following methods are concretely defined, but can be overridden. + + .. autosummary:: + :nosignatures: + + __str__ + __repr__ + """ + + def __init__(self, species_name: str, *, note: NoteType = None) -> None: """A water quality reaction definition. This abstract class must be subclassed. - Arguments - --------- + Parameters + ---------- species_name : str The name of the chemical or biological species being modeled using this reaction. - - - Keyword Arguments - ----------------- - note : str | dict | ENcomment, optional - Supplementary information regarding this reaction, by default None (see :class:`~wntr.epanet.util.ENcomment` for dict structure). - + note : (str | dict | ENcomment), optional keyword + Supplementary information regarding this reaction, by default None + (see-also :class:`~wntr.epanet.util.NoteType`) Raises ------ @@ -454,60 +475,75 @@ def __init__(self, species_name: str, *, note=None) -> None: """ if species_name is None: raise TypeError("The species_name cannot be None") - self._species_name = species_name - self.note = note + self._species_name: str = str(species_name) + """The protected name of the species""" + self.note: NoteType = note + """An optional note regarding the reaction (see :class:`~wntr.epanet.util.NoteType`) + """ @property def species_name(self) -> str: + """The name of the species that has a reaction being defined.""" return self._species_name @abstractproperty def reaction_type(self) -> Enum: - """The type of reaction or where this reaction occurs.""" + """The reaction type (reaction location).""" raise NotImplementedError def __str__(self) -> str: + """Return the name of the species and the reaction type, indicated by an arrow. E.g., 'HOCL->PIPE for chlorine reaction in pipes.""" return "{}->{}".format(self.species_name, self.reaction_type.name) def __repr__(self) -> str: - return ( - "{}(".format(self.__class__.__name__) - + ", ".join(["{}={}".format(k, repr(getattr(self, k))) for k, v in self.to_dict().items()]) - + ")" - ) + """Return a representation of the reaction from the dictionary representation - see :meth:`to_dict`""" + return "{}(".format(self.__class__.__name__) + ", ".join(["{}={}".format(k, repr(getattr(self, k))) for k, v in self.to_dict().items()]) + ")" @abstractmethod def to_dict(self) -> dict: + """Represent the object as a dictionary.""" raise NotImplementedError -class AbstractVariable(ABC): +class VariableBase(ABC): """A multi-species water quality model variable. - This abstract class must be extended before use. There are several concrete classes - that inhert from this class, including - :class:`~wntr.msx.msx.Species`, - :class:`~wntr.msx.msx.Constant`, - :class:`~wntr.msx.msx.Parameter`, - and :class:`~wntr.msx.msx.Term`. - See also the :class:`~wntr.msx.msx.MultispeciesModel`, which has the functions - required to create these variables and define reactions. + This is an abstract class for water quality model variables with partial definition + of concrete attributes and methods. Parameters + and methods documented here must be defined by a subclass except for the following: + + .. rubric:: Concrete attribtues + + The :meth:`__init__` method defines the following attributes concretely. Thus, + a subclass should call :code:`super().__init__()` at the beginning of its own + initialization. + + .. autosummary:: + + ~VariableBase.name + ~VariableBase.note + + .. rubric:: Concrete methods + + The following methods are concretely defined, but can be overridden. + + .. autosummary:: + :nosignatures: + + __str__ + __repr__ """ - def __init__(self, name: str, *, note=None) -> None: + def __init__(self, name: str, *, note: NoteType = None) -> None: """Multi-species variable constructor arguments. - Arguments - --------- + Parameters + ---------- name : str The name/symbol for the variable. Must be a valid MSX variable name. - - Keyword Arguments - ----------------- - note : str | dict | ENcomment, optional - Supplementary information regarding this variable, by default None (see :class:`~wntr.epanet.util.ENcomment` for dict structure). - As dict it can have two keys, "pre" and "post". See :class:`ENcomment` - for more details. + note : (str | dict | ENcomment), optional keyword + Supplementary information regarding this variable, by default None + (see-also :class:`~wntr.epanet.util.NoteType`) Raises ------ @@ -515,22 +551,14 @@ def __init__(self, name: str, *, note=None) -> None: the name is already taken ValueError the name is a reserved word - - - The following should only be used by model building functions, and the - user should never need to pass these arguments. - - Other Parameters - ---------------- - _vars : VariablesRegistry, optional - the variables registry object of the model this variable was added to, by default None """ if name in RESERVED_NAMES: raise ValueError("Name cannot be a reserved name") self.name: str = name """The name/ID of this variable, must be a valid EPANET/MSX ID""" - self.note = note - """A note related to this variable""" + self.note: NoteType = note + """An optional note regarding the variable (see :class:`~wntr.epanet.util.NoteType`) + """ @abstractproperty def var_type(self) -> Enum: @@ -543,49 +571,79 @@ def to_dict(self) -> Dict[str, Any]: raise NotImplementedError def __str__(self) -> str: + """Return the name of the variable""" return self.name def __repr__(self) -> str: - return ( - "{}(".format(self.__class__.__name__) - + ", ".join(["{}={}".format(k, repr(getattr(self, k))) for k, v in self.to_dict().items()]) - + ")" - ) + """Return a representation of the variable from the dictionary representation - see :meth:`to_dict`""" + return "{}(".format(self.__class__.__name__) + ", ".join(["{}={}".format(k, repr(getattr(self, k))) for k, v in self.to_dict().items()]) + ")" -class ReactionSystem(ABC): +class ReactionSystemBase(ABC): """Abstract class for reaction systems, which contains variables and reaction expressions. - This class contains the functions necessary to perform as a mapping view onto the - **variables** defined, by their name. + This class contains the functions necessary to perform dictionary-style + addressing of *variables* by their name. It does not allow dictionary-style + addressing of reactions. + + This is an abstract class with some concrete attributes and methods. Parameters + and methods documented here must be defined by a subclass except for the following: + + .. rubric:: Concrete attributes + + The :meth:`__init__` method defines the following attributes concretely. Thus, + a subclass should call :code:`super().__init__()` or :code:`super().__init__(filename)`. + + .. autosummary:: + + ~ReactionSystemBase._vars + ~ReactionSystemBase._rxns + + .. rubric:: Concrete methods + + The following special methods are concretely provided to directly access items + in the :attr:`_vars` attribute. + + .. autosummary:: + :nosignatures: + + __contains__ + __eq__ + __ne__ + __getitem__ + __iter__ + __len__ """ def __init__(self) -> None: - self._vars = DisjointMapping() - self._rxns = dict() + """The constructor for the reaction system.""" + self._vars: DisjointMapping = DisjointMapping() + """The variables registry, which is mapped to dictionary functions on the reaction system object""" + self._rxns: Dict[str, Any] = dict() + """The reactions dictionary""" @abstractmethod - def add_variable(self, obj: AbstractVariable) -> None: + def add_variable(self, obj: VariableBase) -> None: """Add a variable to the system""" raise NotImplementedError @abstractmethod - def add_reaction(self, obj: AbstractReaction) -> None: + def add_reaction(self, obj: ReactionBase) -> None: """Add a reaction to the system""" raise NotImplementedError @abstractmethod - def variables(self): + def variables(self) -> Generator[Any, Any, Any]: """A generator looping through all variables""" raise NotImplementedError @abstractmethod - def reactions(self): + def reactions(self) -> Generator[Any, Any, Any]: """A generator looping through all reactions""" raise NotImplementedError @abstractmethod - def to_dict(self): + def to_dict(self) -> dict: """Represent the reaction system as a dictionary""" raise NotImplementedError @@ -598,7 +656,7 @@ def __eq__(self, __value: object) -> bool: def __ne__(self, __value: object) -> bool: return self._vars.__ne__(__value) - def __getitem__(self, __key: str) -> AbstractVariable: + def __getitem__(self, __key: str) -> VariableBase: return self._vars.__getitem__(__key) def __iter__(self) -> Iterator: @@ -608,61 +666,118 @@ def __len__(self) -> int: return self._vars.__len__() -class VariableValues(ABC): - """Abstract class for a variable's network-specific values.""" +class VariableValuesBase(ABC): + """Abstract class for a variable's network-specific values. + + This class should contain values for different pipes, tanks, + etc., that correspond to a specific network for the reaction + system. It can be used for intial concentration values, or + for initial settings on parameters, but should be information + that is clearly tied to a specific type of variable. + + This is a pure abstract class. All parameters + and methods documented here must be defined by a subclass. + """ @abstractproperty def var_type(self) -> Enum: - """Define what type of variable this network-specific data is for""" + """The type of variable this object holds data for.""" raise NotImplementedError @abstractmethod def to_dict(self) -> dict: - """Represent the variable's network-specific values as a dictionary""" + """Represent a specific variable's network-specific values as a dictionary. + + Returns + ------- + dict + the network-specific values for a specific variable + """ raise NotImplementedError -class NetworkData(ABC): +class NetworkDataBase(ABC): """Abstract class containing network specific data. - + This class should be populated with things like initial quality, sources, parameterized values, etc. + + This is a pure abstract class. All parameters + and methods documented here must be defined by a subclass. """ @abstractmethod def to_dict(self) -> dict: - """Represent the network specific data as a dictionary""" + """Represent the quality-relevant network-specific data as a dictionary. + + Returns + ------- + dict + the quality-relevant network data + """ raise NotImplementedError -class AbstractModel(ABC): - """Abstract water quality model.""" +class QualityModelBase(ABC): + """Abstract water quality model. + + This is an abstract class for a water quality model. All parameters + and methods documented here must be defined by a subclass except for the following: + + .. rubric:: Concrete attributes + + The :meth:`__init__` method defines the following attributes concretely. Thus, + a subclass should call :code:`super().__init__()` or :code:`super().__init__(filename)`. + + .. autosummary:: + + ~QualityModelBase.name + ~QualityModelBase.title + ~QualityModelBase.description + ~QualityModelBase._orig_file + ~QualityModelBase._options + ~QualityModelBase._rxn_system + ~QualityModelBase._net_data + ~QualityModelBase._wn + """ def __init__(self, filename=None): + """Abstract water quality model. + + Parameters + ---------- + filename : str, optional + the file to use to populate the initial data + """ self.name: str = None if filename is None else os.path.splitext(os.path.split(filename)[1])[0] """A name for the model, or the MSX model filename (no spaces allowed)""" self.title: str = None """The title line from the MSX file, must be a single line""" self.description: str = None - """A longer description, note that multi-line descriptions may not be - represented well in dictionary form.""" + """A longer description; note that multi-line descriptions may not be + represented well in dictionary form""" self._orig_file: str = filename + """The protected original filename, if provided in the constructor""" self._options = None - self._rxn_system: ReactionSystem = None - self._net_data: NetworkData = None + """The protected options data object""" + self._rxn_system: ReactionSystemBase = None + """The protected reaction system object""" + self._net_data: NetworkDataBase = None + """The protected network data object""" self._wn = None + """The protected water network object""" @abstractproperty def options(self): """The model options structure. - Concrete classes should implement this with the appropriate typeing and + Concrete classes should implement this with the appropriate typing and also implement a setter method. """ raise NotImplementedError @abstractproperty - def reaction_system(self) -> ReactionSystem: + def reaction_system(self) -> ReactionSystemBase: """The reaction variables defined for this model. Concrete classes should implement this with the appropriate typing. @@ -670,7 +785,7 @@ def reaction_system(self) -> ReactionSystem: raise NotImplementedError @abstractproperty - def network_data(self) -> NetworkData: + def network_data(self) -> NetworkDataBase: """The network-specific values added to this model. Concrete classes should implement this with the appropriate typing. @@ -679,10 +794,27 @@ def network_data(self) -> NetworkData: @abstractmethod def to_dict(self) -> dict: - """Represent the model as a dictionary.""" + """Represent the model as a dictionary. + + Returns + ------- + dict + A dictionary representation of a water quality model + """ raise NotImplementedError @abstractclassmethod - def from_dict(self, data: dict) -> "AbstractModel": - """Create a new model from a dictionary.""" + def from_dict(self, data: dict) -> "QualityModelBase": + """Create a new model from a dictionary. + + Parameters + ---------- + data : dict + A dictionary representation of a water quality model + + Returns + ------- + QualityModelBase + the new concrete water quality model + """ raise NotImplementedError diff --git a/wntr/msx/elements.py b/wntr/msx/elements.py index b3be0a463..0ae9794f5 100644 --- a/wntr/msx/elements.py +++ b/wntr/msx/elements.py @@ -1,32 +1,24 @@ # -*- coding: utf-8 -*- -"""Water quality model implementations. +"""Concrete implementations of MSX classes. """ - +from __future__ import annotations import logging +from typing import Any, Dict, Literal, Tuple, Union -from typing import ( - Any, - Callable, - Dict, - Literal, - Tuple, - Union, -) - -from wntr.epanet.util import ENcomment +from wntr.epanet.util import ENcomment, NoteType from wntr.utils.disjoint_mapping import KeyExistsError from .base import ( - VariableValues, - AbstractReaction, - ReactionSystem, - AbstractVariable, ExpressionType, ReactionType, - VariableType, SpeciesType, + VariableType, + VariableBase, + VariableValuesBase, + ReactionBase, + ReactionSystemBase, ) has_sympy = False @@ -46,50 +38,9 @@ logger = logging.getLogger(__name__) -__all__ = [ - 'Species', - 'Constant', - 'Parameter', - 'Term', - 'ReservedName', - 'HydraulicVariable', - 'MathFunction', - 'Reaction' -] - -class Species(AbstractVariable): +class Species(VariableBase): """A biological or chemical species that impacts water quality. - - .. rubric:: Attributes - - .. autosummary:: - - ~Species.name - ~Species.species_type - ~Species.units - ~Species.note - ~Species.diffusivity - - .. rubric:: Methods - - .. autosummary:: - - ~Species.set_tolerances - ~Species.get_tolerances - ~Species.clear_tolerances - ~Species.to_dict - - .. rubric:: Read-only Attributes - - .. autosummary:: - - ~Species.atol - ~Species.rtol - ~Species.initial_quality - ~Species.pipe_reaction - ~Species.tank_reaction - """ def __init__( @@ -100,35 +51,33 @@ def __init__( atol: float = None, rtol: float = None, *, - note: Union[str, dict, ENcomment]=None, + note: NoteType = None, diffusivity: float = None, - _vars: ReactionSystem = None, - _vals: VariableValues = None, + _vars: ReactionSystemBase = None, + _vals: VariableValuesBase = None, ) -> None: """A biological or chemical species. Parameters ---------- - name : str + name The species name - species_type : SpeciesType or str + species_type The species type - units : str + units The units of mass for this species, see :attr:`units` property. - atol : float, optional, requires rtol + atol : float | None The absolute tolerance when solving this species' equations, by default None - rtol : float, optional, requires atol + rtol : float | None The relative tolerance when solving this species' equations, by default None - note : str or dict or ENcomment, optional + note Supplementary information regarding this variable, by default None - diffusivity : float, optional + (see :class:`~wntr.epanet.util.NoteType`) + diffusivity Diffusivity of the species in water, by default None - - Other Parameters - ---------------- - _vars : MsxReactionSystem, optional + _vars the reaction system this species is a part of, by default None - _vals : InitialQuality, optional + _vals the initial quality values for this species, by default None Raises @@ -136,10 +85,18 @@ def __init__( KeyExistsError if the name has already been used TypeError - if a tank reaction is provided for a wall species + if `atol` and `rtol` are not the same type + ValueError + if `atol` or `rtol` ≤ 0 + + Notes + ----- + EPANET-MSX requires that `atol` and `rtol` either both be omitted, or both be provided. + In order to enforce this, the arguments passed for `atol` and `rtol` must both be None + or both be positive values. """ super().__init__(name, note=note) - if _vars is not None and not isinstance(_vars, ReactionSystem): + if _vars is not None and not isinstance(_vars, ReactionSystemBase): raise TypeError("Invalid type for _vars, {}".format(type(_vars))) if _vals is not None and not isinstance(_vals, InitialQuality): raise TypeError("Invalid type for _vals, {}".format(type(_vals))) @@ -148,8 +105,8 @@ def __init__( species_type = SpeciesType.get(species_type) if species_type is None: raise TypeError("species_type cannot be None") - self._species_type = species_type - self._tolerances = None + self._species_type: SpeciesType = species_type + self._tolerances: Tuple[float, float] = None self.set_tolerances(atol, rtol) self.units: str = units """The units of mass for this species. @@ -158,8 +115,8 @@ def __init__( """ self.diffusivity: float = diffusivity """The diffusivity of this species in water, if being used, by default None""" - self._vars = _vars - self._vals = _vals + self._vars: ReactionSystemBase = _vars + self._vals: InitialQuality = _vals def set_tolerances(self, atol: float, rtol: float): """Set the absolute and relative tolerance for the solvers. @@ -169,9 +126,9 @@ def set_tolerances(self, atol: float, rtol: float): Parameters ---------- - atol : float + atol The absolute tolerance to use - rtol : float + rtol The relative tolerance to use Raises @@ -179,7 +136,7 @@ def set_tolerances(self, atol: float, rtol: float): TypeError if only one of `atol` or `rtol` is a float ValueError - if either value is less-than-or-equal-to zero + if `atol` or `rtol` ≤ 0 """ if (self.atol is None) ^ (self.rtol is None): raise TypeError("atol and rtol must both be float or both be None") @@ -195,7 +152,7 @@ def get_tolerances(self) -> Union[Tuple[float, float], None]: Returns ------- - Union[Tuple[float, float], None] + (atol, rtol) : (float, float) or None absolute and relative tolerances, respectively, if they are set """ return self._tolerances @@ -220,16 +177,16 @@ def rtol(self) -> float: @property def var_type(self) -> VariableType: - """This is a species""" + """The type of variable, :attr:`~wntr.msx.base.VariableType.SPECIES`.""" return VariableType.SPECIES @property def species_type(self) -> SpeciesType: - """The type of species""" + """The type of species, either :attr:`~wntr.msx.base.SpeciesType.BULK` or :attr:`~wntr.msx.base.SpeciesType.WALL`""" return self._species_type @property - def initial_quality(self): + def initial_quality(self) -> 'InitialQuality': """If a specific network has been linked, then the initial quality values for the network""" if self._vals is not None: return self._vals @@ -237,18 +194,20 @@ def initial_quality(self): raise TypeError("This species is not linked to a NetworkData obejct, please `relink` your model") @property - def pipe_reaction(self): + def pipe_reaction(self) -> 'Reaction': + """The pipe reaction definition""" if self._vars is not None: return self._vars.pipe_reactions[self.name] else: - raise AttributeError('This species is not connected to a ReactionSystem') + raise AttributeError("This species is not connected to a ReactionSystem") @property - def tank_reaction(self): + def tank_reaction(self) -> 'Reaction': + """The tank reaction definition""" if self._vars is not None: return self._vars.tank_reactions[self.name] else: - raise AttributeError('This species is not connected to a ReactionSystem') + raise AttributeError("This species is not connected to a ReactionSystem") def to_dict(self) -> Dict[str, Any]: """Create a dictionary representation of the object @@ -291,9 +250,7 @@ def to_dict(self) -> Dict[str, Any]: } """ - ret = dict( - name=self.name, species_type=self.species_type.name.lower(), units=self.units, atol=self.atol, rtol=self.rtol - ) + ret = dict(name=self.name, species_type=self.species_type.name.lower(), units=self.units, atol=self.atol, rtol=self.rtol) if self.diffusivity: ret["diffusivity"] = self.diffusivity @@ -306,45 +263,42 @@ def to_dict(self) -> Dict[str, Any]: return ret -class Constant(AbstractVariable): +class Constant(VariableBase): """A constant coefficient for use in reaction expressions.""" - def __init__(self, name: str, value: float, *, units: str = None, note: Union[str, dict, ENcomment]=None, _vars: ReactionSystem = None) -> None: + def __init__(self, name: str, value: float, *, units: str = None, note: Union[str, dict, ENcomment] = None, _vars: ReactionSystemBase = None) -> None: """A variable representing a constant value. Parameters ---------- - name : str + name The name of the variable. - value : float + value The constant value. - units : str, optional + units Units for the variable, by default None - note : str or dict or ENcomment, optional + note Supplementary information regarding this variable, by default None - - Other Parameters - ---------------- - _vars : MsxReactionSystem, optional + _vars the reaction system this constant is a part of, by default None """ super().__init__(name, note=note) - if _vars is not None and not isinstance(_vars, ReactionSystem): + if _vars is not None and not isinstance(_vars, ReactionSystemBase): raise TypeError("Invalid type for _vars, {}".format(type(_vars))) if _vars is not None and name in _vars: raise KeyExistsError("This variable name is already taken") - self.value = float(value) + self.value: float = float(value) """The value of the constant""" - self.units = units + self.units: str = units """The units of the constant""" - self._vars = _vars + self._vars: ReactionSystemBase = _vars def __call__(self, *, t=None) -> Any: return self.value @property def var_type(self) -> VariableType: - """This is a constant coefficient.""" + """The type of variable, :attr:`~wntr.msx.base.VariableType.CONSTANT`.""" return VariableType.CONSTANT def to_dict(self) -> Dict[str, Any]: @@ -358,43 +312,68 @@ def to_dict(self) -> Dict[str, Any]: return ret -class Parameter(AbstractVariable): +class Parameter(VariableBase): """A coefficient that is parameterized by pipe/tank.""" - def __init__(self, name: str, global_value: float, *, units: str = None, note: Union[str, dict, ENcomment]=None, _vars: ReactionSystem = None, _vals: VariableValues=None) -> None: + def __init__( + self, name: str, global_value: float, *, units: str = None, note: Union[str, dict, ENcomment] = None, _vars: ReactionSystemBase = None, _vals: VariableValuesBase = None + ) -> None: """A parameterized variable for use in expressions. Parameters ---------- - name : str + name The name of this parameter. - global_value : float + global_value The global value for the parameter if otherwise unspecified. - units : str, optional + units The units for this parameter, by default None - note : str or dict or ENcomment, optional + note Supplementary information regarding this variable, by default None - - Other Parameters - ---------------- - _vars : MsxReactionSystem, optional + _vars the reaction system this parameter is a part of, by default None - _vals : ParameterValues, optional + _vals the netork-specific values for this parameter, by default None """ super().__init__(name, note=note) - if _vars is not None and not isinstance(_vars, ReactionSystem): + if _vars is not None and not isinstance(_vars, ReactionSystemBase): raise TypeError("Invalid type for _vars, {}".format(type(_vars))) if _vals is not None and not isinstance(_vals, ParameterValues): raise TypeError("Invalid type for _vals, {}".format(type(_vals))) if _vars is not None and name in _vars: raise KeyExistsError("This variable name is already taken") - self.global_value = float(global_value) - self.units = units - self._vars = _vars - self._vals = _vals + self.global_value: float = float(global_value) + self.units: str = units + self._vars: ReactionSystemBase = _vars + self._vals: ParameterValues = _vals + + def __call__(self, *, pipe: str = None, tank: str = None) -> float: + """Get the value of the parameter for a given pipe or tank. - def __call__(self, *, t=None, pipe: float = None, tank: float = None) -> Any: + If there is no specific, different value for the requested pipe + or tank, then the global value will be returned. *This is true even* + *if the pipe or tank does not exist in the network, so caution is* + *advised*. + + Parameters + ---------- + pipe + the name of a pipe to get the parameter value for, by default None + tank + the name of a pipe to get the parameter value for, by default None + + Returns + ------- + float + the value at the specified pipe or tank, or the global value + + Raises + ------ + TypeError + if both pipe and tank are specified + ValueError + if there is no ParameterValues object defined for and linked to this parameter + """ if pipe is not None and tank is not None: raise TypeError("Both pipe and tank cannot be specified at the same time") elif self._vals is None and (pipe is not None or tank is not None): @@ -407,7 +386,7 @@ def __call__(self, *, t=None, pipe: float = None, tank: float = None) -> Any: @property def var_type(self) -> VariableType: - """This is a parameterized coefficient.""" + """The type of variable, :attr:`~wntr.msx.base.VariableType.PARAMETER`.""" return VariableType.PARAMETER def to_dict(self) -> Dict[str, Any]: @@ -421,36 +400,35 @@ def to_dict(self) -> Dict[str, Any]: return ret -class Term(AbstractVariable): - def __init__(self, name: str, expression: str, *, note: Union[str, dict, ENcomment]=None, _vars: ReactionSystem = None) -> None: +class Term(VariableBase): + """A named expression that can be used as a term in other expressions.""" + + def __init__(self, name: str, expression: str, *, note: Union[str, dict, ENcomment] = None, _vars: ReactionSystemBase = None) -> None: """A named expression that can be used as a term in other expressions. Parameters ---------- - name : str + name The variable name. - expression : str + expression The mathematical expression to be aliased - note : str or dict or ENcomment, optional + note Supplementary information regarding this variable, by default None - - Other Parameters - ---------------- - _vars : MsxReactionSystem, optional + _vars the reaction system this species is a part of, by default None """ super().__init__(name, note=note) - if _vars is not None and not isinstance(_vars, ReactionSystem): + if _vars is not None and not isinstance(_vars, ReactionSystemBase): raise TypeError("Invalid type for _vars, {}".format(type(_vars))) if _vars is not None and name in _vars: raise KeyExistsError("This variable name is already taken") - self.expression = expression + self.expression: str = expression """The expression that is aliased by this term""" - self._vars = _vars + self._vars: ReactionSystemBase = _vars @property def var_type(self) -> VariableType: - """This is a term (named expression).""" + """The type of variable, :attr:`~wntr.msx.base.VariableType.TERM`.""" return VariableType.TERM def to_dict(self) -> Dict[str, Any]: @@ -462,43 +440,40 @@ def to_dict(self) -> Dict[str, Any]: return ret -class ReservedName(AbstractVariable): - def __init__(self, name: str, *, note: Union[str, dict, ENcomment]=None) -> None: +class ReservedName(VariableBase): + """An object representing a reserved name that should not be used by the user.""" + + def __init__(self, name: str, *, note: Union[str, dict, ENcomment] = None) -> None: """An object representing a reserved name that should not be used by the user. Parameters ---------- - name : str + name The reserved name. - note : str or dict or ENcomment, optional + note Supplementary information regarding this variable, by default None - Other Parameters - ---------------- - _vars : MsxReactionSystem, optional - the reaction system this species is a part of, by default None - Raises ------ KeyExistsError - _description_ + if the name has already been registered """ - self.name = name - self.note = note + self.name: str = name + self.note: Union[str, dict, ENcomment] = note @property def var_type(self) -> VariableType: - """Variable name is a reserved word in MSX""" + """The type of variable, :attr:`~wntr.msx.base.VariableType.RESERVED`.""" return VariableType.RESERVED def to_dict(self) -> Dict[str, Any]: - return '{}({})'.format(self.__class__.__name__, ', '.join(['name={}'.format(repr(self.name)), 'note={}'.format(repr(self.note))])) + return "{}({})".format(self.__class__.__name__, ", ".join(["name={}".format(repr(self.name)), "note={}".format(repr(self.note))])) class HydraulicVariable(ReservedName): """A variable representing instantaneous hydraulics data.""" - def __init__(self, name: str, units: str = None, *, note: Union[str, dict, ENcomment]=None) -> None: + def __init__(self, name: str, units: str = None, *, note: Union[str, dict, ENcomment] = None) -> None: """A variable representing instantaneous hydraulics data. The user should not need to create any variables using this class, they @@ -506,69 +481,74 @@ def __init__(self, name: str, units: str = None, *, note: Union[str, dict, ENcom Parameters ---------- - name : str + name The name of the variable (predefined by MSX) - units : str, optional + units The units for hydraulic variable, by default None - note : str or dict or ENcomment, optional + note Supplementary information regarding this variable, by default None """ super().__init__(name, note=note) - self.units = units + self.units: str = units """The hydraulic variable's units""" class MathFunction(ReservedName): """A variable that is actually a mathematical function defined by MSX.""" - def __init__(self, name: str, func: Callable, *, note: Union[str, dict, ENcomment]=None) -> None: + def __init__(self, name: str, func: callable, *, note: Union[str, dict, ENcomment] = None) -> None: """A variable that is actually a mathematical function defined by MSX. Parameters ---------- - name : str + name The function name - func : Callable + func The callable function - note : str or dict or ENcomment, optional + note Supplementary information regarding this variable, by default None """ super().__init__(name, note=note) - self.func = func + self.func: callable = func """A callable function or SymPy function""" def __call__(self, *args: Any, **kwds: Any) -> Any: + """Evaluate the function using any specified args and kwds.""" return self.func(*args, **kwds) -class Reaction(AbstractReaction): +class Reaction(ReactionBase): """A water quality biochemical reaction dynamics definition for a specific species.""" def __init__( - self, species_name: str, reaction_type: ReactionType, expression_type: ExpressionType, expression: str, *, note: Union[str, dict, ENcomment]=None, _vars: ReactionSystem = None + self, + species_name: str, + reaction_type: ReactionType, + expression_type: ExpressionType, + expression: str, + *, + note: Union[str, dict, ENcomment] = None, + _vars: ReactionSystemBase = None, ) -> None: """A water quality biochemical reaction dynamics definition for a specific species. Parameters ---------- - species_name : str + species_name The species (object or name) this reaction is applicable to. - reaction_type : ReactionType + reaction_type The type of reaction, either PIPE or TANK - expression_type : ExpressionType + expression_type The type of reaction dynamics being described by the expression: one of RATE, FORMULA, or EQUIL. - expression : str + expression The mathematical expression for the right-hand-side of the reaction equation. - note : str or dict or ENcomment, optional + note Supplementary information regarding this variable, by default None - - Other Parameters - ---------------- - _vars : MsxReactionSystem, optional + _vars the reaction system this species is a part of, by default None """ super().__init__(species_name=species_name, note=note) - if _vars is not None and not isinstance(_vars, ReactionSystem): + if _vars is not None and not isinstance(_vars, ReactionSystemBase): raise TypeError("Invalid type for _vars, {}".format(type(_vars))) expression_type = ExpressionType.get(expression_type) reaction_type = ReactionType.get(reaction_type) @@ -576,28 +556,26 @@ def __init__( raise TypeError("Required argument reaction_type cannot be None") if expression_type is None: raise TypeError("Required argument expression_type cannot be None") - self.__rxn_type = reaction_type - self._expr_type = expression_type + self.__rxn_type: ReactionType = reaction_type + self._expr_type: ExpressionType = expression_type if not expression: raise TypeError("expression cannot be None") - self.expression = expression + self.expression: str = expression """The mathematical expression (right-hand-side)""" - self._vars = _vars + self._vars: ReactionSystemBase = _vars @property def expression_type(self) -> ExpressionType: - """The type of dynamics being described: RATE, EQUIL or FORMULA""" + """The expression type (left-hand-side), either :attr:`~wntr.msx.base.ExpressionType.RATE`, :attr:`~wntr.msx.base.ExpressionType.EQUIL`, or :attr:`~wntr.msx.base.ExpressionType.FORMULA`""" return self._expr_type @property def reaction_type(self) -> ReactionType: - """The type (i.e., location) of reaction: will be PIPE or TANK""" + """The reaction type (reaction location), either :attr:`~wntr.msx.base.ReactionType.PIPE` or :attr:`~wntr.msx.base.ReactionType.TANK`""" return self.__rxn_type def to_dict(self) -> dict: - ret = dict( - species_name=str(self.species_name), expression_type=self.expression_type.name.lower(), expression=self.expression - ) + ret = dict(species_name=str(self.species_name), expression_type=self.expression_type.name.lower(), expression=self.expression) if isinstance(self.note, ENcomment): ret["note"] = self.note.to_dict() elif isinstance(self.note, (str, dict, list)): @@ -605,26 +583,23 @@ def to_dict(self) -> dict: return ret -class InitialQuality(VariableValues): +class InitialQuality(VariableValuesBase): """A container for initial quality values for a species in a specific network.""" def __init__(self, global_value: float = 0.0, node_values: dict = None, link_values: dict = None): """The initial quality values for a species. - Arguments - --------- - global_value : float, optional - _description_, by default 0.0 - node_values : dict[str, float], optional - _description_, by default None - link_values : dict[str, float], optional - _description_, by default None + Parameters + ---------- + global_value + the global initial quality value, by default 0.0 + node_values + any different initial quality values for specific nodes, by default None + link_values + any different initial quality values for specific links, by default None """ self.global_value = global_value - """The global initial quality for this species. - - Will be set to 0.0 when not explicitly specified, and can be overridden for - specific nodes and links using the other members of this class.""" + """The global initial quality values for this species.""" self._node_values = node_values if node_values is not None else dict() self._link_values = link_values if link_values is not None else dict() @@ -635,7 +610,7 @@ def __repr__(self) -> str: @property def var_type(self) -> VariableType: - """This is data for a species""" + """The type of variable, :attr:`~wntr.msx.base.VariableType.SPECIES`, this object holds data for.""" return VariableType.SPECIES @property @@ -652,30 +627,28 @@ def to_dict(self) -> Dict[str, Dict[str, float]]: return dict(global_value=self.global_value, node_values=self._node_values.copy(), link_values=self._link_values.copy()) -class ParameterValues(VariableValues): +class ParameterValues(VariableValuesBase): """A container for pipe and tank specific values of a parameter for a specific network.""" def __init__(self, *, pipe_values: dict = None, tank_values: dict = None) -> None: """The non-global values for a parameter. - Arguments - --------- - pipe_values : dict, optional - _description_, by default None - tank_values : dict, optional - _description_, by default None + Parameters + ---------- + pipe_values + any different values for this parameter for specific pipes, by default None + tank_values + any different values for this parameter for specific tanks, by default None """ self._pipe_values = pipe_values if pipe_values is not None else dict() self._tank_values = tank_values if tank_values is not None else dict() def __repr__(self) -> str: - return self.__class__.__name__ + "(pipe_values=<{} entries>, tank_values=<{} entries>)".format( - len(self._pipe_values), len(self._tank_values) - ) + return self.__class__.__name__ + "(pipe_values=<{} entries>, tank_values=<{} entries>)".format(len(self._pipe_values), len(self._tank_values)) @property def var_type(self) -> VariableType: - """This is data for a parameter""" + """The type of variable, :attr:`~wntr.msx.base.VariableType.PARAMETER`, this object holds data for.""" return VariableType.PARAMETER @property @@ -690,4 +663,3 @@ def tank_values(self) -> Dict[str, float]: def to_dict(self) -> Dict[str, Dict[str, float]]: return dict(pipe_values=self._pipe_values.copy(), tank_values=self._tank_values.copy()) - diff --git a/wntr/msx/library.py b/wntr/msx/library.py index 9e9d4bcb6..76f00a173 100644 --- a/wntr/msx/library.py +++ b/wntr/msx/library.py @@ -1,8 +1,6 @@ # -*- coding: utf-8 -*- -# @Contributors: -# Jonathan Burkhardt, U.S. Environmental Protection Agency, Office of Research and Development -r"""A library of common multispecies reactions. +r"""A library of common MSX reactions. .. rubric:: Environment Variable @@ -13,19 +11,19 @@ path to search for quality model files, (files with an ".msx", ".yaml", or ".json" file extension). Multiple folders should be separated using the "``;``" character. - See :class:`~wntr.msx.library.ReactionLibrary` for more details. - + See :class:`~wntr.msx.library.ReactionLibrary` for more details. """ +from __future__ import annotations +import json import logging import os from typing import Any, ItemsView, Iterator, KeysView, List, Tuple, Union, ValuesView + from pkg_resources import resource_filename +from .base import ExpressionType, ReactionType, SpeciesType from .model import MsxModel -from .base import ReactionType, SpeciesType, ExpressionType - -import json try: import yaml @@ -49,10 +47,10 @@ def cite_msx() -> dict: """A citation generator for the EPANET-MSX user guide. - References - ---------- - [SRU23]_ Shang, F. and Rossman, L.A. and Uber, J.G. (2023) "EPANET-MSX 2.0 User Manual". (Cincinnati, OH: Water Infrastructure Division (CESER), U.S. Environmental Protection Agency). EPA/600/R-22/199. - + Returns + ------- + str + Shang, F. and Rossman, L.A. and Uber, J.G. (2023) "EPANET-MSX 2.0 User Manual". (Cincinnati, OH: Water Infrastructure Division (CESER), U.S. Environmental Protection Agency). EPA/600/R-22/199. """ return 'Shang, F. and Rossman, L.A. and Uber, J.G. (2023) "EPANET-MSX 2.0 User Manual". (Cincinnati, OH: Water Infrastructure Division (CESER), U.S. Environmental Protection Agency). EPA/600/R-22/199.' # return dict( @@ -75,9 +73,7 @@ class ReactionLibrary: This object can be accessed and treated like a dictionary, where keys are the model names and the values are the model objects. - The initialization sets up a list of paths, but *will not* - automatically read the files in them (use :meth:`load_all` for this). - The paths are added in the following order: + Paths are added/processed in the following order: 1. the builtin directory of reactions, 2. any paths specified in the environment variable described below, with directories listed @@ -85,9 +81,7 @@ class ReactionLibrary: 3. any extra paths specified in the constructor, searched in the order provided. Once created, the library paths cannot be modified. However, a model can be added - to the library using the :meth:`add_model_from_file` or :meth:`add_models_from_dir` - methods. The precedence of the directories can be reversed based on the ``duplicates`` - argument passed to these functions. + to the library using :meth:`add_model_from_file` or :meth:`add_models_from_dir`. """ def __init__(self, extra_paths: List[str] = None, include_builtins=True, include_envvar_paths=True, load=True) -> None: @@ -95,17 +89,17 @@ def __init__(self, extra_paths: List[str] = None, include_builtins=True, include Parameters ---------- - extra_paths : List[str], optional - _description_, by default None + extra_paths : list of str, optional + user-specified list of reaction library directories, by default None include_builtins : bool, optional load files built-in with wntr, by default True include_envvar_paths : bool, optional load files from the paths specified in :envvar:`WNTR_RXN_LIBRARY_PATH`, by default True - load : bool, optional - load the files immediately on creation, by default True + load : bool or str, optional + load the files immediately on creation, by default True. - If this is a string, then it will be passed as the `duplicates` argument - to the load function. See :meth:`reset_and_reload` for more details. + If a string, then it will be passed as the `duplicates` argument + to the load function. See :meth:`reset_and_reload` for details. Raises ------ @@ -144,9 +138,7 @@ def __init__(self, extra_paths: List[str] = None, include_builtins=True, include def __repr__(self) -> str: if len(self.__library_paths) > 3: - return "{}(initial_paths=[{}, ..., {}])".format( - self.__class__.__name__, repr(self.__library_paths[0]), repr(self.__library_paths[-1]) - ) + return "{}(initial_paths=[{}, ..., {}])".format(self.__class__.__name__, repr(self.__library_paths[0]), repr(self.__library_paths[-1])) return "{}({})".format(self.__class__.__name__, repr(self.__library_paths)) def path_list(self) -> List[str]: @@ -154,7 +146,7 @@ def path_list(self) -> List[str]: Returns ------- - List[str] + list of str a copy of the paths used to **initially** populate this library """ return self.__library_paths.copy() @@ -167,25 +159,30 @@ def reset_and_reload(self, duplicates: str = "error") -> List[Tuple[str, str, An The ``duplicates`` argument specifies how models that have the same name, or that have the same filename if a name isn't specified in the file, - are handled. This effectively changes the priority of the library's data - directories specified during library creation. - **Warning**, if two files in the same directory have models + are handled. **Warning**, if two files in the same directory have models with the same name, there is no guarantee which will be read in first. + The first directory processed is the builtin library data. Next, any + paths specified in the environment variable are searched in the order listed + in the variable. Finally, any directories specified by the user in the + constructor are processed in the order listed. + Parameters ---------- duplicates : {"error" | "skip" | "replace"}, optional - how to handle models with the same name, by default ``"error"``. - - A value of of ``"error"`` raises an exception and stops execution. A value of ``"skip"`` will - skip models with the same `name` as a model that already exists in the - library (prioritizing directories as described in the :class:`ReactionLibrary` - documentation). A value of ``"replace"`` will replace any existing model - with a model that is read in that has the same `name` (effecitvely, this - reverses the precedence of the library's configured directories by - prioritizing models in the last - user-specified directories, then models in the paths in envvar in reverse order, if - applicable, and giving lowest priority to builtin models). + by default ``"error"`` + + - A value of of ``"error"`` raises an exception and stops execution. + - A value of ``"skip"`` will skip models with the same `name` as a model that already + exists in the library. + - A value of ``"replace"`` will replace any existing model with a model that is read + in that has the same `name`. + + Returns + ------- + (filename, reason, obj) : (str, str, Any) + the file not read in, the cause of the problem, and the object that was skipped/overwritten + or the exception raised Raises ------ @@ -197,16 +194,6 @@ def reset_and_reload(self, duplicates: str = "error") -> List[Tuple[str, str, An if `path_to_folder` is not a directory KeyError if `duplicates` is ``"error"`` and two models have the same name - - Returns - ------- - List[Tuple[str, str, Any]] - files that caused problems, with tuple elements: - - 0. the full path to the file that caused a problem; - 1. the reason for the problem; - 2. the model that was *not* included, or was removed, - or the exception that was raised when trying to read the file """ if duplicates and not isinstance(duplicates, str): raise TypeError("The `duplicates` argument must be None or a string") @@ -229,18 +216,24 @@ def add_models_from_dir(self, path_to_dir: str, duplicates: str = "error") -> Li are handled. **Warning**, if two files in the same directory have models with the same name, there is no guarantee which will be read in first. - Parameters ---------- path_to_dir : str the path to the folder to search duplicates : {"error", "skip", "replace"}, optional - how to handle models with the same name, by default ``"error"`` + by default ``"error"`` - A value of of ``"error"`` raises an exception and stops execution. A value - of ``"skip"`` will skip models with the same `name` as a model that already - exists in the library. A value of ``"replace"`` will replace any existing model - with a model that is read in that has the same `name`. + - A value of of ``"error"`` raises an exception and stops execution. + - A value of ``"skip"`` will skip models with the same `name` as a model that already + exists in the library. + - A value of ``"replace"`` will replace any existing model with a model that is read + in that has the same `name`. + + Returns + ------- + (filename, reason, obj) : tuple[str, str, Any] + the file not read in, the cause of the problem, and the object that was skipped/overwritten + or the exception raised Raises ------ @@ -252,15 +245,6 @@ def add_models_from_dir(self, path_to_dir: str, duplicates: str = "error") -> Li if `path_to_folder` is not a directory KeyError if `duplicates` is ``"error"`` and two models have the same name - - Returns - ------- - str - the full path to the file that caused a problem; - str - the reason for the problem; - object - the model that was not included, was removed, or the exception raised """ if duplicates and not isinstance(duplicates, str): raise TypeError("The `duplicates` argument must be None or a string") @@ -312,11 +296,7 @@ def add_models_from_dir(self, path_to_dir: str, duplicates: str = "error") -> Li else: # this name exists in the library name = new.name if not duplicates or duplicates.lower() == "error": - raise KeyError( - 'A model named "{}" already exists in the model; failed processing "{}"'.format( - new.name, os.path.join(folder, file) - ) - ) + raise KeyError('A model named "{}" already exists in the model; failed processing "{}"'.format(new.name, os.path.join(folder, file))) elif duplicates.lower() == "skip": load_errors.append((new._orig_file, "skipped", new)) continue @@ -338,10 +318,10 @@ def add_model_from_file(self, path_and_filename: str, name: str = None): Parameters ---------- path_to_file : str - The full path **and** filename where the model is described. - name : str + The full path and filename where the model is described. + name : str, optional The name to use for the model instead of the name provided in the - file or the filename. + file or the filename, by default None """ if not os.path.isfile(path_and_filename): raise IOError("The following path does not identify a file, {}".format(path_and_filename)) @@ -369,7 +349,7 @@ def add_model_from_file(self, path_and_filename: str, name: str = None): self.__data[new.name] = new def get_model(self, name: str) -> MsxModel: - """Get a reaction model from the library by model name + """Get a reaction model from the library by model name. Parameters ---------- @@ -378,13 +358,19 @@ def get_model(self, name: str) -> MsxModel: Returns ------- - MultispeciesQualityModel - the model + MsxModel + the model object """ return self.__data[name] def model_name_list(self) -> List[str]: - """Get a list of model names in the library""" + """Get the names of all models in the library. + + Returns + ------- + list of str + list of model names + """ return list(self.keys()) def __getitem__(self, __key: Any) -> Any: diff --git a/wntr/msx/model.py b/wntr/msx/model.py index 18d6343ad..788f925cb 100644 --- a/wntr/msx/model.py +++ b/wntr/msx/model.py @@ -1,35 +1,31 @@ # -*- coding: utf-8 -*- -"""Water quality model implementations. +"""The WNTR MSX model. """ +from __future__ import annotations import logging - -from typing import ( - Any, - Dict, - List, - Union, -) import warnings +from typing import Any, Dict, Generator, List, NewType, Union +from wntr.epanet.util import ENcomment, NoteType - -from wntr.msx.elements import Constant, HydraulicVariable, InitialQuality, MathFunction, Parameter, ParameterValues, Reaction, Species, Term from wntr.utils.disjoint_mapping import KeyExistsError + from .base import ( - NetworkData, - AbstractModel, - AbstractReaction, - ReactionSystem, - AbstractVariable, - HYDRAULIC_VARIABLES, EXPR_FUNCTIONS, + HYDRAULIC_VARIABLES, + QualityModelBase, + ReactionBase, + NetworkDataBase, + ReactionSystemBase, + VariableBase, ExpressionType, ReactionType, - VariableType, SpeciesType, + VariableType, ) -from .options import MultispeciesOptions +from .elements import Constant, HydraulicVariable, InitialQuality, MathFunction, Parameter, ParameterValues, Reaction, Species, Term +from .options import MsxSolverOptions has_sympy = False try: @@ -48,18 +44,14 @@ logger = logging.getLogger(__name__) -__all__ = [ - "MsxNetworkData", - "MsxReactionSystem", - "MsxModel", -] +MsxVariable = Union[Constant, HydraulicVariable, MathFunction, Parameter, Species, Term] +"""A class that is a valid MSX variable class""" -class MsxReactionSystem(ReactionSystem): +class MsxReactionSystem(ReactionSystemBase): """A registry for all the variables registered in the multispecies reactions model. - This object can be used like an immutable mapping, with the ``__len__``, ``__getitem__``, - ``__iter__``, ``__contains__``, ``__eq__`` and ``__ne__`` functions being defined. + This object can be used like a mapping. """ def __init__(self) -> None: @@ -95,68 +87,68 @@ def terms(self) -> Dict[str, Term]: return self._term @property - def pipe_reactions(self) -> Dict[str, AbstractReaction]: + def pipe_reactions(self) -> Dict[str, Reaction]: """The dictionary view onto pipe reactions""" return self._pipes @property - def tank_reactions(self) -> Dict[str, AbstractReaction]: + def tank_reactions(self) -> Dict[str, Reaction]: """The dictionary view onto tank reactions""" return self._tanks - def add_variable(self, obj: AbstractVariable) -> None: + def add_variable(self, variable: MsxVariable) -> None: """Add a variable object to the registry. The appropriate group is determined by querying the object's var_type attribute. - Arguments - --------- - obj : WaterQualityVariable + Parameters + ---------- + variable The variable to add. Raises ------ TypeError - if obj is not a WaterQualityVariable + if `variable` is not an MsxVariable KeyExistsError - if obj has a name that is already used in the registry + if `variable` has a name that is already used in the registry """ - if not isinstance(obj, AbstractVariable): - raise TypeError("Expected WaterQualityVariable object") - if obj.name in self: - raise KeyExistsError("Variable name {} already exists in model".format(obj.name)) - obj._vars = self - self._vars.add_item_to_group(obj.var_type.name.lower(), obj.name, obj) - - def add_reaction(self, obj: AbstractReaction) -> None: + if not isinstance(variable, (Species, Constant, Parameter, Term, MathFunction, HydraulicVariable)): + raise TypeError("Expected AVariable object") + if variable.name in self: + raise KeyExistsError("Variable name {} already exists in model".format(variable.name)) + variable._vars = self + self._vars.add_item_to_group(variable.var_type.name.lower(), variable.name, variable) + + def add_reaction(self, reaction: Reaction) -> None: """Add a reaction to the model Parameters ---------- - obj : WaterQualityReaction - _description_ + reaction : Reaction + a water quality reaction definition Raises ------ TypeError - _description_ + if `reaction` is not a Reaction KeyError - _description_ + if the `species_name` in the `reaction` does not exist in the model """ - if not isinstance(obj, AbstractReaction): - raise TypeError("Expected WaterQualityReaction object") - if obj.species_name not in self: - raise KeyError("Species {} does not exist in the model".format(obj.species_name)) - self._rxns[obj.reaction_type.name.lower()][obj.species_name] = obj + if not isinstance(reaction, Reaction): + raise TypeError("Expected a Reaction object") + if reaction.species_name not in self: + raise KeyError("Species {} does not exist in the model".format(reaction.species_name)) + self._rxns[reaction.reaction_type.name.lower()][reaction.species_name] = reaction - def variables(self): + def variables(self) -> Generator[tuple, None, None]: # FIXME: rename without "all_" for this """A generator looping through all variables""" for k, v in self._vars.items(): yield k, v.var_type.name.lower(), v - def reactions(self): + def reactions(self) -> Generator[tuple, None, None]: """A generator looping through all reactions""" for k2, v in self._rxns.items(): for k1, v1 in v.items(): @@ -173,12 +165,10 @@ def to_dict(self) -> dict: ) -class MsxNetworkData(NetworkData): +class MsxNetworkData(NetworkDataBase): """A container for network-specific values associated with a multispecies water quality model.""" - def __init__( - self, patterns: dict = None, sources: dict = None, initial_quality: dict = None, parameter_values: dict = None - ) -> None: + def __init__(self, patterns: Dict[str, List[float]] = None, sources: Dict[str, Dict[str, dict]] = None, initial_quality: Dict[str, Union[dict,InitialQuality]] = None, parameter_values: Dict[str, Union[dict, ParameterValues]] = None) -> None: """A container for network-specific values associated with a multispecies water quality model. Data is copied from dictionaries passed in, so once created, the dictionaries passed are not connected @@ -186,14 +176,28 @@ def __init__( Parameters ---------- - patterns : Dict[str, List[float]] + patterns : dict, optional patterns to use for sources - sources : Dict[str, dict] + sources : dict, optional sources defined for the model - initial_quality : Dict[str, dict] + initial_quality : dict, optional initial values for different species at different nodes, links, and the global value - parameter_values : Dict[str, dict] + parameter_values : dict, optional parameter values for different pipes and tanks + + Notes + ----- + ``patterns`` + A dictionary keyed by pattern name (str) with values being the multipliers (list of float) + ``sources`` + A dictionary keyed by species name (str) with values being dictionaries keyed by junction name (str) with values being the + dictionary of settings for the source + ``initial_quality`` + A dictionary keyed by species name (str) with values being either an :class:`~wntr.msx.elements.InitialQuality` object or + the appropriate dictionary representation thereof. + ``parameter_values`` + A dictionary keyed by parameter name (str) with values being either a :class:`~wntr.msx.elements.ParameterValues` object or + the appropriate dictionary representation thereof. """ if sources is None: sources = dict() @@ -236,7 +240,7 @@ def patterns(self): return self._pattern_dict @property - def parameter_values(self): + def parameter_values(self) -> Dict[str, ParameterValues]: """A dictionary of parameter values, keyed by parameter name""" return self._parameter_value_dict @@ -247,7 +251,7 @@ def add_pattern(self, name: str, multipliers: List[float]): --------- name : str The pattern name - multipliers : List[float] + multipliers : list of float The pattern multipliers """ self._pattern_dict[name] = multipliers @@ -258,7 +262,7 @@ def init_new_species(self, species: Species): Arguments --------- species : Species - The species to (re) initialized. + The species to (re)initialized. Returns ------- @@ -275,8 +279,8 @@ def remove_species(self, species: Union[Species, str]): Arguments --------- - species : Union[Species, str] - _description_ + species : Species or str + a species to be removed from the network data """ if isinstance(species, Species): species._vals = None @@ -291,12 +295,12 @@ def init_new_parameter(self, param: Parameter): Arguments --------- param : Parameter - _description_ + a parameter to be (re)initialized with network data Returns ------- - _type_ - _description_ + ParameterValues + the new network data for the specific parameter """ self._parameter_value_dict[str(param)] = ParameterValues() if isinstance(param, Parameter): @@ -306,10 +310,12 @@ def init_new_parameter(self, param: Parameter): def remove_parameter(self, param: Union[Parameter, str]): """Remove values associated with a specific parameter. + Ignores non-parameters. + Arguments --------- - param : Union[Parameter, str] - _description_ + param : Parameter or str + the parameter or parameter name to be removed from the network data """ if isinstance(param, Parameter): param._vals = None @@ -329,7 +335,7 @@ def to_dict(self) -> dict: return ret -class MsxModel(AbstractModel): +class MsxModel(QualityModelBase): """A multispecies water quality model for use with WNTR EPANET-MSX simulator.""" def __init__(self, msx_file_name=None) -> None: @@ -342,9 +348,9 @@ def __init__(self, msx_file_name=None) -> None: """ super().__init__(msx_file_name) self._references: List[Union[str, Dict[str, str]]] = list() - self._options = MultispeciesOptions() - self._rxn_system = MsxReactionSystem() - self._net_data = MsxNetworkData() + self._options: MsxSolverOptions = MsxSolverOptions() + self._rxn_system: MsxReactionSystem = MsxReactionSystem() + self._net_data: MsxNetworkData = MsxNetworkData() self._wn = None for v in HYDRAULIC_VARIABLES: @@ -375,7 +381,7 @@ def references(self) -> List[Union[str, Dict[str, str]]]: """A list of strings or mappings that provide references for this model. .. note:: - This property is a list, and should be modified using append/insert/remove. + This property is a list, and should be modified using append/insert/remove. Members of the list should be json seriealizable (i.e., strings or dicts of strings). """ return self._references @@ -391,7 +397,7 @@ def network_data(self) -> MsxNetworkData: return self._net_data @property - def options(self) -> MultispeciesOptions: + def options(self) -> MsxSolverOptions: """The MSX model options""" return self._options @@ -416,10 +422,10 @@ def term_name_list(self) -> List[str]: return list(self.reaction_system.terms.keys()) @options.setter - def options(self, value): + def options(self, value: Union[dict, MsxSolverOptions]): if isinstance(value, dict): - self._options = MultispeciesOptions.factory(value) - elif not isinstance(value, MultispeciesOptions): + self._options = MsxSolverOptions.factory(value) + elif not isinstance(value, MsxSolverOptions): raise TypeError("Expected a MultispeciesOptions object, got {}".format(type(value))) else: self._options = value @@ -431,7 +437,7 @@ def add_species( units: str, atol: float = None, rtol: float = None, - note: Any = None, + note: NoteType = None, diffusivity: float = None, ) -> Species: """Add a species to the model @@ -439,37 +445,35 @@ def add_species( Arguments --------- name : str - _description_ + the species name species_type : SpeciesType - _description_ + the type of species, either BULK or WALL units : str - _description_ - atol : float, optional - _description_, by default None - rtol : float, optional - _description_, by default None - note : str | dict | ENcomment, optional - Supplementary information regarding this variable, by default None - (see :class:`~wntr.epanet.util.ENcomment` for dict structure). + the mass units for this species + atol : float, optional unless rtol is not None + the absolute solver tolerance for this species, by default None + rtol : float, optional unless atol is not None + the relative solver tolerance for this species, by default None + note : NoteType, optional keyword + supplementary information regarding this variable, by default None + (see also :class:`~wntr.epanet.util.ENcomment`) diffusivity : float, optional - Diffusivity in water for this species. + diffusivity of this species in water Raises ------ - KeyError - _description_ + KeyExistsError + if a variable with this name already exists + ValueError + if `atol` or `rtol` ≤ 0 Returns ------- Species - _description_ + the new species """ if name in self._rxn_system: - raise KeyError( - "Variable named {} already exists in model as type {}".format( - name, self._rxn_system._vars.get_groupname(name) - ) - ) + raise KeyExistsError("Variable named {} already exists in model as type {}".format(name, self._rxn_system._vars.get_groupname(name))) species_type = SpeciesType.get(species_type, allow_none=False) iq = self.network_data.init_new_species(name) new = Species( @@ -486,165 +490,178 @@ def add_species( self.reaction_system.add_variable(new) return new - def remove_species(self, species): + def remove_species(self, variable_or_name): """Remove a species from the model. Removes from both the reaction_system and the network_data. - Arguments - --------- - species : _type_ - _description_ + Parameters + ---------- + variable_or_name : Species or str + the species (or name of the species) to be removed + + Raises + ------ + KeyError + if `variable_or_name` is not a species in the model """ - name = str(species) + name = str(variable_or_name) + if name not in self.reaction_system.species: + raise KeyError('The specified variable is not a registered species in the reaction system') self.network_data.remove_species(name) # FIXME: validate additional items self.reaction_system.__delitem__(name) - def add_constant(self, name: str, value: float, units: str = None, note: Any = None) -> Constant: + def add_constant(self, name: str, value: float, units: str = None, note: NoteType = None) -> Constant: """Add a constant coefficient to the model. Arguments --------- name : str - _description_ + the name of the coefficient value : float - _description_ + the constant value of the coefficient units : str, optional - _description_, by default None - note : str | dict | ENcomment, optional - Supplementary information regarding this variable, by default None - (see :class:`~wntr.epanet.util.ENcomment` for dict structure). + the units for this coefficient, by default None + note : NoteType, optional + supplementary information regarding this variable, by default None Raises ------ - KeyError - _description_ + KeyExistsError + a variable with this name already exists Returns ------- Constant - _description_ + the new constant coefficient """ if name in self._rxn_system: - raise KeyError( - "Variable named {} already exists in model as type {}".format( - name, self._rxn_system._vars.get_groupname(name) - ) - ) + raise KeyExistsError("Variable named {} already exists in model as type {}".format(name, self._rxn_system._vars.get_groupname(name))) new = Constant(name=name, value=value, units=units, note=note, _vars=self._rxn_system) self.reaction_system.add_variable(new) return new - def remove_constant(self, const): + def remove_constant(self, variable_or_name): """Remove a constant coefficient from the model. - Arguments - --------- - const : _type_ - _description_ + Parameters + ---------- + variable_or_name : Constant or str + the constant (or name of the constant) to be removed + + Raises + ------ + KeyError + if `variable_or_name` is not a constant coefficient in the model """ - name = str(const) + name = str(variable_or_name) + if name not in self.reaction_system.constants: + raise KeyError('The specified variable is not a registered constant in the reaction system') # FIXME: validate deletion self.reaction_system.__delitem__(name) - def add_parameter(self, name: str, global_value: float, units: str = None, note: Any = None) -> Parameter: + def add_parameter(self, name: str, global_value: float, units: str = None, note: NoteType = None) -> Parameter: """Add a parameterized coefficient to the model. Arguments --------- name : str - _description_ + the name of the parameter global_value : float - _description_ + the global value of the coefficient (can be overridden for specific pipes/tanks) units : str, optional - _description_, by default None - note : str | dict | ENcomment, optional + the units for the coefficient, by default None + note : NoteType, optional keyword Supplementary information regarding this variable, by default None - (see :class:`~wntr.epanet.util.ENcomment` for dict structure). + (see also :class:`~wntr.epanet.util.ENcomment`). Raises ------ - KeyError - _description_ + KeyExistsError + if a variable with this name already exists Returns ------- Parameter - _description_ + the new parameterized coefficient """ if name in self._rxn_system: - raise KeyError( - "Variable named {} already exists in model as type {}".format( - name, self._rxn_system._vars.get_groupname(name) - ) - ) + raise KeyExistsError("Variable named {} already exists in model as type {}".format(name, self._rxn_system._vars.get_groupname(name))) pv = self.network_data.init_new_parameter(name) new = Parameter(name=name, global_value=global_value, units=units, note=note, _vars=self._rxn_system, _vals=pv) self.reaction_system.add_variable(new) return new - def remove_parameter(self, param): + def remove_parameter(self, variable_or_name): """Remove a parameterized coefficient from the model. - Arguments - --------- - param : _type_ - _description_ + Parameters + ---------- + variable_or_name : Parameter or str + the parameter (or name of the parameter) to be removed + + Raises + ------ + KeyError + if `variable_or_name` is not a parameter in the model """ - name = str(param) + name = str(variable_or_name) + if name not in self.reaction_system.parameters: + raise KeyError('The specified variable is not a registered parameter in the reaction system') self.network_data.remove_parameter(name) # FIXME: validate additional items self.reaction_system.__delitem__(name) - def add_term(self, name: str, expression: str, note: Any = None) -> Term: + def add_term(self, name: str, expression: str, note: NoteType = None) -> Term: """Add a named expression (term) to the model. - Arguments - --------- + Parameters + ---------- name : str - _description_ + the name of the functional term to be added expression : str - _description_ - note : str | dict | ENcomment, optional + the expression that the term defines + note : NoteType, optional keyword Supplementary information regarding this variable, by default None - (see :class:`~wntr.epanet.util.ENcomment` for dict structure). + (see also :class:`~wntr.epanet.util.ENcomment`) Raises ------ - KeyError - _description_ + KeyExistsError + if a variable with this name already exists Returns ------- Term - _description_ + the new term """ if name in self._rxn_system: - raise KeyError( - "Variable named {} already exists in model as type {}".format( - name, self._rxn_system._vars.get_groupname(name) - ) - ) + raise KeyError("Variable named {} already exists in model as type {}".format(name, self._rxn_system._vars.get_groupname(name))) new = Term(name=name, expression=expression, note=note, _vars=self._rxn_system) self.reaction_system.add_variable(new) return new - def remove_term(self, term): + def remove_term(self, variable_or_name): """Remove a named expression (term) from the model. - Arguments - --------- - term : _type_ - _description_ + Parameters + ---------- + variable_or_name : Term or str + the term (or name of the term) to be deleted + + Raises + ------ + KeyError + if `variable_or_name` is not a term in the model """ - name = str(term) + name = str(variable_or_name) # FIXME: validate deletion + if name not in self.reaction_system.terms: + raise KeyError('The specified variable is not a registered term in the reaction system') self.reaction_system.__delitem__(name) - def add_reaction( - self, species_name: str, reaction_type: ReactionType, expression_type: ExpressionType, expression: str, note: Any = None - ) -> AbstractReaction: + def add_reaction(self, species_name: Union[Species, str], reaction_type: ReactionType, expression_type: ExpressionType, expression: str, note: NoteType = None) -> ReactionBase: """Add a reaction to a species in the model. Note that all species need to have both a pipe and tank reaction defined @@ -656,27 +673,27 @@ def add_reaction( Arguments --------- - species_name : str - _description_ - location_type : LocationType - _description_ + species_name : Species or str + the species (or name of species) the reaction is being defined for + reaction_type: ReactionType + where this reaction takes place, from {PIPE, TANK} expression_type : ExpressionType - _description_ + the type (LHS) of the equation the expression belongs to, from {RATE, EQUIL, FORMULA} expression : str - _description_ - note : str | dict | ENcomment, optional + the expression defining the reaction + note : NoteType, optional keyword Supplementary information regarding this reaction, by default None - (see :class:`~wntr.epanet.util.ENcomment` for dict structure). + (see also :class:`~wntr.epanet.util.ENcomment`) Raises ------ TypeError - _description_ + if a variable that is not species is passed Returns ------- MultispeciesReaction - _description_ + the new reaction object """ species_name = str(species_name) species = self.reaction_system.species[species_name] @@ -699,10 +716,10 @@ def remove_reaction(self, species_name: str, reaction_type: ReactionType) -> Non Parameters ---------- - species : str - the species name to remove the reaction from - location : LocationType - the location to remove the reaction from + species : Species or str + the species (or name of the species) of the reaction to remove + reaction_type : ReactionType + the reaction type (location) of the reaction to remove """ reaction_type = ReactionType.get(reaction_type, allow_none=False) species_name = str(species_name) @@ -723,7 +740,14 @@ def to_dict(self) -> dict: } @classmethod - def from_dict(cls, data) -> 'MsxModel': + def from_dict(cls, data) -> "MsxModel": + """Create a new multispecies reaction model from a dictionary. + + Parameters + ---------- + data : dict + The model data + """ from wntr import __version__ ver = data.get("wntr-version", None) diff --git a/wntr/msx/options.py b/wntr/msx/options.py index b91c2c9f9..e99645352 100644 --- a/wntr/msx/options.py +++ b/wntr/msx/options.py @@ -9,7 +9,8 @@ logger = logging.getLogger(__name__) -class ReportOptions(_OptionsBase): + +class MsxReportOptions(_OptionsBase): """ Options related to EPANET-MSX report outputs. """ @@ -69,8 +70,7 @@ def __setattr__(self, name, value): self.__dict__[name] = value - -class MultispeciesOptions(_OptionsBase): +class MsxSolverOptions(_OptionsBase): """ Multispecies quality model options. """ @@ -88,7 +88,7 @@ def __init__( segments: int = 5000, peclet: int = 1000, # global_initial_quality: Dict[str, float] = None, - report: ReportOptions = None, + report: MsxReportOptions = None, ): """ Multispecies quality model options. @@ -139,14 +139,14 @@ def __init__( """The number of segments per-pipe to use, by default 5000.""" self.peclet: int = peclet """The threshold for applying dispersion, by default 1000.""" - self.report: ReportOptions = ReportOptions.factory(report) + self.report: MsxReportOptions = MsxReportOptions.factory(report) """The reporting output options.""" def __setattr__(self, name, value): if name == "report": - if not isinstance(value, (ReportOptions, dict, tuple, list)): + if not isinstance(value, (MsxReportOptions, dict, tuple, list)): raise ValueError("report must be a ReportOptions or convertable object") - value = ReportOptions.factory(value) + value = MsxReportOptions.factory(value) elif name in {"timestep"}: try: value = max(1, int(value)) From 1f8c3dd3272bb64197dad1c79be5f3fb1b527351 Mon Sep 17 00:00:00 2001 From: dbhart Date: Thu, 9 Nov 2023 14:38:55 -0700 Subject: [PATCH 36/75] Delete test file --- wntr/tests/test_quality_variables.py | 250 --------------------------- 1 file changed, 250 deletions(-) delete mode 100644 wntr/tests/test_quality_variables.py diff --git a/wntr/tests/test_quality_variables.py b/wntr/tests/test_quality_variables.py deleted file mode 100644 index 142e33049..000000000 --- a/wntr/tests/test_quality_variables.py +++ /dev/null @@ -1,250 +0,0 @@ -import unittest -import warnings -from os.path import abspath, dirname, join - -import numpy as np -import pandas as pd -import wntr -import wntr.msx -import sympy - -testdir = dirname(abspath(str(__file__))) -test_network_dir = join(testdir, "networks_for_testing") -test_data_dir = join(testdir, "data_for_testing") -ex_datadir = join(testdir, "..", "..", "examples", "networks") - - -class Test(unittest.TestCase): - @classmethod - def setUpClass(self): - pass - - @classmethod - def tearDownClass(self): - pass - - def test_ReactionVariable_reserved_name_exception(self): - self.assertRaises(ValueError, wntr.msx.Species, 'bulk', "D", "mg") - self.assertRaises(ValueError, wntr.msx.Species, 'wall', "Q", "mg") - self.assertRaises(ValueError, wntr.msx.Constant, "Re", 0.52) - self.assertRaises(ValueError, wntr.msx.Parameter, "Re", 0.52) - self.assertRaises(ValueError, wntr.msx.OtherTerm, "Re", 0.52) - - def test_RxnVariable_symbols_and_sympy(self): - species1 = wntr.msx.Species('BULK', "Cl", "mg") - symbol1 = sympy.symbols("Cl") - self.assertEqual(species1.symbol, symbol1) - - const1 = wntr.msx.Constant("Kb", 0.482) - symbol2 = sympy.symbols("Kb") - self.assertEqual(const1.symbol, symbol2) - - param1 = wntr.msx.Constant("Ka", 0.482) - symbol3 = sympy.symbols("Ka") - self.assertEqual(param1.symbol, symbol3) - - term1 = wntr.msx.OtherTerm("T0", "-3.2 * Kb * Cl^2", note="bar") - symbol4 = sympy.symbols("T0") - self.assertEqual(term1.symbol, symbol4) - - def test_RxnVariable_values(self): - const1 = wntr.msx.Constant("Kb", 0.482, note="test") - self.assertEqual(const1.get_value(), const1.global_value) - test_pipe_dict = {"PIPE": 0.38} - test_tank_dict = {"TANK": 222.23} - param2 = wntr.msx.Parameter("Kb", 0.482, note="test", pipe_values=test_pipe_dict, tank_values=test_tank_dict) - self.assertEqual(param2.get_value(), param2.global_value) - self.assertEqual(param2.get_value(pipe="PIPE"), test_pipe_dict["PIPE"]) - self.assertEqual(param2.get_value(pipe="FOO"), param2.global_value) - self.assertEqual(param2.get_value(tank="TANK"), test_tank_dict["TANK"]) - self.assertRaises(TypeError, param2.get_value, pipe="PIPE", tank="TANK") - - def test_RxnVariable_string_functions(self): - species1 = wntr.msx.Species('BULK', "Cl", "mg") - species2 = wntr.msx.Species('WALL', "Cl", "mg", 0.01, 0.0001, note="Testing stuff") - const1 = wntr.msx.Constant("Kb", 0.482) - param1 = wntr.msx.Parameter("Ka", 0.482, note="foo") - term1 = wntr.msx.OtherTerm("T0", "-3.2 * Kb * Cl^2", note="bar") - - self.assertEqual(str(species1), "Cl") - self.assertEqual(str(const1), "Kb") - self.assertEqual(str(param1), "Ka") - self.assertEqual(str(term1), "T0") - - def test_Species_tolerances(self): - # """RxnSpecies(*s) tolerance settings""" - species1 = wntr.msx.Species("B", "Cl", "mg") - species2 = wntr.msx.Species("W", "Cl", "mg", 0.01, 0.0001, note="Testing stuff") - self.assertIsNone(species1.get_tolerances()) - self.assertIsNotNone(species2.get_tolerances()) - self.assertTupleEqual(species2.get_tolerances(), (0.01, 0.0001)) - self.assertRaises(TypeError, species1.set_tolerances, None, 0.0001) - self.assertRaises(ValueError, species1.set_tolerances, -0.51, 0.01) - self.assertRaises(ValueError, species1.set_tolerances, 0.0, 0.0) - species1.set_tolerances(0.01, 0.0001) - self.assertEqual(species1._atol, 0.01) - self.assertEqual(species1._rtol, 0.0001) - species1.set_tolerances(None, None) - self.assertIsNone(species1._atol) - self.assertIsNone(species1._rtol) - species2.clear_tolerances() - self.assertIsNone(species1._atol) - self.assertIsNone(species1._rtol) - self.assertIsNone(species2.get_tolerances()) - - def test_BulkSpecies_creation(self): - # """BlukSpecies object creation (direct instantiation)""" - self.assertRaises(TypeError, wntr.msx.Species, "b", "Re") - self.assertRaises(ValueError, wntr.msx.Species, "B", "Re", "mg") - self.assertRaises(TypeError, wntr.msx.Species, 1, "Cl", "mg", 0.01) - self.assertRaises(TypeError, wntr.msx.Species, wntr.msx.base.SpeciesType.BULK, "Cl", "mg", None, 0.01) - species = wntr.msx.Species(1, "Cl", "mg") - self.assertEqual(species.name, "Cl") - self.assertEqual(species.units, "mg") - self.assertEqual(species.var_type, wntr.msx.SpeciesType.BULK) - self.assertIsNone(species._atol) - self.assertIsNone(species._rtol) - self.assertIsNone(species.note) - species = wntr.msx.Species('b', "Cl", "mg", 0.01, 0.0001, note="Testing stuff") - self.assertEqual(species.var_type, wntr.msx.SpeciesType.BULK) - self.assertEqual(species.name, "Cl") - self.assertEqual(species.units, "mg") - self.assertEqual(species._atol, 0.01) - self.assertEqual(species._rtol, 0.0001) - self.assertEqual(species.note, "Testing stuff") - - def test_WallSpecies_creation(self): - # """WallSpecies object creation (direct instantiation)""" - self.assertRaises(TypeError, wntr.msx.Species, 'W', "Re") - self.assertRaises(ValueError, wntr.msx.Species, 'Wall', "Re", "mg") - self.assertRaises(TypeError, wntr.msx.Species, 2, "Cl", "mg", 0.01) - self.assertRaises(TypeError, wntr.msx.Species, 'W', "Cl", "mg", None, 0.01) - species = wntr.msx.Species('w', "Cl", "mg") - self.assertEqual(species.name, "Cl") - self.assertEqual(species.units, "mg") - self.assertEqual(species.var_type, wntr.msx.SpeciesType.WALL) - self.assertIsNone(species._atol) - self.assertIsNone(species._rtol) - self.assertIsNone(species.note) - species = wntr.msx.Species('w', "Cl", "mg", 0.01, 0.0001, note="Testing stuff") - self.assertEqual(species.var_type, wntr.msx.SpeciesType.WALL) - self.assertEqual(species.name, "Cl") - self.assertEqual(species.units, "mg") - self.assertEqual(species._atol, 0.01) - self.assertEqual(species._rtol, 0.0001) - self.assertEqual(species.note, "Testing stuff") - - def test_Constant_creation(self): - self.assertRaises(TypeError, wntr.msx.Constant, "Re") - self.assertRaises(ValueError, wntr.msx.Constant, "Re", 2.48) - const1 = wntr.msx.Constant("Kb", 0.482, note="test") - # FIXME: Find a way to suppress warning printing - # self.assertWarns(RuntimeWarning, wntr.reaction.Constant, 'Kb1', 0.83, pipe_values={'a',1}) - self.assertEqual(const1.name, "Kb") - self.assertEqual(const1.global_value, 0.482) - self.assertEqual(const1.get_value(), const1.global_value) - self.assertEqual(const1.var_type, wntr.msx.VariableType.CONST) - self.assertEqual(const1.note, "test") - - def test_Parameter_creation(self): - self.assertRaises(TypeError, wntr.msx.Parameter, "Re") - self.assertRaises(ValueError, wntr.msx.Parameter, "Re", 2.48) - param1 = wntr.msx.Parameter("Kb", 0.482, note="test") - self.assertEqual(param1.name, "Kb") - self.assertEqual(param1.global_value, 0.482) - self.assertEqual(param1.get_value(), param1.global_value) - self.assertEqual(param1.var_type, wntr.msx.VariableType.PARAM) - self.assertEqual(param1.note, "test") - test_pipe_dict = {"PIPE": 0.38} - test_tank_dict = {"TANK": 222.23} - param2 = wntr.msx.Parameter("Kb", 0.482, note="test", pipe_values=test_pipe_dict, tank_values=test_tank_dict) - self.assertDictEqual(param2.pipe_values, test_pipe_dict) - self.assertDictEqual(param2.tank_values, test_tank_dict) - - def test_RxnTerm_creation(self): - self.assertRaises(TypeError, wntr.msx.OtherTerm, "Re") - self.assertRaises(ValueError, wntr.msx.OtherTerm, "Re", "1.0*Re") - term1 = wntr.msx.OtherTerm("T0", "-3.2 * Kb * Cl^2", note="bar") - self.assertEqual(term1.name, "T0") - self.assertEqual(term1.expression, "-3.2 * Kb * Cl^2") - self.assertEqual(term1.var_type, wntr.msx.VariableType.TERM) - self.assertEqual(term1.note, "bar") - - def test_RxnExpression_strings(self): - equil1 = wntr.msx.EquilibriumDynamics("Cl", wntr.msx.ReactionType.PIPE, "-Ka + Kb * Cl + T0") - rate1 = wntr.msx.TankReaction("Cl", wntr.msx.ReactionType.TANK, "-Ka + Kb * Cl + T0", note="Foo Bar") - formula1 = wntr.msx.PipeReaction("Cl", wntr.msx.ReactionType.PIPE, "-Ka + Kb * Cl + T0") - - def test_Equilibrium_creation(self): - equil1 = wntr.msx.EquilibriumDynamics("Cl", wntr.msx.ReactionType.PIPE, "-Ka + Kb * Cl + T0") - self.assertEqual(equil1.species, "Cl") - self.assertEqual(equil1.expression, "-Ka + Kb * Cl + T0") - self.assertEqual(equil1.dynamics, wntr.msx.ExpressionType.EQUIL) - - def test_Rate_creation(self): - rate1 = wntr.msx.TankReaction("Cl", wntr.msx.ReactionType.TANK, "-Ka + Kb * Cl + T0", note="Foo Bar") - self.assertEqual(rate1.species_name, "Cl") - self.assertEqual(rate1.expression, "-Ka + Kb * Cl + T0") - self.assertEqual(rate1.dynamics, wntr.msx.ExpressionType.RATE) - self.assertEqual(rate1.note, "Foo Bar") - - def test_Formula_creation(self): - formula1 = wntr.msx.FormulaDynamics("Cl", wntr.msx.ReactionType.PIPE, "-Ka + Kb * Cl + T0") - self.assertEqual(formula1.species, "Cl") - self.assertEqual(formula1.expression, "-Ka + Kb * Cl + T0") - self.assertEqual(formula1.dynamics, wntr.msx.ExpressionType.FORMULA) - - def test_WaterQualityReactionsModel_creation_specific_everything(self): - rxn_model1 = wntr.msx.MsxModel() - bulk1 = wntr.msx.Species('b',"Cl", "mg") - wall1 = wntr.msx.Species('w', "ClOH", "mg", 0.01, 0.0001, note="Testing stuff") - const1 = wntr.msx.Constant("Kb", 0.482) - param1 = wntr.msx.Parameter("Ka", 0.482, note="foo") - term1 = wntr.msx.OtherTerm("T0", "-3.2 * Kb * Cl^2", note="bar") - equil1 = wntr.msx.EquilibriumDynamics(bulk1, wntr.msx.ReactionType.PIPE, "-Ka + Kb * Cl + T0") - rate1 = wntr.msx.TankReaction(bulk1, wntr.msx.ReactionType.TANK, "-Ka + Kb * Cl + T0", note="Foo Bar") - formula1 = wntr.msx.FormulaDynamics(wall1, wntr.msx.ReactionType.PIPE, "-Ka + Kb * Cl + T0") - - bulk2 = rxn_model1.add_bulk_species("Cl", "mg") - wall2 = rxn_model1.add_wall_species("ClOH", "mg", 0.01, 0.0001, note="Testing stuff") - const2 = rxn_model1.add_constant("Kb", 0.482) - param2 = rxn_model1.add_parameter("Ka", 0.482, note="foo") - term2 = rxn_model1.add_other_term("T0", "-3.2 * Kb * Cl^2", note="bar") - equil2 = rxn_model1.add_pipe_reaction("Cl", "equil", "-Ka + Kb * Cl + T0") - rate2 = rxn_model1.add_tank_reaction("Cl", wntr.msx.ExpressionType.R, "-Ka + Kb * Cl + T0", note="Foo Bar") - formula2 = rxn_model1.add_reaction("PIPE", "ClOH", "formula", "-Ka + Kb * Cl + T0") - self.assertEqual(bulk1, bulk2) - self.assertEqual(wall1, wall2) - self.assertEqual(const1, const2) - # self.assertEqual(param1, param2) # No good way to compare dicts inside - self.assertEqual(term1, term2) - # self.assertEqual(equil1, equil2) - # self.assertEqual(rate1, rate2) - # self.assertEqual(formula1, formula2) - - def test_WaterQualityReactionsModel_creation_generic_species_coeffs(self): - bulk1 = wntr.msx.Species('b', "Cl", "mg") - wall1 = wntr.msx.Species(2, "ClOH", "mg", 0.01, 0.0001, note="Testing stuff") - const1 = wntr.msx.Constant("Kb", 0.482) - param1 = wntr.msx.Parameter("Ka", 0.482, note="foo") - term1 = wntr.msx.OtherTerm("T0", "-3.2 * Kb * Cl^2", note="bar") - - rxn_model2 = wntr.msx.MsxModel() - - self.assertRaises(ValueError, rxn_model2.add_species, wntr.msx.VariableType.CONST, "Cl", "mg") - self.assertRaises(TypeError, rxn_model2.add_coefficient, None, "Kb", 0.482) - self.assertRaises(ValueError, rxn_model2.add_coefficient, "Wall", "Kb", 0.482) - - bulk3 = rxn_model2.add_species("BULK", "Cl", "mg") - wall3 = rxn_model2.add_species(wntr.msx.VariableType.WALL, "ClOH", "mg", 0.01, 0.0001, note="Testing stuff") - const3 = rxn_model2.add_coefficient("Consolation", "Kb", 0.482) - param3 = rxn_model2.add_coefficient(wntr.msx.VariableType.P, "Ka", 0.482, note="foo") - - self.assertEqual(bulk3, bulk1) - self.assertEqual(wall3, wall1) - self.assertEqual(const3, const1) - self.assertEqual(param3, param1) - - -if __name__ == "__main__": - unittest.main(verbosity=2) From e44e3470a388bd9aa8f0181fc57329068f65ff47 Mon Sep 17 00:00:00 2001 From: dbhart Date: Thu, 9 Nov 2023 14:39:15 -0700 Subject: [PATCH 37/75] Add test file --- wntr/tests/test_msx_variables.py | 231 +++++++++++++++++++++++++++++++ 1 file changed, 231 insertions(+) create mode 100644 wntr/tests/test_msx_variables.py diff --git a/wntr/tests/test_msx_variables.py b/wntr/tests/test_msx_variables.py new file mode 100644 index 000000000..3b0df6ab8 --- /dev/null +++ b/wntr/tests/test_msx_variables.py @@ -0,0 +1,231 @@ +import unittest +import warnings +from os.path import abspath, dirname, join + +import numpy as np +import pandas as pd +import wntr + +testdir = dirname(abspath(str(__file__))) +test_network_dir = join(testdir, "networks_for_testing") +test_data_dir = join(testdir, "data_for_testing") +ex_datadir = join(testdir, "..", "..", "examples", "networks") + + +class Test(unittest.TestCase): + @classmethod + def setUpClass(self): + pass + + @classmethod + def tearDownClass(self): + pass + + def test_ReactionVariable_reserved_name_exception(self): + self.assertRaises(ValueError, wntr.msx.Species, 'bulk', "D", "mg") + self.assertRaises(ValueError, wntr.msx.Species, 'wall', "Q", "mg") + self.assertRaises(ValueError, wntr.msx.Constant, "Re", 0.52) + self.assertRaises(ValueError, wntr.msx.Parameter, "Re", 0.52) + self.assertRaises(ValueError, wntr.msx.Term, "Re", 0.52) + + def test_RxnVariable_values(self): + const1 = wntr.msx.Constant("Kb", 0.482, note="test") + self.assertEqual(const1.get_value(), const1.value) + test_pipe_dict = {"PIPE": 0.38} + test_tank_dict = {"TANK": 222.23} + param2 = wntr.msx.Parameter("Kb", 0.482, note="test", pipe_values=test_pipe_dict, tank_values=test_tank_dict) + self.assertEqual(param2.get_value(), param2.global_value) + self.assertEqual(param2.get_value(pipe="PIPE"), test_pipe_dict["PIPE"]) + self.assertEqual(param2.get_value(pipe="FOO"), param2.global_value) + self.assertEqual(param2.get_value(tank="TANK"), test_tank_dict["TANK"]) + self.assertRaises(TypeError, param2.get_value, pipe="PIPE", tank="TANK") + + def test_RxnVariable_string_functions(self): + species1 = wntr.msx.Species('BULK', "Cl", "mg") + species2 = wntr.msx.Species('WALL', "Cl", "mg", 0.01, 0.0001, note="Testing stuff") + const1 = wntr.msx.Constant("Kb", 0.482) + param1 = wntr.msx.Parameter("Ka", 0.482, note="foo") + term1 = wntr.msx.OtherTerm("T0", "-3.2 * Kb * Cl^2", note="bar") + + self.assertEqual(str(species1), "Cl") + self.assertEqual(str(const1), "Kb") + self.assertEqual(str(param1), "Ka") + self.assertEqual(str(term1), "T0") + + def test_Species_tolerances(self): + # """RxnSpecies(*s) tolerance settings""" + species1 = wntr.msx.Species("B", "Cl", "mg") + species2 = wntr.msx.Species("W", "Cl", "mg", 0.01, 0.0001, note="Testing stuff") + self.assertIsNone(species1.get_tolerances()) + self.assertIsNotNone(species2.get_tolerances()) + self.assertTupleEqual(species2.get_tolerances(), (0.01, 0.0001)) + self.assertRaises(TypeError, species1.set_tolerances, None, 0.0001) + self.assertRaises(ValueError, species1.set_tolerances, -0.51, 0.01) + self.assertRaises(ValueError, species1.set_tolerances, 0.0, 0.0) + species1.set_tolerances(0.01, 0.0001) + self.assertEqual(species1._atol, 0.01) + self.assertEqual(species1._rtol, 0.0001) + species1.set_tolerances(None, None) + self.assertIsNone(species1._atol) + self.assertIsNone(species1._rtol) + species2.clear_tolerances() + self.assertIsNone(species1._atol) + self.assertIsNone(species1._rtol) + self.assertIsNone(species2.get_tolerances()) + + def test_BulkSpecies_creation(self): + # """BlukSpecies object creation (direct instantiation)""" + self.assertRaises(TypeError, wntr.msx.Species, "b", "Re") + self.assertRaises(ValueError, wntr.msx.Species, "B", "Re", "mg") + self.assertRaises(TypeError, wntr.msx.Species, 1, "Cl", "mg", 0.01) + self.assertRaises(TypeError, wntr.msx.Species, wntr.msx.base.SpeciesType.BULK, "Cl", "mg", None, 0.01) + species = wntr.msx.Species(1, "Cl", "mg") + self.assertEqual(species.name, "Cl") + self.assertEqual(species.units, "mg") + self.assertEqual(species.var_type, wntr.msx.SpeciesType.BULK) + self.assertIsNone(species._atol) + self.assertIsNone(species._rtol) + self.assertIsNone(species.note) + species = wntr.msx.Species('b', "Cl", "mg", 0.01, 0.0001, note="Testing stuff") + self.assertEqual(species.var_type, wntr.msx.SpeciesType.BULK) + self.assertEqual(species.name, "Cl") + self.assertEqual(species.units, "mg") + self.assertEqual(species._atol, 0.01) + self.assertEqual(species._rtol, 0.0001) + self.assertEqual(species.note, "Testing stuff") + + def test_WallSpecies_creation(self): + # """WallSpecies object creation (direct instantiation)""" + self.assertRaises(TypeError, wntr.msx.Species, 'W', "Re") + self.assertRaises(ValueError, wntr.msx.Species, 'Wall', "Re", "mg") + self.assertRaises(TypeError, wntr.msx.Species, 2, "Cl", "mg", 0.01) + self.assertRaises(TypeError, wntr.msx.Species, 'W', "Cl", "mg", None, 0.01) + species = wntr.msx.Species('w', "Cl", "mg") + self.assertEqual(species.name, "Cl") + self.assertEqual(species.units, "mg") + self.assertEqual(species.var_type, wntr.msx.SpeciesType.WALL) + self.assertIsNone(species._atol) + self.assertIsNone(species._rtol) + self.assertIsNone(species.note) + species = wntr.msx.Species('w', "Cl", "mg", 0.01, 0.0001, note="Testing stuff") + self.assertEqual(species.var_type, wntr.msx.SpeciesType.WALL) + self.assertEqual(species.name, "Cl") + self.assertEqual(species.units, "mg") + self.assertEqual(species._atol, 0.01) + self.assertEqual(species._rtol, 0.0001) + self.assertEqual(species.note, "Testing stuff") + + def test_Constant_creation(self): + self.assertRaises(TypeError, wntr.msx.Constant, "Re") + self.assertRaises(ValueError, wntr.msx.Constant, "Re", 2.48) + const1 = wntr.msx.Constant("Kb", 0.482, note="test") + # FIXME: Find a way to suppress warning printing + # self.assertWarns(RuntimeWarning, wntr.reaction.Constant, 'Kb1', 0.83, pipe_values={'a',1}) + self.assertEqual(const1.name, "Kb") + self.assertEqual(const1.global_value, 0.482) + self.assertEqual(const1.get_value(), const1.global_value) + self.assertEqual(const1.var_type, wntr.msx.VariableType.CONST) + self.assertEqual(const1.note, "test") + + def test_Parameter_creation(self): + self.assertRaises(TypeError, wntr.msx.Parameter, "Re") + self.assertRaises(ValueError, wntr.msx.Parameter, "Re", 2.48) + param1 = wntr.msx.Parameter("Kb", 0.482, note="test") + self.assertEqual(param1.name, "Kb") + self.assertEqual(param1.global_value, 0.482) + self.assertEqual(param1.get_value(), param1.global_value) + self.assertEqual(param1.var_type, wntr.msx.VariableType.PARAM) + self.assertEqual(param1.note, "test") + test_pipe_dict = {"PIPE": 0.38} + test_tank_dict = {"TANK": 222.23} + param2 = wntr.msx.Parameter("Kb", 0.482, note="test", pipe_values=test_pipe_dict, tank_values=test_tank_dict) + self.assertDictEqual(param2.pipe_values, test_pipe_dict) + self.assertDictEqual(param2.tank_values, test_tank_dict) + + def test_RxnTerm_creation(self): + self.assertRaises(TypeError, wntr.msx.OtherTerm, "Re") + self.assertRaises(ValueError, wntr.msx.OtherTerm, "Re", "1.0*Re") + term1 = wntr.msx.OtherTerm("T0", "-3.2 * Kb * Cl^2", note="bar") + self.assertEqual(term1.name, "T0") + self.assertEqual(term1.expression, "-3.2 * Kb * Cl^2") + self.assertEqual(term1.var_type, wntr.msx.VariableType.TERM) + self.assertEqual(term1.note, "bar") + + def test_RxnExpression_strings(self): + equil1 = wntr.msx.EquilibriumDynamics("Cl", wntr.msx.ReactionType.PIPE, "-Ka + Kb * Cl + T0") + rate1 = wntr.msx.TankReaction("Cl", wntr.msx.ReactionType.TANK, "-Ka + Kb * Cl + T0", note="Foo Bar") + formula1 = wntr.msx.PipeReaction("Cl", wntr.msx.ReactionType.PIPE, "-Ka + Kb * Cl + T0") + + def test_Equilibrium_creation(self): + equil1 = wntr.msx.EquilibriumDynamics("Cl", wntr.msx.ReactionType.PIPE, "-Ka + Kb * Cl + T0") + self.assertEqual(equil1.species, "Cl") + self.assertEqual(equil1.expression, "-Ka + Kb * Cl + T0") + self.assertEqual(equil1.dynamics, wntr.msx.ExpressionType.EQUIL) + + def test_Rate_creation(self): + rate1 = wntr.msx.TankReaction("Cl", wntr.msx.ReactionType.TANK, "-Ka + Kb * Cl + T0", note="Foo Bar") + self.assertEqual(rate1.species_name, "Cl") + self.assertEqual(rate1.expression, "-Ka + Kb * Cl + T0") + self.assertEqual(rate1.dynamics, wntr.msx.ExpressionType.RATE) + self.assertEqual(rate1.note, "Foo Bar") + + def test_Formula_creation(self): + formula1 = wntr.msx.FormulaDynamics("Cl", wntr.msx.ReactionType.PIPE, "-Ka + Kb * Cl + T0") + self.assertEqual(formula1.species, "Cl") + self.assertEqual(formula1.expression, "-Ka + Kb * Cl + T0") + self.assertEqual(formula1.dynamics, wntr.msx.ExpressionType.FORMULA) + + def test_WaterQualityReactionsModel_creation_specific_everything(self): + rxn_model1 = wntr.msx.MsxModel() + bulk1 = wntr.msx.Species('b',"Cl", "mg") + wall1 = wntr.msx.Species('w', "ClOH", "mg", 0.01, 0.0001, note="Testing stuff") + const1 = wntr.msx.Constant("Kb", 0.482) + param1 = wntr.msx.Parameter("Ka", 0.482, note="foo") + term1 = wntr.msx.OtherTerm("T0", "-3.2 * Kb * Cl^2", note="bar") + equil1 = wntr.msx.EquilibriumDynamics(bulk1, wntr.msx.ReactionType.PIPE, "-Ka + Kb * Cl + T0") + rate1 = wntr.msx.TankReaction(bulk1, wntr.msx.ReactionType.TANK, "-Ka + Kb * Cl + T0", note="Foo Bar") + formula1 = wntr.msx.FormulaDynamics(wall1, wntr.msx.ReactionType.PIPE, "-Ka + Kb * Cl + T0") + + bulk2 = rxn_model1.add_bulk_species("Cl", "mg") + wall2 = rxn_model1.add_wall_species("ClOH", "mg", 0.01, 0.0001, note="Testing stuff") + const2 = rxn_model1.add_constant("Kb", 0.482) + param2 = rxn_model1.add_parameter("Ka", 0.482, note="foo") + term2 = rxn_model1.add_other_term("T0", "-3.2 * Kb * Cl^2", note="bar") + equil2 = rxn_model1.add_pipe_reaction("Cl", "equil", "-Ka + Kb * Cl + T0") + rate2 = rxn_model1.add_tank_reaction("Cl", wntr.msx.ExpressionType.R, "-Ka + Kb * Cl + T0", note="Foo Bar") + formula2 = rxn_model1.add_reaction("PIPE", "ClOH", "formula", "-Ka + Kb * Cl + T0") + self.assertEqual(bulk1, bulk2) + self.assertEqual(wall1, wall2) + self.assertEqual(const1, const2) + # self.assertEqual(param1, param2) # No good way to compare dicts inside + self.assertEqual(term1, term2) + # self.assertEqual(equil1, equil2) + # self.assertEqual(rate1, rate2) + # self.assertEqual(formula1, formula2) + + def test_WaterQualityReactionsModel_creation_generic_species_coeffs(self): + bulk1 = wntr.msx.Species('b', "Cl", "mg") + wall1 = wntr.msx.Species(2, "ClOH", "mg", 0.01, 0.0001, note="Testing stuff") + const1 = wntr.msx.Constant("Kb", 0.482) + param1 = wntr.msx.Parameter("Ka", 0.482, note="foo") + term1 = wntr.msx.OtherTerm("T0", "-3.2 * Kb * Cl^2", note="bar") + + rxn_model2 = wntr.msx.MsxModel() + + self.assertRaises(ValueError, rxn_model2.add_species, wntr.msx.VariableType.CONST, "Cl", "mg") + self.assertRaises(TypeError, rxn_model2.add_coefficient, None, "Kb", 0.482) + self.assertRaises(ValueError, rxn_model2.add_coefficient, "Wall", "Kb", 0.482) + + bulk3 = rxn_model2.add_species("BULK", "Cl", "mg") + wall3 = rxn_model2.add_species(wntr.msx.VariableType.WALL, "ClOH", "mg", 0.01, 0.0001, note="Testing stuff") + const3 = rxn_model2.add_coefficient("Consolation", "Kb", 0.482) + param3 = rxn_model2.add_coefficient(wntr.msx.VariableType.P, "Ka", 0.482, note="foo") + + self.assertEqual(bulk3, bulk1) + self.assertEqual(wall3, wall1) + self.assertEqual(const3, const1) + self.assertEqual(param3, param1) + + +if __name__ == "__main__": + unittest.main(verbosity=2) From 8766bbd54f0f6a851a49c948683ac6f7464efa9e Mon Sep 17 00:00:00 2001 From: dbhart Date: Thu, 9 Nov 2023 15:05:21 -0700 Subject: [PATCH 38/75] Updates to documentation for MSX --- MANIFEST.in | 4 +- requirements.txt | 1 - wntr/epanet/msx/toolkit.py | 215 ++++++++++---------------- wntr/msx/__init__.py | 4 - wntr/msx/base.py | 204 ++++++------------------ wntr/msx/elements.py | 15 -- wntr/msx/model.py | 15 -- wntr/tests/test_epanet_msx_io.py | 1 - wntr/tests/test_epanet_msx_tooklit.py | 1 - 9 files changed, 129 insertions(+), 331 deletions(-) diff --git a/MANIFEST.in b/MANIFEST.in index 1961f8a2e..7157c882b 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -7,4 +7,6 @@ include wntr/sim/aml/evaluator* include wntr/sim/aml/numpy.i include wntr/sim/network_isolation/network_isolation* include wntr/sim/network_isolation/numpy.i -include wntr/tests/networks_for_testing/*.inp \ No newline at end of file +include wntr/tests/networks_for_testing/*.inp +include wntr/msx/_library_data/*.json +include wntr/msx/_library_data/*.msx diff --git a/requirements.txt b/requirements.txt index ee2a94f43..77fd539c5 100644 --- a/requirements.txt +++ b/requirements.txt @@ -12,7 +12,6 @@ utm openpyxl geopandas; sys_platform == "darwin" or sys_platform == "linux" rtree; sys_platform == "darwin" or sys_platform == "linux" -sympy # Documentation sphinx diff --git a/wntr/epanet/msx/toolkit.py b/wntr/epanet/msx/toolkit.py index b45056d47..20aea7cd8 100644 --- a/wntr/epanet/msx/toolkit.py +++ b/wntr/epanet/msx/toolkit.py @@ -410,26 +410,26 @@ def MSXgetparameter(self, _type, node_link_index, param_index): Parameters ---------- - _type : _type_ - _description_ - node_link_index : _type_ - _description_ - param_index : _type_ - _description_ + _type : int or str or Enum + get the type of the parameter + node_link_index : int + the link index + param_index : int + the parameter variable index Returns ------- - _type_ - _description_ + float + the parameter value Raises ------ MSXKeyError - _description_ + if there is no such _type MSXValueError - _description_ + if the _type is improper EpanetMsxException - _description_ + any other error """ try: _type = TkObjectType.get(_type) @@ -463,18 +463,13 @@ def MSXgetpatternlen(self, pat): Parameters ---------- - pat : _type_ - _description_ + pat : int + pattern index Returns ------- - _type_ - _description_ - - Raises - ------ - EpanetMsxException - _description_ + int + number of time periods in the pattern """ len = ctypes.c_int() ierr = self.ENlib.MSXgetpatternlen(pat, ctypes.byref(len)) @@ -487,20 +482,15 @@ def MSXgetpatternvalue(self, pat, period): Parameters ---------- - pat : _type_ - _description_ + pat : int + pattern index period : int 1-indexed period of the pattern to retrieve Returns ------- - _type_ - _description_ - - Raises - ------ - EpanetMsxException - _description_ + float + the multiplier """ val = ctypes.c_double() ierr = self.ENlib.MSXgetpatternvalue(pat, period, ctypes.byref(val)) @@ -513,20 +503,18 @@ def MSXgetcount(self, _type): Parameters ---------- - _type : _type_ - _description_ + _type : int or str or Enum + the type of object to count Returns ------- - _type_ - _description_ + int + the number of objects of specified type Raises ------ MSXKeyError - _description_ - EpanetMsxException - _description_ + if the _type is invalid """ try: _type = TkObjectType.get(_type) @@ -545,18 +533,13 @@ def MSXgetspecies(self, species_index): Parameters ---------- - species_index : _type_ - _description_ + species_index : int + the species to query Returns ------- - _type_ - _description_ - - Raises - ------ - EpanetMsxException - _description_ + int, str, float, float + the type, units, aTol, and rTol for the species """ type_ind = ctypes.c_int() units = ctypes.create_string_buffer(15) @@ -573,15 +556,21 @@ def MSXgeterror(self, errcode, len=100): Parameters ---------- - errcode : _type_ - _description_ + errcode : int + the error code len : int, optional - _description_, by default 100 and minimum 80 + the length of the error message, by default 100 and minimum 80 Returns ------- - _type_ - _description_ + str + returns a string decoded from the DLL + + Warning + ------- + Getting string parameters in this way is not recommended, because it requires + setting up string arrays that may or may not be the correct size. Use the + wntr.epanet.msx.enums package to get error information. """ errmsg = ctypes.create_string_buffer(len) self.ENlib.MSXgeterror(errcode, ctypes.byref(errmsg), len) @@ -594,15 +583,10 @@ def MSXsetconstant(self, ind, value): Parameters ---------- - ind : _type_ - _description_ - value : _type_ - _description_ - - Raises - ------ - EpanetMsxException - _description_ + ind : int + the index to the variable + value : float + the value to give the constant """ ierr = self.ENlib.MSXsetconstant(ctypes.c_int(ind), ctypes.c_double(value)) if ierr != 0: @@ -613,23 +597,21 @@ def MSXsetparameter(self, _type, ind, param, value): Parameters ---------- - _type : _type_ - _description_ - ind : _type_ - _description_ - param : _type_ - _description_ - value : _type_ - _description_ + _type : int or str or enum + the type of value to set + ind : int + the tank or pipe index + param : int + the parameter variable index + value : float + the value to be set Raises ------ MSXKeyError - _description_ + if there is no such _type MSXValueError - _description_ - EpanetMsxException - _description_ + if the _type is invalid """ try: _type = TkObjectType.get(_type) @@ -648,23 +630,14 @@ def MSXsetinitqual(self, _type, ind, spe, value): Parameters ---------- - _type : _type_ - _description_ - ind : _type_ - _description_ - spe : _type_ - _description_ - value : _type_ - _description_ - - Raises - ------ - MSXKeyError - _description_ - MSXValueError - _description_ - EpanetMsxException - _description_ + _type : int or str or enum + what type of network element is being set + ind : int + the index of the network element + spe : int + the index of the species + value : float + the initial quality value """ try: _type = TkObjectType.get(_type) @@ -682,23 +655,16 @@ def MSXsetsource(self, node, spe, _type, level, pat): Parameters ---------- - node : _type_ - _description_ - spe : _type_ - _description_ - _type : _type_ - _description_ - level : _type_ - _description_ - pat : _type_ - _description_ - - Raises - ------ - MSXKeyError - _description_ - EpanetMsxException - _description_ + node : int + the node index + spe : int + the species index + _type : int or str or enum + the type of source + level : float + the source quality value + pat : int + the pattern index """ try: _type = TkSourceType.get(_type) @@ -714,15 +680,10 @@ def MSXsetpattern(self, pat, mult): Parameters ---------- - pat : _type_ - _description_ - mult : _type_ - _description_ - - Raises - ------ - EpanetMsxException - _description_ + pat : int + the pattern index + mult : list-like + the pattern multipliers """ length = len(mult) cfactors_type = ctypes.c_double * length @@ -738,17 +699,12 @@ def MSXsetpatternvalue(self, pat, period, value): Parameters ---------- - pat : _type_ - _description_ - period : _type_ - _description_ - value : _type_ - _description_ - - Raises - ------ - EpanetMsxException - _description_ + pat : int + the pattern index + period : int + the 1-indexed pattern time period index + value : float + the value to set at that time period """ ierr = self.ENlib.MSXsetpatternvalue(ctypes.c_int(pat), ctypes.c_int(period), ctypes.c_double(value)) if ierr != 0: @@ -759,13 +715,8 @@ def MSXaddpattern(self, patternid): Parameters ---------- - patternid : _type_ - _description_ - - Raises - ------ - EpanetMsxException - _description_ + patternid : str + the name of the new pattern """ ierr = self.ENlib.MSXaddpattern(ctypes.c_char_p(patternid.encode())) if ierr != 0: diff --git a/wntr/msx/__init__.py b/wntr/msx/__init__.py index 5937536fd..e44b248fe 100644 --- a/wntr/msx/__init__.py +++ b/wntr/msx/__init__.py @@ -2,10 +2,6 @@ """Contains definitions for EPANET Multispecies Extension (MSX) water quality modeling. """ -# Dependencies: -# pyomo.dae? -# sympy? - from .base import VariableType, SpeciesType, ReactionType, ExpressionType from .elements import Species, Constant, Parameter, Term, Reaction, HydraulicVariable, MathFunction from .model import MsxModel diff --git a/wntr/msx/base.py b/wntr/msx/base.py index 75bff8f31..e795616c7 100644 --- a/wntr/msx/base.py +++ b/wntr/msx/base.py @@ -15,99 +15,33 @@ from wntr.utils.disjoint_mapping import DisjointMapping from wntr.utils.enumtools import add_get -has_sympy = False -try: - from sympy import ( - Add, - Float, - Function, - Integer, - Mul, - Pow, - Symbol, - init_printing, - symbols, - ) - from sympy.functions import ( - Abs, - Heaviside, - acos, - acot, - asin, - atan, - cos, - cosh, - cot, - coth, - exp, - log, - sign, - sin, - sinh, - sqrt, - tan, - tanh, - ) - from sympy.parsing import parse_expr - from sympy.parsing.sympy_parser import ( - auto_number, - auto_symbol, - convert_xor, - standard_transformations, - ) - - class _log10(Function): - @classmethod - def eval(cls, x): - return log(x, 10) - - has_sympy = True -except ImportError: - sympy = None - has_sympy = False - logging.critical("This python installation does not have SymPy installed. Certain functionality will be disabled.") - standard_transformations = (None,) - convert_xor = None - if not has_sympy: - from numpy import ( - abs, - arccos, - arcsin, - arctan, - cos, - cosh, - exp, - heaviside, - log, - log10, - sign, - sin, - sinh, - sqrt, - tan, - tanh, - ) - - def _cot(x): - return 1 / tan(x) - - cot = _cot - Abs = abs - asin = arcsin - acos = arccos - atan = arctan - - def _acot(x): - return 1 / arctan(1 / x) - - acot = _acot - - def _coth(x): - return 1 / tanh(x) - - coth = _coth - Heaviside = heaviside - _log10 = log10 +from numpy import ( + abs, + arccos, + arcsin, + arctan, + cos, + cosh, + exp, + heaviside, + log, + log10, + sign, + sin, + sinh, + sqrt, + tan, + tanh, +) + +def cot(x): + return 1 / tan(x) + +def arccot(x): + return 1 / arctan(1 / x) + +def coth(x): + return 1 / tanh(x) logger = logging.getLogger(__name__) @@ -151,46 +85,41 @@ def _coth(x): abs=abs, sgn=sign, sqrt=sqrt, - step=Heaviside, + step=heaviside, log=log, exp=exp, sin=sin, cos=cos, tan=tan, cot=cot, - asin=asin, - acos=acos, - atan=atan, - acot=acot, + asin=arcsin, + acos=arccos, + atan=arctan, + acot=arccot, sinh=sinh, cosh=cosh, tanh=tanh, coth=coth, - log10=_log10, + log10=log10, ) """Mathematical functions available for use in expressions. See :numref:`table-msx-funcs` for a list and description of the different functions recognized. These names, case insensitive, are considered invalid when naming variables. -Additionally, the following SymPy names - ``Mul``, ``Add``, ``Pow``, -``Integer``, ``Float`` - are used to convert numbers and symbolic -functions; therefore, these five words, case sensitive, are also invalid -for use as variable names. - .. _table-msx-funcs: .. table:: Functions defined for use in EPANET-MSX expressions. ============== ================================================================ **Name** **Description** -------------- ---------------------------------------------------------------- - ``abs`` absolute value (:func:`~sympy.functions.Abs`) - ``sgn`` sign (:func:`~sympy.functions.sign`) + ``abs`` absolute value + ``sgn`` sign ``sqrt`` square-root - ``step`` step function (:func:`~sympy.functions.Heaviside`) + ``step`` step function ``exp`` natural number, `e`, raised to a power ``log`` natural logarithm - ``log10`` base-10 logarithm (defined as internal function) + ``log10`` base-10 logarithm ``sin`` sine ``cos`` cosine ``tan`` tangent @@ -203,13 +132,12 @@ def _coth(x): ``cosh`` hyperbolic cosine ``tanh`` hyperbolic tangent ``coth`` hyperbolic cotangent - ``*`` multiplication (:func:`~sympy.Mul`) - ``/`` division (:func:`~sympy.Mul`) - ``+`` addition (:func:`~sympy.Add`) - ``-`` negation and subtraction (:func:`~sympy.Add`) - ``^`` power/exponents (:func:`~sympy.Pow`) + ``*`` multiplication + ``/`` division + ``+`` addition + ``-`` negation and subtraction + ``^`` power/exponents ``(``, ``)`` groupings and function parameters - `numbers` literal values (:func:`~sympy.Float` and :func:`~sympy.Integer`) ============== ================================================================ :meta hide-value: @@ -220,7 +148,6 @@ def _coth(x): + tuple([k.lower() for k in EXPR_FUNCTIONS.keys()]) + tuple([k.upper() for k in EXPR_FUNCTIONS.keys()]) + tuple([k.capitalize() for k in EXPR_FUNCTIONS.keys()]) - + ("Mul", "Add", "Pow", "Integer", "Float") ) """The WNTR reserved names. This includes the MSX hydraulic variables (see :numref:`table-msx-hyd-vars`) and the MSX defined functions @@ -235,52 +162,7 @@ def _coth(x): _global_dict[k.capitalize()] = v _global_dict[k.upper()] = v for v in HYDRAULIC_VARIABLES: - _global_dict[v["name"]] = symbols(v["name"]) -_global_dict["Mul"] = Mul -_global_dict["Add"] = Add -_global_dict["Pow"] = Pow -_global_dict["Integer"] = Integer -_global_dict["Float"] = Float - -EXPR_TRANSFORMS = ( - auto_symbol, - auto_number, - convert_xor, -) -"""The sympy transforms to use in expression parsing. See -:numref:`table-sympy-transformations` for the list of transformations. - -.. _table-sympy-transformations: -.. table:: Transformations used by WNTR when parsing expressions using SymPy. - - ========================================== ================== - **Transformation** **Is used?** - ------------------------------------------ ------------------ - ``lambda_notation`` No - ``auto_symbol`` Yes - ``repeated_decimals`` No - ``auto_number`` Yes - ``factorial_notation`` No - ``implicit_multiplication_application`` No - ``convert_xor`` Yes - ``implicit_application`` No - ``implicit_multiplication`` No - ``convert_equals_signs`` No - ``function_exponentiation`` No - ``rationalize`` No - ========================================== ================== - -:meta hide-value: -""" - - -class _AnnotatedFloat(float): - def __new__(self, value, note=None): - return float.__new__(self, value) - - def __init__(self, value, note=None): - float.__init__(value) - self.note = note + _global_dict[v["name"]] = v["name"] @add_get(abbrev=True) diff --git a/wntr/msx/elements.py b/wntr/msx/elements.py index 0ae9794f5..e6c7eb289 100644 --- a/wntr/msx/elements.py +++ b/wntr/msx/elements.py @@ -21,21 +21,6 @@ ReactionSystemBase, ) -has_sympy = False -try: - from sympy import Float, Symbol, init_printing, symbols - from sympy.parsing import parse_expr - from sympy.parsing.sympy_parser import convert_xor, standard_transformations - - has_sympy = True -except ImportError: - sympy = None - logging.critical("This python installation does not have SymPy installed. " "Certain functionality will be disabled.") - standard_transformations = (None,) - convert_xor = None - has_sympy = False - - logger = logging.getLogger(__name__) diff --git a/wntr/msx/model.py b/wntr/msx/model.py index 788f925cb..4d9749c3d 100644 --- a/wntr/msx/model.py +++ b/wntr/msx/model.py @@ -27,21 +27,6 @@ from .elements import Constant, HydraulicVariable, InitialQuality, MathFunction, Parameter, ParameterValues, Reaction, Species, Term from .options import MsxSolverOptions -has_sympy = False -try: - from sympy import Float, Symbol, init_printing, symbols - from sympy.parsing import parse_expr - from sympy.parsing.sympy_parser import convert_xor, standard_transformations - - has_sympy = True -except ImportError: - sympy = None - logging.critical("This python installation does not have SymPy installed. " "Certain functionality will be disabled.") - standard_transformations = (None,) - convert_xor = None - has_sympy = False - - logger = logging.getLogger(__name__) MsxVariable = Union[Constant, HydraulicVariable, MathFunction, Parameter, Species, Term] diff --git a/wntr/tests/test_epanet_msx_io.py b/wntr/tests/test_epanet_msx_io.py index 09cb38625..74d222798 100644 --- a/wntr/tests/test_epanet_msx_io.py +++ b/wntr/tests/test_epanet_msx_io.py @@ -7,7 +7,6 @@ import wntr import wntr.msx import wntr.epanet.msx -import sympy testdir = dirname(abspath(str(__file__))) test_network_dir = join(testdir, "networks_for_testing") diff --git a/wntr/tests/test_epanet_msx_tooklit.py b/wntr/tests/test_epanet_msx_tooklit.py index 71cef63fe..6235cba73 100644 --- a/wntr/tests/test_epanet_msx_tooklit.py +++ b/wntr/tests/test_epanet_msx_tooklit.py @@ -8,7 +8,6 @@ import wntr.msx import wntr.epanet.msx import wntr.epanet.msx.toolkit -import sympy testdir = dirname(abspath(str(__file__))) test_network_dir = join(testdir, "networks_for_testing") From 54690ce3a4b25d44c68ca40523472feb9ade288f Mon Sep 17 00:00:00 2001 From: dbhart Date: Thu, 9 Nov 2023 15:15:24 -0700 Subject: [PATCH 39/75] Update to example files and tests --- examples/msx/example.inp | 36 ++++++++++++++++++++ examples/msx/example.msx | 58 ++++++++++++++++++++++++++++++++ wntr/tests/test_msx_variables.py | 29 ++++++---------- 3 files changed, 105 insertions(+), 18 deletions(-) create mode 100644 examples/msx/example.inp create mode 100644 examples/msx/example.msx diff --git a/examples/msx/example.inp b/examples/msx/example.inp new file mode 100644 index 000000000..0887e00db --- /dev/null +++ b/examples/msx/example.inp @@ -0,0 +1,36 @@ +[TITLE] +EPANET-MSX Example Network + +[JUNCTIONS] +;ID Elev Demand Pattern + A 0 4.1 + B 0 3.4 + C 0 5.5 + D 0 2.3 + +[RESERVOIRS] +;ID Head Pattern + Source 100 + +[PIPES] +;ID Node1 Node2 Length Diameter Roughness + 1 Source A 1000 200 100 + 2 A B 800 150 100 + 3 A C 1200 200 100 + 4 B C 1000 150 100 + 5 C D 2000 150 100 + +[TIMES] + Duration 48 + Hydraulic Timestep 1:00 + Quality Timestep 0:05 + Report Timestep 2 + Report Start 0 + Statistic NONE + +[OPTIONS] + Units CMH + Headloss H-W + Quality NONE + +[END] diff --git a/examples/msx/example.msx b/examples/msx/example.msx new file mode 100644 index 000000000..b20e0854b --- /dev/null +++ b/examples/msx/example.msx @@ -0,0 +1,58 @@ +[TITLE] +Arsenic Oxidation/Adsorption Example + +[OPTIONS] + AREA_UNITS M2 ;Surface concentration is mass/m2 + RATE_UNITS HR ;Reaction rates are concentration/hour + SOLVER RK5 ;5-th order Runge-Kutta integrator + TIMESTEP 360 ;360 sec (5 min) solution time step + RTOL 0.001 ;Relative concentration tolerance + ATOL 0.0001 ;Absolute concentration tolerance + +[SPECIES] + BULK AS3 UG ;Dissolved arsenite + BULK AS5 UG ;Dissolved arsenate + BULK AStot UG ;Total dissolved arsenic + WALL AS5s UG ;Adsorbed arsenate + BULK NH2CL MG ;Monochloramine + +[COEFFICIENTS] + CONSTANT Ka 10.0 ;Arsenite oxidation rate coefficient + CONSTANT Kb 0.1 ;Monochloramine decay rate coefficient + CONSTANT K1 5.0 ;Arsenate adsorption coefficient + CONSTANT K2 1.0 ;Arsenate desorption coefficient + CONSTANT Smax 50 ;Arsenate adsorption saturation limit + +[TERMS] + Ks K1/K2 ;Equil. adsorption coeff. + +[PIPES] + ;Arsenite oxidation + RATE AS3 -Ka*AS3*NH2CL + ;Arsenate production + RATE AS5 Ka*AS3*NH2CL - Av*(K1*(Smax-AS5s)*AS5 - K2*AS5s) + ;Monochloramine decay + RATE NH2CL -Kb*NH2CL + ;Arsenate adsorption + EQUIL AS5s Ks*Smax*AS5/(1+Ks*AS5) - AS5s + ;Total bulk arsenic + FORMULA AStot AS3 + AS5 + +[TANKS] + RATE AS3 -Ka*AS3*NH2CL + RATE AS5 Ka*AS3*NH2CL + RATE NH2CL -Kb*NH2CL + FORMULA AStot AS3 + AS5 + +[QUALITY] + ;Initial conditions (= 0 if not specified here) + NODE Source AS3 10.0 + NODE Source NH2CL 2.5 + +[REPORT] + NODES C D ;Report results for nodes C and D + LINKS 5 ;Report results for pipe 5 + SPECIES AStot YES ;Report results for each specie + SPECIES AS5 YES + SPECIES AS5s YES + SPECIES NH2CL YES diff --git a/wntr/tests/test_msx_variables.py b/wntr/tests/test_msx_variables.py index 3b0df6ab8..429125a06 100644 --- a/wntr/tests/test_msx_variables.py +++ b/wntr/tests/test_msx_variables.py @@ -30,22 +30,15 @@ def test_ReactionVariable_reserved_name_exception(self): def test_RxnVariable_values(self): const1 = wntr.msx.Constant("Kb", 0.482, note="test") - self.assertEqual(const1.get_value(), const1.value) - test_pipe_dict = {"PIPE": 0.38} - test_tank_dict = {"TANK": 222.23} - param2 = wntr.msx.Parameter("Kb", 0.482, note="test", pipe_values=test_pipe_dict, tank_values=test_tank_dict) - self.assertEqual(param2.get_value(), param2.global_value) - self.assertEqual(param2.get_value(pipe="PIPE"), test_pipe_dict["PIPE"]) - self.assertEqual(param2.get_value(pipe="FOO"), param2.global_value) - self.assertEqual(param2.get_value(tank="TANK"), test_tank_dict["TANK"]) - self.assertRaises(TypeError, param2.get_value, pipe="PIPE", tank="TANK") + self.assertEqual(const1.value, 0.482) + param2 = wntr.msx.Parameter("Kb", 0.482, note="test") + self.assertEqual(param2.global_value, 0.482) def test_RxnVariable_string_functions(self): - species1 = wntr.msx.Species('BULK', "Cl", "mg") - species2 = wntr.msx.Species('WALL', "Cl", "mg", 0.01, 0.0001, note="Testing stuff") + species1 = wntr.msx.Species('Cl', 'BULK', "mg") const1 = wntr.msx.Constant("Kb", 0.482) param1 = wntr.msx.Parameter("Ka", 0.482, note="foo") - term1 = wntr.msx.OtherTerm("T0", "-3.2 * Kb * Cl^2", note="bar") + term1 = wntr.msx.Term("T0", "-3.2 * Kb * Cl^2", note="bar") self.assertEqual(str(species1), "Cl") self.assertEqual(str(const1), "Kb") @@ -122,7 +115,7 @@ def test_Constant_creation(self): # FIXME: Find a way to suppress warning printing # self.assertWarns(RuntimeWarning, wntr.reaction.Constant, 'Kb1', 0.83, pipe_values={'a',1}) self.assertEqual(const1.name, "Kb") - self.assertEqual(const1.global_value, 0.482) + self.assertEqual(const1.value, 0.482) self.assertEqual(const1.get_value(), const1.global_value) self.assertEqual(const1.var_type, wntr.msx.VariableType.CONST) self.assertEqual(const1.note, "test") @@ -136,11 +129,11 @@ def test_Parameter_creation(self): self.assertEqual(param1.get_value(), param1.global_value) self.assertEqual(param1.var_type, wntr.msx.VariableType.PARAM) self.assertEqual(param1.note, "test") - test_pipe_dict = {"PIPE": 0.38} - test_tank_dict = {"TANK": 222.23} - param2 = wntr.msx.Parameter("Kb", 0.482, note="test", pipe_values=test_pipe_dict, tank_values=test_tank_dict) - self.assertDictEqual(param2.pipe_values, test_pipe_dict) - self.assertDictEqual(param2.tank_values, test_tank_dict) + # test_pipe_dict = {"PIPE": 0.38} + # test_tank_dict = {"TANK": 222.23} + # param2 = wntr.msx.Parameter("Kb", 0.482, note="test", pipe_values=test_pipe_dict, tank_values=test_tank_dict) + # self.assertDictEqual(param2.pipe_values, test_pipe_dict) + # self.assertDictEqual(param2.tank_values, test_tank_dict) def test_RxnTerm_creation(self): self.assertRaises(TypeError, wntr.msx.OtherTerm, "Re") From 73264e427f97b8c1c553c7e354cd4cbbbae9a0bd Mon Sep 17 00:00:00 2001 From: dbhart Date: Thu, 9 Nov 2023 15:46:30 -0700 Subject: [PATCH 40/75] Test updates --- wntr/tests/test_msx_elements.py | 190 ++++++++++++++++++++++++++ wntr/tests/test_msx_variables.py | 224 ------------------------------- 2 files changed, 190 insertions(+), 224 deletions(-) create mode 100644 wntr/tests/test_msx_elements.py delete mode 100644 wntr/tests/test_msx_variables.py diff --git a/wntr/tests/test_msx_elements.py b/wntr/tests/test_msx_elements.py new file mode 100644 index 000000000..39cc09188 --- /dev/null +++ b/wntr/tests/test_msx_elements.py @@ -0,0 +1,190 @@ +import unittest +import warnings +from os.path import abspath, dirname, join + +import numpy as np +import pandas as pd +import wntr + +testdir = dirname(abspath(str(__file__))) +test_network_dir = join(testdir, "networks_for_testing") +test_data_dir = join(testdir, "data_for_testing") +ex_datadir = join(testdir, "..", "..", "examples", "networks") + + +class Test(unittest.TestCase): + @classmethod + def setUpClass(self): + pass + + @classmethod + def tearDownClass(self): + pass + + def test_ReactionVariable_reserved_name_exception(self): + self.assertRaises(ValueError, wntr.msx.Species, "D", 'bulk', "mg") + self.assertRaises(ValueError, wntr.msx.Species, "Q", 'wall', "mg") + self.assertRaises(ValueError, wntr.msx.Constant, "Re", 0.52) + self.assertRaises(ValueError, wntr.msx.Parameter, "Re", 0.52) + self.assertRaises(ValueError, wntr.msx.Term, "Re", 0.52) + + def test_RxnVariable_values(self): + const1 = wntr.msx.Constant("Kb", 0.482, note="test") + self.assertEqual(const1.value, 0.482) + param2 = wntr.msx.Parameter("Kb", 0.482, note="test") + self.assertEqual(param2.global_value, 0.482) + + def test_RxnVariable_string_functions(self): + species1 = wntr.msx.Species('Cl', 'BULK', "mg") + const1 = wntr.msx.Constant("Kb", 0.482) + param1 = wntr.msx.Parameter("Ka", 0.482, note="foo") + term1 = wntr.msx.Term("T0", "-3.2 * Kb * Cl^2", note="bar") + + self.assertEqual(str(species1), "Cl") + self.assertEqual(str(const1), "Kb") + self.assertEqual(str(param1), "Ka") + self.assertEqual(str(term1), "T0") + + def test_Species_tolerances(self): + # """RxnSpecies(*s) tolerance settings""" + species1 = wntr.msx.Species("Cl", 'bulk', "mg") + species2 = wntr.msx.Species("Cl", 'wall', "mg", 0.01, 0.0001, note="Testing stuff") + self.assertIsNone(species1.get_tolerances()) + self.assertIsNotNone(species2.get_tolerances()) + self.assertTupleEqual(species2.get_tolerances(), (0.01, 0.0001)) + self.assertRaises(TypeError, species1.set_tolerances, None, 0.0001) + self.assertRaises(ValueError, species1.set_tolerances, -0.51, 0.01) + self.assertRaises(ValueError, species1.set_tolerances, 0.0, 0.0) + species1.set_tolerances(0.01, 0.0001) + self.assertEqual(species1.atol, 0.01) + self.assertEqual(species1.rtol, 0.0001) + species1.set_tolerances(None, None) + self.assertIsNone(species1.atol) + self.assertIsNone(species1.rtol) + species2.clear_tolerances() + self.assertIsNone(species1.atol) + self.assertIsNone(species1.rtol) + self.assertIsNone(species2.get_tolerances()) + + def test_BulkSpecies_creation(self): + # """BlukSpecies object creation (direct instantiation)""" + self.assertRaises(TypeError, wntr.msx.Species, "Re", 'bulk') + self.assertRaises(ValueError, wntr.msx.Species, "Re", 'bulk', "mg") + # self.assertRaises(TypeError, wntr.msx.Species, "Cl", 1, "mg", 0.01, None) + # self.assertRaises(TypeError, wntr.msx.Species, "Cl", wntr.msx.base.SpeciesType.BULK, "mg", None, 0.01) + species = wntr.msx.Species("Cl", 1, "mg") + self.assertEqual(species.name, "Cl") + self.assertEqual(species.units, "mg") + self.assertEqual(species.species_type, wntr.msx.SpeciesType.BULK) + self.assertIsNone(species.atol) + self.assertIsNone(species.rtol) + self.assertIsNone(species.note) + species = wntr.msx.Species("Cl",'bulk', "mg", 0.01, 0.0001, note="Testing stuff") + self.assertEqual(species.species_type, wntr.msx.SpeciesType.BULK) + self.assertEqual(species.name, "Cl") + self.assertEqual(species.units, "mg") + self.assertEqual(species.atol, 0.01) + self.assertEqual(species.rtol, 0.0001) + self.assertEqual(species.note, "Testing stuff") + + def test_WallSpecies_creation(self): + # """WallSpecies object creation (direct instantiation)""" + self.assertRaises(TypeError, wntr.msx.Species, "Re", 'W') + self.assertRaises(ValueError, wntr.msx.Species, "Re", 'Wall', "mg") + self.assertRaises(TypeError, wntr.msx.Species, "Cl", 2, "mg", 0.01) + self.assertRaises(TypeError, wntr.msx.Species, "Cl", 'w', "mg", None, 0.01) + species = wntr.msx.Species( "Cl", 'w', "mg") + self.assertEqual(species.name, "Cl") + self.assertEqual(species.units, "mg") + self.assertEqual(species.species_type, wntr.msx.SpeciesType.WALL) + self.assertIsNone(species.atol) + self.assertIsNone(species.rtol) + self.assertIsNone(species.note) + species = wntr.msx.Species( "Cl", 'w', "mg", 0.01, 0.0001, note="Testing stuff") + self.assertEqual(species.species_type, wntr.msx.SpeciesType.WALL) + self.assertEqual(species.name, "Cl") + self.assertEqual(species.units, "mg") + self.assertEqual(species.atol, 0.01) + self.assertEqual(species.rtol, 0.0001) + self.assertEqual(species.note, "Testing stuff") + + def test_Constant_creation(self): + self.assertRaises(TypeError, wntr.msx.Constant, "Re") + self.assertRaises(ValueError, wntr.msx.Constant, "Re", 2.48) + const1 = wntr.msx.Constant("Kb", 0.482, note="test") + # FIXME: Find a way to suppress warning printing + # self.assertWarns(RuntimeWarning, wntr.reaction.Constant, 'Kb1', 0.83, pipe_values={'a',1}) + self.assertEqual(const1.name, "Kb") + self.assertEqual(const1.value, 0.482) + self.assertEqual(const1.var_type, wntr.msx.VariableType.CONST) + self.assertEqual(const1.note, "test") + + def test_Parameter_creation(self): + self.assertRaises(TypeError, wntr.msx.Parameter, "Re") + self.assertRaises(ValueError, wntr.msx.Parameter, "Re", 2.48) + param1 = wntr.msx.Parameter("Kb", 0.482, note="test") + self.assertEqual(param1.name, "Kb") + self.assertEqual(param1.global_value, 0.482) + self.assertEqual(param1.var_type, wntr.msx.VariableType.PARAM) + self.assertEqual(param1.note, "test") + # test_pipe_dict = {"PIPE": 0.38} + # test_tank_dict = {"TANK": 222.23} + # param2 = wntr.msx.Parameter("Kb", 0.482, note="test", pipe_values=test_pipe_dict, tank_values=test_tank_dict) + # self.assertDictEqual(param2.pipe_values, test_pipe_dict) + # self.assertDictEqual(param2.tank_values, test_tank_dict) + + def test_RxnTerm_creation(self): + self.assertRaises(TypeError, wntr.msx.Term, "Re") + self.assertRaises(ValueError, wntr.msx.Term, "Re", "1.0*Re") + term1 = wntr.msx.Term("T0", "-3.2 * Kb * Cl^2", note="bar") + self.assertEqual(term1.name, "T0") + self.assertEqual(term1.expression, "-3.2 * Kb * Cl^2") + self.assertEqual(term1.var_type, wntr.msx.VariableType.TERM) + self.assertEqual(term1.note, "bar") + + def test_Reaction(self): + equil1 = wntr.msx.Reaction("Cl", wntr.msx.ReactionType.PIPE, 'equil', "-Ka + Kb * Cl + T0") + self.assertEqual(equil1.species_name, "Cl") + self.assertEqual(equil1.expression, "-Ka + Kb * Cl + T0") + self.assertEqual(equil1.expression_type, wntr.msx.ExpressionType.EQUIL) + rate1 = wntr.msx.Reaction("Cl", wntr.msx.ReactionType.TANK, 'rate', "-Ka + Kb * Cl + T0", note="Foo Bar") + self.assertEqual(rate1.species_name, "Cl") + self.assertEqual(rate1.expression, "-Ka + Kb * Cl + T0") + self.assertEqual(rate1.expression_type, wntr.msx.ExpressionType.RATE) + self.assertEqual(rate1.note, "Foo Bar") + formula1 = wntr.msx.Reaction("Cl", wntr.msx.ReactionType.PIPE, 'formula', "-Ka + Kb * Cl + T0") + self.assertEqual(formula1.species_name, "Cl") + self.assertEqual(formula1.expression, "-Ka + Kb * Cl + T0") + self.assertEqual(formula1.expression_type, wntr.msx.ExpressionType.FORMULA) + + def test_WaterQualityReactionsModel_creation_specific_everything(self): + rxn_model1 = wntr.msx.MsxModel() + bulk1 = wntr.msx.Species("Cl", 'b', "mg") + wall1 = wntr.msx.Species("ClOH", 'w', "mg", 0.01, 0.0001, note="Testing stuff") + const1 = wntr.msx.Constant("Kb", 0.482) + param1 = wntr.msx.Parameter("Ka", 0.482, note="foo") + term1 = wntr.msx.Term("T0", "-3.2 * Kb * Cl^2", note="bar") + equil1 = wntr.msx.Reaction(bulk1, wntr.msx.ReactionType.PIPE, 'equil', "-Ka + Kb * Cl + T0") + rate1 = wntr.msx.Reaction(bulk1, wntr.msx.ReactionType.TANK, 'rate', "-Ka + Kb * Cl + T0", note="Foo Bar") + formula1 = wntr.msx.Reaction(wall1, wntr.msx.ReactionType.PIPE, 'formula', "-Ka + Kb * Cl + T0") + + bulk2 = rxn_model1.add_species("Cl", 'bulk', "mg") + wall2 = rxn_model1.add_species("ClOH", 'wall', "mg", 0.01, 0.0001, note="Testing stuff") + const2 = rxn_model1.add_constant("Kb", 0.482) + param2 = rxn_model1.add_parameter("Ka", 0.482, note="foo") + term2 = rxn_model1.add_term("T0", "-3.2 * Kb * Cl^2", note="bar") + equil2 = rxn_model1.add_reaction("Cl", "pipe", "equil", "-Ka + Kb * Cl + T0") + rate2 = rxn_model1.add_reaction("Cl", "tank", wntr.msx.ExpressionType.R, "-Ka + Kb * Cl + T0", note="Foo Bar") + formula2 = rxn_model1.add_reaction("ClOH", "PIPE", "formula", "-Ka + Kb * Cl + T0") + self.assertDictEqual(bulk1.to_dict(), bulk2.to_dict()) + self.assertDictEqual(wall1.to_dict(), wall2.to_dict()) + self.assertDictEqual(const1.to_dict(), const2.to_dict()) + self.assertDictEqual(param1.to_dict(), param2.to_dict()) + self.assertDictEqual(term1.to_dict(), term2.to_dict()) + self.assertDictEqual(equil1.to_dict(), equil2.to_dict()) + self.assertDictEqual(rate1.to_dict(), rate2.to_dict()) + self.assertDictEqual(formula1.to_dict(), formula2.to_dict()) + + +if __name__ == "__main__": + unittest.main(verbosity=2) diff --git a/wntr/tests/test_msx_variables.py b/wntr/tests/test_msx_variables.py deleted file mode 100644 index 429125a06..000000000 --- a/wntr/tests/test_msx_variables.py +++ /dev/null @@ -1,224 +0,0 @@ -import unittest -import warnings -from os.path import abspath, dirname, join - -import numpy as np -import pandas as pd -import wntr - -testdir = dirname(abspath(str(__file__))) -test_network_dir = join(testdir, "networks_for_testing") -test_data_dir = join(testdir, "data_for_testing") -ex_datadir = join(testdir, "..", "..", "examples", "networks") - - -class Test(unittest.TestCase): - @classmethod - def setUpClass(self): - pass - - @classmethod - def tearDownClass(self): - pass - - def test_ReactionVariable_reserved_name_exception(self): - self.assertRaises(ValueError, wntr.msx.Species, 'bulk', "D", "mg") - self.assertRaises(ValueError, wntr.msx.Species, 'wall', "Q", "mg") - self.assertRaises(ValueError, wntr.msx.Constant, "Re", 0.52) - self.assertRaises(ValueError, wntr.msx.Parameter, "Re", 0.52) - self.assertRaises(ValueError, wntr.msx.Term, "Re", 0.52) - - def test_RxnVariable_values(self): - const1 = wntr.msx.Constant("Kb", 0.482, note="test") - self.assertEqual(const1.value, 0.482) - param2 = wntr.msx.Parameter("Kb", 0.482, note="test") - self.assertEqual(param2.global_value, 0.482) - - def test_RxnVariable_string_functions(self): - species1 = wntr.msx.Species('Cl', 'BULK', "mg") - const1 = wntr.msx.Constant("Kb", 0.482) - param1 = wntr.msx.Parameter("Ka", 0.482, note="foo") - term1 = wntr.msx.Term("T0", "-3.2 * Kb * Cl^2", note="bar") - - self.assertEqual(str(species1), "Cl") - self.assertEqual(str(const1), "Kb") - self.assertEqual(str(param1), "Ka") - self.assertEqual(str(term1), "T0") - - def test_Species_tolerances(self): - # """RxnSpecies(*s) tolerance settings""" - species1 = wntr.msx.Species("B", "Cl", "mg") - species2 = wntr.msx.Species("W", "Cl", "mg", 0.01, 0.0001, note="Testing stuff") - self.assertIsNone(species1.get_tolerances()) - self.assertIsNotNone(species2.get_tolerances()) - self.assertTupleEqual(species2.get_tolerances(), (0.01, 0.0001)) - self.assertRaises(TypeError, species1.set_tolerances, None, 0.0001) - self.assertRaises(ValueError, species1.set_tolerances, -0.51, 0.01) - self.assertRaises(ValueError, species1.set_tolerances, 0.0, 0.0) - species1.set_tolerances(0.01, 0.0001) - self.assertEqual(species1._atol, 0.01) - self.assertEqual(species1._rtol, 0.0001) - species1.set_tolerances(None, None) - self.assertIsNone(species1._atol) - self.assertIsNone(species1._rtol) - species2.clear_tolerances() - self.assertIsNone(species1._atol) - self.assertIsNone(species1._rtol) - self.assertIsNone(species2.get_tolerances()) - - def test_BulkSpecies_creation(self): - # """BlukSpecies object creation (direct instantiation)""" - self.assertRaises(TypeError, wntr.msx.Species, "b", "Re") - self.assertRaises(ValueError, wntr.msx.Species, "B", "Re", "mg") - self.assertRaises(TypeError, wntr.msx.Species, 1, "Cl", "mg", 0.01) - self.assertRaises(TypeError, wntr.msx.Species, wntr.msx.base.SpeciesType.BULK, "Cl", "mg", None, 0.01) - species = wntr.msx.Species(1, "Cl", "mg") - self.assertEqual(species.name, "Cl") - self.assertEqual(species.units, "mg") - self.assertEqual(species.var_type, wntr.msx.SpeciesType.BULK) - self.assertIsNone(species._atol) - self.assertIsNone(species._rtol) - self.assertIsNone(species.note) - species = wntr.msx.Species('b', "Cl", "mg", 0.01, 0.0001, note="Testing stuff") - self.assertEqual(species.var_type, wntr.msx.SpeciesType.BULK) - self.assertEqual(species.name, "Cl") - self.assertEqual(species.units, "mg") - self.assertEqual(species._atol, 0.01) - self.assertEqual(species._rtol, 0.0001) - self.assertEqual(species.note, "Testing stuff") - - def test_WallSpecies_creation(self): - # """WallSpecies object creation (direct instantiation)""" - self.assertRaises(TypeError, wntr.msx.Species, 'W', "Re") - self.assertRaises(ValueError, wntr.msx.Species, 'Wall', "Re", "mg") - self.assertRaises(TypeError, wntr.msx.Species, 2, "Cl", "mg", 0.01) - self.assertRaises(TypeError, wntr.msx.Species, 'W', "Cl", "mg", None, 0.01) - species = wntr.msx.Species('w', "Cl", "mg") - self.assertEqual(species.name, "Cl") - self.assertEqual(species.units, "mg") - self.assertEqual(species.var_type, wntr.msx.SpeciesType.WALL) - self.assertIsNone(species._atol) - self.assertIsNone(species._rtol) - self.assertIsNone(species.note) - species = wntr.msx.Species('w', "Cl", "mg", 0.01, 0.0001, note="Testing stuff") - self.assertEqual(species.var_type, wntr.msx.SpeciesType.WALL) - self.assertEqual(species.name, "Cl") - self.assertEqual(species.units, "mg") - self.assertEqual(species._atol, 0.01) - self.assertEqual(species._rtol, 0.0001) - self.assertEqual(species.note, "Testing stuff") - - def test_Constant_creation(self): - self.assertRaises(TypeError, wntr.msx.Constant, "Re") - self.assertRaises(ValueError, wntr.msx.Constant, "Re", 2.48) - const1 = wntr.msx.Constant("Kb", 0.482, note="test") - # FIXME: Find a way to suppress warning printing - # self.assertWarns(RuntimeWarning, wntr.reaction.Constant, 'Kb1', 0.83, pipe_values={'a',1}) - self.assertEqual(const1.name, "Kb") - self.assertEqual(const1.value, 0.482) - self.assertEqual(const1.get_value(), const1.global_value) - self.assertEqual(const1.var_type, wntr.msx.VariableType.CONST) - self.assertEqual(const1.note, "test") - - def test_Parameter_creation(self): - self.assertRaises(TypeError, wntr.msx.Parameter, "Re") - self.assertRaises(ValueError, wntr.msx.Parameter, "Re", 2.48) - param1 = wntr.msx.Parameter("Kb", 0.482, note="test") - self.assertEqual(param1.name, "Kb") - self.assertEqual(param1.global_value, 0.482) - self.assertEqual(param1.get_value(), param1.global_value) - self.assertEqual(param1.var_type, wntr.msx.VariableType.PARAM) - self.assertEqual(param1.note, "test") - # test_pipe_dict = {"PIPE": 0.38} - # test_tank_dict = {"TANK": 222.23} - # param2 = wntr.msx.Parameter("Kb", 0.482, note="test", pipe_values=test_pipe_dict, tank_values=test_tank_dict) - # self.assertDictEqual(param2.pipe_values, test_pipe_dict) - # self.assertDictEqual(param2.tank_values, test_tank_dict) - - def test_RxnTerm_creation(self): - self.assertRaises(TypeError, wntr.msx.OtherTerm, "Re") - self.assertRaises(ValueError, wntr.msx.OtherTerm, "Re", "1.0*Re") - term1 = wntr.msx.OtherTerm("T0", "-3.2 * Kb * Cl^2", note="bar") - self.assertEqual(term1.name, "T0") - self.assertEqual(term1.expression, "-3.2 * Kb * Cl^2") - self.assertEqual(term1.var_type, wntr.msx.VariableType.TERM) - self.assertEqual(term1.note, "bar") - - def test_RxnExpression_strings(self): - equil1 = wntr.msx.EquilibriumDynamics("Cl", wntr.msx.ReactionType.PIPE, "-Ka + Kb * Cl + T0") - rate1 = wntr.msx.TankReaction("Cl", wntr.msx.ReactionType.TANK, "-Ka + Kb * Cl + T0", note="Foo Bar") - formula1 = wntr.msx.PipeReaction("Cl", wntr.msx.ReactionType.PIPE, "-Ka + Kb * Cl + T0") - - def test_Equilibrium_creation(self): - equil1 = wntr.msx.EquilibriumDynamics("Cl", wntr.msx.ReactionType.PIPE, "-Ka + Kb * Cl + T0") - self.assertEqual(equil1.species, "Cl") - self.assertEqual(equil1.expression, "-Ka + Kb * Cl + T0") - self.assertEqual(equil1.dynamics, wntr.msx.ExpressionType.EQUIL) - - def test_Rate_creation(self): - rate1 = wntr.msx.TankReaction("Cl", wntr.msx.ReactionType.TANK, "-Ka + Kb * Cl + T0", note="Foo Bar") - self.assertEqual(rate1.species_name, "Cl") - self.assertEqual(rate1.expression, "-Ka + Kb * Cl + T0") - self.assertEqual(rate1.dynamics, wntr.msx.ExpressionType.RATE) - self.assertEqual(rate1.note, "Foo Bar") - - def test_Formula_creation(self): - formula1 = wntr.msx.FormulaDynamics("Cl", wntr.msx.ReactionType.PIPE, "-Ka + Kb * Cl + T0") - self.assertEqual(formula1.species, "Cl") - self.assertEqual(formula1.expression, "-Ka + Kb * Cl + T0") - self.assertEqual(formula1.dynamics, wntr.msx.ExpressionType.FORMULA) - - def test_WaterQualityReactionsModel_creation_specific_everything(self): - rxn_model1 = wntr.msx.MsxModel() - bulk1 = wntr.msx.Species('b',"Cl", "mg") - wall1 = wntr.msx.Species('w', "ClOH", "mg", 0.01, 0.0001, note="Testing stuff") - const1 = wntr.msx.Constant("Kb", 0.482) - param1 = wntr.msx.Parameter("Ka", 0.482, note="foo") - term1 = wntr.msx.OtherTerm("T0", "-3.2 * Kb * Cl^2", note="bar") - equil1 = wntr.msx.EquilibriumDynamics(bulk1, wntr.msx.ReactionType.PIPE, "-Ka + Kb * Cl + T0") - rate1 = wntr.msx.TankReaction(bulk1, wntr.msx.ReactionType.TANK, "-Ka + Kb * Cl + T0", note="Foo Bar") - formula1 = wntr.msx.FormulaDynamics(wall1, wntr.msx.ReactionType.PIPE, "-Ka + Kb * Cl + T0") - - bulk2 = rxn_model1.add_bulk_species("Cl", "mg") - wall2 = rxn_model1.add_wall_species("ClOH", "mg", 0.01, 0.0001, note="Testing stuff") - const2 = rxn_model1.add_constant("Kb", 0.482) - param2 = rxn_model1.add_parameter("Ka", 0.482, note="foo") - term2 = rxn_model1.add_other_term("T0", "-3.2 * Kb * Cl^2", note="bar") - equil2 = rxn_model1.add_pipe_reaction("Cl", "equil", "-Ka + Kb * Cl + T0") - rate2 = rxn_model1.add_tank_reaction("Cl", wntr.msx.ExpressionType.R, "-Ka + Kb * Cl + T0", note="Foo Bar") - formula2 = rxn_model1.add_reaction("PIPE", "ClOH", "formula", "-Ka + Kb * Cl + T0") - self.assertEqual(bulk1, bulk2) - self.assertEqual(wall1, wall2) - self.assertEqual(const1, const2) - # self.assertEqual(param1, param2) # No good way to compare dicts inside - self.assertEqual(term1, term2) - # self.assertEqual(equil1, equil2) - # self.assertEqual(rate1, rate2) - # self.assertEqual(formula1, formula2) - - def test_WaterQualityReactionsModel_creation_generic_species_coeffs(self): - bulk1 = wntr.msx.Species('b', "Cl", "mg") - wall1 = wntr.msx.Species(2, "ClOH", "mg", 0.01, 0.0001, note="Testing stuff") - const1 = wntr.msx.Constant("Kb", 0.482) - param1 = wntr.msx.Parameter("Ka", 0.482, note="foo") - term1 = wntr.msx.OtherTerm("T0", "-3.2 * Kb * Cl^2", note="bar") - - rxn_model2 = wntr.msx.MsxModel() - - self.assertRaises(ValueError, rxn_model2.add_species, wntr.msx.VariableType.CONST, "Cl", "mg") - self.assertRaises(TypeError, rxn_model2.add_coefficient, None, "Kb", 0.482) - self.assertRaises(ValueError, rxn_model2.add_coefficient, "Wall", "Kb", 0.482) - - bulk3 = rxn_model2.add_species("BULK", "Cl", "mg") - wall3 = rxn_model2.add_species(wntr.msx.VariableType.WALL, "ClOH", "mg", 0.01, 0.0001, note="Testing stuff") - const3 = rxn_model2.add_coefficient("Consolation", "Kb", 0.482) - param3 = rxn_model2.add_coefficient(wntr.msx.VariableType.P, "Ka", 0.482, note="foo") - - self.assertEqual(bulk3, bulk1) - self.assertEqual(wall3, wall1) - self.assertEqual(const3, const1) - self.assertEqual(param3, param1) - - -if __name__ == "__main__": - unittest.main(verbosity=2) From f4244c773b672f993b7f2bcb396884b086e99b77 Mon Sep 17 00:00:00 2001 From: dbhart Date: Thu, 9 Nov 2023 15:47:54 -0700 Subject: [PATCH 41/75] Fix tolerances --- wntr/msx/elements.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/wntr/msx/elements.py b/wntr/msx/elements.py index e6c7eb289..82fa4236f 100644 --- a/wntr/msx/elements.py +++ b/wntr/msx/elements.py @@ -123,9 +123,9 @@ def set_tolerances(self, atol: float, rtol: float): ValueError if `atol` or `rtol` ≤ 0 """ - if (self.atol is None) ^ (self.rtol is None): + if (atol is None) ^ (rtol is None): raise TypeError("atol and rtol must both be float or both be None") - if self.atol is None: + if atol is None: self._tolerances = None elif atol <= 0 or rtol <= 0: raise ValueError("atol and rtol must both be positive, got atol={}, rtol={}".format(atol, rtol)) From 8d1a41eb033bb43cf2bafda073ea96dfb3a1329e Mon Sep 17 00:00:00 2001 From: Katherine Klise Date: Thu, 9 Nov 2023 16:29:53 -0800 Subject: [PATCH 42/75] MSX documentation update --- documentation/advancedsim.rst | 359 +++++++++++++++++++++++++++++ documentation/conf.py | 2 +- documentation/hydraulics.rst | 3 +- documentation/index.rst | 2 +- documentation/reference.rst | 4 + documentation/waterquality.rst | 12 +- documentation/waterquality_msx.rst | 92 ++++++++ 7 files changed, 468 insertions(+), 6 deletions(-) create mode 100644 documentation/waterquality_msx.rst diff --git a/documentation/advancedsim.rst b/documentation/advancedsim.rst index 4a8be4fe7..1944c9c70 100644 --- a/documentation/advancedsim.rst +++ b/documentation/advancedsim.rst @@ -248,3 +248,362 @@ The solution for :math:`u` and :math:`v` is then returned and printed to four si 1.618 >>> np.round(m.v.value,4) 2.618 + +Building MSX models +------------------- + +The following two examples illustrate how to build :class:`~wntr.msx.model.MsxModel` objects in WNTR + +.. _msx_example1_lead: + +Plumbosolvency of lead +^^^^^^^^^^^^^^^^^^^^^^ + +The following example builds the plumbosolvency of lead model +described in [BWMS20]_. The model represents plumbosolvency +in lead pipes within a dwelling. +The MSX model is built without a specific water network model in mind. + +Model development starts by defining the model +name, +title, +description, and +reference. + +.. doctest:: + + >>> import wntr.msx + >>> msx = wntr.msx.MsxModel() + >>> msx.name = "lead_ppm" + >>> msx.title = "Lead Plumbosolvency Model (from Burkhardt et al 2020)" + >>> msx.desc = "Parameters for EPA HPS Simulator Model" + >>> msx.references.append( + ... """J. B. Burkhardt, et al. (2020) https://doi.org/10.1061/(asce)wr.1943-5452.0001304""" + ... ) + >>> msx + MultispeciesQualityModel(name='lead_ppm') + +Model options are added as follows: + +.. doctest:: + + >>> msx.options = { + ... "report": { + ... "species": {"PB2": "YES"}, + ... "species_precision": {"PB2": 5}, + ... "nodes": "all", + ... "links": "all", + ... }, + ... "timestep": 1, + ... "area_units": "M2", + ... "rate_units": "SEC", + ... "rtol": 1e-08, + ... "atol": 1e-08, + ... } + +There is only one species defined in this model, which is dissolved lead. + +======================== =============== ================================= ======================== +Name Type Units Note +------------------------ --------------- --------------------------------- ------------------------ +:math:`Pb` bulk species :math:`\mathrm{μg}_\mathrm{(Pb)}` dissolved lead +======================== =============== ================================= ======================== + +The species is added to the MsxModel using the using the +:meth:`~wntr.msx.model.MsxModel.add_species` method. +This method adds the new species to the model and also return a copy of the new species object. + +.. doctest:: + + >>> msx.add_species(name="PB2", species_type='bulk', units="ug", note="dissolved lead (Pb)") + Species(name='PB2', species_type=, units='ug', atol=None, rtol=None, note='dissolved lead (Pb)') + +The new species can be accessed by using the item's name and indexing on the model's +:attr:`~wntr.msx.model.MsxModel.reaction_system` attribute. + + >>> PB2 = msx.reaction_system['PB2'] + >>> PB2 + Species(name='PB2', species_type=, units='ug', atol=None, rtol=None, note='dissolved lead (Pb)') + +The model also includes two constants and one parameter. + +=============== =============== =============== ================================= ======================== +Type Name Value Units Note +--------------- --------------- --------------- --------------------------------- ------------------------ +constant :math:`M` 0.117 :math:`\mathrm{μg~m^{-2}~s^{-1}}` desorption rate +constant :math:`E` 140.0 :math:`\mathrm{μg~L^{-1}}` saturation level +parameter :math:`F` 0 `n/a` is pipe made of lead? +=============== =============== =============== ================================= ======================== + +These are added to the MsxModel using the using the +:meth:`~wntr.msx.model.MsxModel.add_constant` and +:meth:`~wntr.msx.model.MsxModel.add_parameter` methods. +methods. + +.. doctest:: + + >>> msx.add_constant("M", value=0.117, note="Desorption rate (ug/m^2/s)", units="ug * m^(-2) * s^(-1)") + >>> msx.add_constant("E", value=140.0, note="saturation/plumbosolvency level (ug/L)", units="ug/L") + >>> msx.add_parameter("F", global_value=0, note="determines which pipes have reactions") + +Note that all models must include both pipe and tank reactions. +Since the model only has reactions within +pipes, tank reactions need to be unchanging. +The system of equations defined as follows: + +.. math:: + + \frac{d}{dt}Pb_p &= F_p \, Av_p \, M \frac{\left( E - Pb_p \right)}{E}, &\quad\text{for all pipes}~p~\text{in network} \\ + \frac{d}{dt}Pb_t &= 0, & \quad\text{for all tanks}~t~\text{in network} + +Note that the pipe reaction has a variable that has not been defined, :math:`Av`; +this variable is a pre-defined hydraulic variable. The list of these variables can be found in +the EPANET-MSX documentation, and also in the :attr:`~wntr.msx.base.HYDRAULIC_VARIABLES` +documentation. The reactions are defined as follows: + +================ ============== ========================================================================== +Reaction type Dynamics type Reaction expression +---------------- -------------- -------------------------------------------------------------------------- +pipe rate :math:`F \cdot Av \cdot M \cdot \left( E - Pb \right) / E` +tank rate :math:`0` +================ ============== ========================================================================== + +The reactions are added to the MsxModel using the :meth:`~wntr.msx.model.MsxModel.add_reaction` +method. + +.. doctest:: + + >>> msx.add_reaction("PB2", "pipe", "RATE", expression="F * Av * M * (E - PB2) / E") + >>> msx.add_reaction(PB2, "tank", "rate", expression="0") + +Arsenic oxidation and adsorption +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +This example models monochloramine oxidation of arsenite/arsenate and wall +adsorption/desorption, as given in section 3 of the EPANET-MSX user manual [SRU23]_. + +The system of equations for the reaction in pipes is given in Eq. (2.4) through (2.7) +in [SRU23]_. This is a simplified model, taken from [GSCL94]_. + +.. math:: + + \frac{d}{dt}{(\mathsf{As}^\mathrm{III})} &= -k_a ~ {(\mathsf{As}^\mathrm{III})} ~ {(\mathsf{NH_2Cl})} \\ + \frac{d}{dt}{(\mathsf{As}^\mathrm{V})} &= k_a ~ {(\mathsf{As}^\mathrm{III})} ~ {(\mathsf{NH_2CL})} - Av \left( k_1 \left(S_\max - {(\mathsf{As}^\mathrm{V}_s)} \right) {(\mathsf{As}^\mathrm{V})} - k_2 ~ {(\mathsf{As}^\mathrm{V}_s)} \right) \\ + \frac{d}{dt}{(\mathsf{NH_2Cl})} &= -k_b ~ {(\mathsf{NH_2Cl})} \\ + {(\mathsf{As}^\mathrm{V}_s)} &= \frac{k_s ~ S_\max ~ {(\mathsf{As}^\mathrm{V})}}{1 + k_s {(\mathsf{As}^\mathrm{V})}} + + +where the various species, coefficients, and expressions are described in the tables below. + + +.. list-table:: Options + :header-rows: 1 + :widths: 3 3 10 + + * - Option + - Code + - Description + * - Rate units + - "HR" + - :math:`\mathrm{h}^{-1}` + * - Area units + - "M2" + - :math:`\mathrm{m}^2` + + +.. list-table:: Species + :header-rows: 1 + :widths: 2 2 2 3 4 6 + + * - Name + - Type + - Value + - Symbol + - Units + - Note + * - AS3 + - Bulk + - "UG" + - :math:`{\mathsf{As}^\mathrm{III}}` + - :math:`\require{upgreek}\upmu\mathrm{g~L^{-1}}` + - dissolved arsenite + * - AS5 + - Bulk + - "UG" + - :math:`{\mathsf{As}^\mathrm{V}}` + - :math:`\require{upgreek}\upmu\mathrm{g~L^{-1}}` + - dissolved arsenate + * - AStot + - Bulk + - "UG" + - :math:`{\mathsf{As}^\mathrm{tot}}` + - :math:`\require{upgreek}\upmu\mathrm{g~L^{-1}}` + - dissolved arsenic (total) + * - NH2CL + - Bulk + - "MG" + - :math:`{\mathsf{NH_2Cl}}` + - :math:`\mathrm{mg~L^{-1}}` + - dissolved monochloramine + * - AS5s + - Wall + - "UG" + - :math:`{\mathsf{As}^\mathrm{V}_{s}}` + - :math:`\require{upgreek}\upmu\mathrm{g}~\mathrm{m}^{-2}` + - adsorped arsenate (surface) + + +.. list-table:: Coefficients + :header-rows: 1 + :widths: 2 2 2 3 4 6 + + * - Name + - Type + - Value + - Symbol + - Units + - Note + * - Ka + - Const + - :math:`10` + - :math:`k_a` + - :math:`\mathrm{mg}^{-1}_{\left(\mathsf{NH_2Cl}\right)}~\mathrm{h}^{-1}` + - arsenite oxidation + * - Kb + - Const + - :math:`0.1` + - :math:`k_b` + - :math:`\mathrm{h}^{-1}` + - chloromine decay + * - K1 + - Const + - :math:`5.0` + - :math:`k_1` + - :math:`\require{upgreek}\textrm{L}~\upmu\mathrm{g}^{-1}_{\left(\mathsf{As}^\mathrm{V}\right)}~\mathrm{h}^{-1}` + - arsenate adsorption + * - K2 + - Const + - :math:`1.0` + - :math:`k_2` + - :math:`\textrm{L}~\mathrm{h}^{-1}` + - arsenate desorption + * - Smax + - Const + - :math:`50.0` + - :math:`S_{\max}` + - :math:`\require{upgreek}\upmu\mathrm{g}_{\left(\mathsf{As}^\mathrm{V}\right)}~\mathrm{m}^{-2}` + - arsenate adsorption limit + + +.. list-table:: Other terms + :header-rows: 1 + :widths: 3 3 2 3 10 + + * - Name + - Symbol + - Expression + - Units + - Note + * - Ks + - :math:`k_s` + - :math:`{k_1}/{k_2}` + - :math:`\require{upgreek}\upmu\mathrm{g}^{-1}_{\left(\mathsf{As}^\mathrm{V}\right)}` + - equilibrium adsorption coefficient + + +.. list-table:: Pipe reactions + :header-rows: 1 + :widths: 3 3 16 + + * - Species + - Type + - Expression + * - AS3 + - Rate + - :math:`-k_a \, {\mathsf{As}^\mathrm{III}} \, {\mathsf{NH_2Cl}}` + * - AS5 + - Rate + - :math:`k_a \, {\mathsf{As}^\mathrm{III}} \, {\mathsf{NH_2Cl}} -Av \left( k_1 \left(S_{\max}-{\mathsf{As}^\mathrm{V}_{s}} \right) {\mathsf{As}^\mathrm{V}} - k_2 \, {\mathsf{As}^\mathrm{V}_{s}} \right)` + * - NH2CL + - Rate + - :math:`-k_b \, {\mathsf{NH_2Cl}}` + * - AStot + - Formula + - :math:`{\mathsf{As}^\mathrm{III}} + {\mathsf{As}^\mathrm{V}}` + * - AS5s + - Equil + - :math:`k_s \, S_{\max} \frac{{\mathsf{As}^\mathrm{V}}}{1 + k_s \, {\mathsf{As}^\mathrm{V}}} - {\mathsf{As}^\mathrm{V}_{s}}` + + +.. list-table:: Tank reactions + :header-rows: 1 + :widths: 3 3 16 + + * - Species + - Type + - Expression + * - AS3 + - Rate + - :math:`-k_a \, {\mathsf{As}^\mathrm{III}} \, {\mathsf{NH_2Cl}}` + * - AS5 + - Rate + - :math:`k_a \, {\mathsf{As}^\mathrm{III}} \, {\mathsf{NH_2Cl}}` + * - NH2CL + - Rate + - :math:`-k_b \, {\mathsf{NH_2Cl}}` + * - AStot + - Formula + - :math:`{\mathsf{As}^\mathrm{III}} + {\mathsf{As}^\mathrm{V}}` + * - AS5s + - Equil + - :math:`0` (`not present in tanks`) + + +The model is created in WTNR as shown below. + +.. doctest:: + + >>> msx = wntr.msx.MsxModel() + >>> msx.name = "arsenic_chloramine" + >>> msx.title = "Arsenic Oxidation/Adsorption Example" + >>> msx.references.append(wntr.msx.library.cite_msx()) + + >>> AS3 = msx.add_species(name="AS3", species_type="BULK", units="UG", note="Dissolved arsenite") + >>> AS5 = msx.add_species(name="AS5", species_type="BULK", units="UG", note="Dissolved arsenate") + >>> AStot = msx.add_species(name="AStot", species_type="BULK", units="UG", + ... note="Total dissolved arsenic") + >>> AS5s = msx.add_species(name="AS5s", species_type="WALL", units="UG", note="Adsorbed arsenate") + >>> NH2CL = msx.add_species(name="NH2CL", species_type="BULK", units="MG", note="Monochloramine") + + >>> Ka = msx.add_constant("Ka", 10.0, units="1 / (MG * HR)", note="Arsenite oxidation rate coeff") + >>> Kb = msx.add_constant("Kb", 0.1, units="1 / HR", note="Monochloramine decay rate coeff") + >>> K1 = msx.add_constant("K1", 5.0, units="M^3 / (UG * HR)", note="Arsenate adsorption coeff") + >>> K2 = msx.add_constant("K2", 1.0, units="1 / HR", note="Arsenate desorption coeff") + >>> Smax = msx.add_constant("Smax", 50.0, units="UG / M^2", note="Arsenate adsorption limit") + + >>> Ks = msx.add_term(name="Ks", expression="K1/K2", note="Equil. adsorption coeff") + + >>> _ = msx.add_reaction(species_name="AS3", reaction_type="pipes", expression_type="rate", + ... expression="-Ka*AS3*NH2CL", note="Arsenite oxidation") + >>> _ = msx.add_reaction("AS5", "pipes", "rate", "Ka*AS3*NH2CL - Av*(K1*(Smax-AS5s)*AS5 - K2*AS5s)", + ... note="Arsenate production less adsorption") + >>> _ = msx.add_reaction( + ... species_name="NH2CL", reaction_type="pipes", expression_type="rate", expression="-Kb*NH2CL", + ... note="Monochloramine decay") + >>> _ = msx.add_reaction("AS5s", "pipe", "equil", "Ks*Smax*AS5/(1+Ks*AS5) - AS5s", + ... note="Arsenate adsorption") + >>> _ = msx.add_reaction(species_name="AStot", reaction_type="pipes", expression_type="formula", + ... expression="AS3 + AS5", note="Total arsenic") + >>> _ = msx.add_reaction(species_name="AS3", reaction_type="tank", expression_type="rate", + ... expression="-Ka*AS3*NH2CL", note="Arsenite oxidation") + >>> _ = msx.add_reaction(species_name="AS5", reaction_type="tank", expression_type="rate", + ... expression="Ka*AS3*NH2CL", note="Arsenate production") + >>> _ = msx.add_reaction(species_name="NH2CL", reaction_type="tank", expression_type="rate", + ... expression="-Kb*NH2CL", note="Monochloramine decay") + >>> _ = msx.add_reaction(species_name="AStot", reaction_type="tanks", expression_type="formula", + ... expression="AS3 + AS5", note="Total arsenic") + + >>> msx.options.area_units = "M2" + >>> msx.options.rate_units = "HR" + >>> msx.options.rtol = 0.001 + >>> msx.options.atol = 0.0001 diff --git a/documentation/conf.py b/documentation/conf.py index f9eef5dfc..d45b8e778 100644 --- a/documentation/conf.py +++ b/documentation/conf.py @@ -108,7 +108,7 @@ # If true, '()' will be appended to :func: etc. cross-reference text. #add_function_parentheses = True -autodoc_type_aliases = {'DataFrame': 'pandas DataFrame', 'MsxVariable': ':class:`~wntr.msx.model.MsxVariable`', 'NoteType': ':class:`~wntr.epanet.util.NoteType`'} +#autodoc_type_aliases = {'DataFrame': 'pandas DataFrame', 'MsxVariable': ':class:`~wntr.msx.model.MsxVariable`', 'NoteType': ':class:`~wntr.epanet.util.NoteType`'} # If true, the current module name will be prepended to all description # unit titles (such as .. function::). diff --git a/documentation/hydraulics.rst b/documentation/hydraulics.rst index 0c755bda5..8a4714d82 100644 --- a/documentation/hydraulics.rst +++ b/documentation/hydraulics.rst @@ -9,10 +9,11 @@ Hydraulic simulation WNTR contains two simulators: the EpanetSimulator and the WNTRSimulator. See :ref:`software_framework` for more information on features and limitations of these simulators. +Additional hydraulic simulation options are included in :ref:`advanced_simulation`. EpanetSimulator ----------------- -The EpanetSimulator can be used to run EPANET 2.00.12 Programmer's Toolkit [Ross00]_ or EPANET 2.2.0 Programmer's Toolkit [RWTS20]_. +The EpanetSimulator can be used to run a hydraulic simulation using the EPANET 2.00.12 Programmer's Toolkit [Ross00]_ or EPANET 2.2.0 Programmer's Toolkit [RWTS20]_. EPANET 2.2.0 is used by default and runs demand-driven and pressure dependent hydraulic analysis. EPANET 2.00.12 runs demand-driven hydraulic analysis only. Both versions can also run water quality simulations, as described in :ref:`water_quality_simulation`. diff --git a/documentation/index.rst b/documentation/index.rst index f7d9e1c42..003bde8c1 100644 --- a/documentation/index.rst +++ b/documentation/index.rst @@ -21,6 +21,7 @@ designed to simulate and analyze resilience of water distribution networks. options hydraulics waterquality + waterquality_msx resultsobject disaster_models criticality @@ -30,7 +31,6 @@ designed to simulate and analyze resilience of water distribution networks. graphics gis advancedsim - advancedqual license whatsnew developers diff --git a/documentation/reference.rst b/documentation/reference.rst index 6d74bce38..3fadfd9d5 100644 --- a/documentation/reference.rst +++ b/documentation/reference.rst @@ -18,10 +18,14 @@ References .. [Bieni19] Bieniek, T., van Andel, B., and Bø, T.I. (2019). Bidirectional UTM-WGS84 converter for python, Retrieved on February 5, 2019 from https://github.com/Turbo87/utm. +.. [BWMS20] Burkhardt, J. B., Woo, J., Mason, J., Shang, F., Triantafyllidou, S., Schock, M.R., Lytle, D., and Murray, R. (2020). Framework for Modeling Lead in Premise Plumbing Systems Using EPANET. Journal of Water Resources Planning and Management, 146(12). https://doi.org/10.1061/(asce)wr.1943-5452.0001304 PMID:33627937. + .. [CrLo02] Crowl, D.A., and Louvar, J.F. (2011). Chemical Process Safety: Fundamentals with Applications, 3 edition. Upper Saddle River, NJ: Prentice Hall, 720p. .. [ELLT12] Eto, J.H., LaCommare, K.H., Larsen, P.H., Todd, A., and Fisher, E. (2012). An Examination of Temporal Trends in Electricity Reliability Based on Reports from U.S. Electric Utilities. Lawrence Berkeley National Laboratory Report Number LBNL-5268E. Berkeley, CA: Ernest Orlando Lawrence Berkeley National Laboratory, 68p. +.. [GSCL94] Gu, B., Schmitt, J., Chen, Z. Liang, L., and McCarthy, J.F. (1994) Adsorption and desorption of natural organic matter on iron oxide: mechanisms and models. Environmental Science and Technology, 28:38-46. + .. [JVFM21] Jordahl, K., Van den Bossche, J., Fleischmann, M, McBride, J. and others (2021) geopandas, 10.5281/zenodo.5573592. .. [Folium] python-visualization/folium. (n.d.). Retrieved on February 5, 2019 from https://github.com/python-visualization/folium. diff --git a/documentation/waterquality.rst b/documentation/waterquality.rst index fa784d531..8b8c6ee37 100644 --- a/documentation/waterquality.rst +++ b/documentation/waterquality.rst @@ -17,7 +17,12 @@ Water quality simulation ================================== Water quality simulations can only be run using the EpanetSimulator. - +This includes the ability to run +EPANET 2.00.12 Programmer's Toolkit [Ross00]_ or +EPANET 2.2.0 Programmer's Toolkit [RWTS20]_ for single species, water age, and tracer analysis. + +WNTR also includes the ability to run EPANET-MSX 2.0 [SRU23]_, see :ref:`msx_water_quality` for more information. + After defining water quality options and sources (described in the :ref:`wq_options` and :ref:`sources` sections below), a hydraulic and water quality simulation using the EpanetSimulator is run using the following code: @@ -34,7 +39,7 @@ The results include a quality value for each node (see :ref:`simulation_results` .. _wq_options: Water quality options ------------------------- +--------------------- Three types of water quality analysis are supported. These options include water age, tracer, and chemical concentration. * **Water age**: A water quality simulation can be used to compute water age at every node. @@ -83,7 +88,7 @@ More information on water network options can be found in :ref:`options`. .. _sources: Sources ------------- +------- Sources are required for CHEMICAL water quality analysis. Sources can still be defined, but *will not* be used if AGE, TRACE, or NONE water quality analysis is selected. Sources are added to the water network model using the :class:`~wntr.network.model.WaterNetworkModel.add_source` method. @@ -135,6 +140,7 @@ In the example below, the strength of the source is changed from 1000 to 1500. When creating a water network model from an EPANET INP file, the sources that are defined in the [SOURCES] section are added to the water network model. These sources are given the name 'INP#' where # is an integer representing the number of sources in the INP file. + .. The following is not shown in the UM _wq_pdd: diff --git a/documentation/waterquality_msx.rst b/documentation/waterquality_msx.rst new file mode 100644 index 000000000..2fa6aa823 --- /dev/null +++ b/documentation/waterquality_msx.rst @@ -0,0 +1,92 @@ +.. raw:: latex + + \clearpage + +.. doctest:: + :hide: + + >>> import wntr + >>> try: + ... wn = wntr.network.model.WaterNetworkModel('../examples/networks/Net3.inp') + ... msx_filename = '../examples/data/something.msx' + ... except: + ... wn = wntr.network.model.WaterNetworkModel('examples/networks/Net3.inp') + ... msx_filename = 'examples/data/something.msx' + +.. _msx_water_quality: + +Multi-species water quality simulation +======================================= + +The EpanetSimulator can use EPANET-MSX 2.0 [SRU23]_ to run +multi-species water quality simulations. +Additional multi-species simulation options are discussed in :ref:`advanced_simulation`. + +A multi-species analysis is run if a :class:`~wntr.msx.model.MsxModel` is added to the +:class:`~wntr.network.model.WaterNetworkModel`, as shown below. +In this example, the MsxModel is created from a MSX file (see [SRU23]_ for more information on file format). + +.. doctest:: + + >>> msx_filename = 'data/something.msx') # doctest: +SKIP + >>> wn.msx = wntr.msx.MsxModel(msx_filename) + >>> sim = wntr.sim.EpanetSimulator(wn) + >>> results = sim.run_sim() +[TODO add an msx file that uses Net3 to the examples folder for documentation examples] + +The results include a quality value for each node, link, and species +(see :ref:`simulation_results` for more details). + +Multi-species model +------------------- +In addition to creating an MsxModel from a MSX file, the MsxModel +can be built from scratch and modified using WNTR. +For example, the user can +add and remove species using :class:`~wntr.msx.model.MsxModel.add_species` and :class:`~wntr.msx.model.MsxModel.remove_species`, or +add and remove reactions using :class:`~wntr.msx.model.MsxModel.add_reaction` and :class:`~wntr.msx.model.MsxModel.remove_reaction`. +See the API documentation for the :class:`~wntr.msx.model.MsxModel` for a complete list of methods. + +Variables +~~~~~~~~~ +Variables include **species**, **coefficients**, and **terms**. +These are used in **expressions** to define the dynamics of the reaction. All variables have at least two +attributes: a name and a note. +The variable name must be a valid EPANET-MSX id, which primarily +means no spaces are permitted. However, it may be useful to ensure that the name is a valid python +variable name, so that it can be used to identify the variable in your code as well. +The note can be a string, a dictionary with the keys "pre" and "post", or an :class:`~wntr.epanet.util.ENcomment` object +(which has a "pre" and "post" attribute). See the ENcomment documentation for details on the meaning; +in this example the string form of the note is used. + +There are two different types of coefficients that can be used in reaction expressions: **constants** +and **parameters**. Constants have a single value in every expression. Parameters have a global value +that is used by default, but which can be modified on a per-pipe or per-tank basis. + +Pre-defined hydraulic variable can be found in +the EPANET-MSX documentation, and are also defined in WNTR as :attr:`~wntr.msx.base.HYDRAULIC_VARIABLES`. + +Reactions +~~~~~~~~~ +All species must have two reactions defined for the model to be run successfully in EPANET-MSX by WNTR. +One is a **pipe reaction**, the other is a **tank reaction**. + +Examples that illustrate how to build MSX models in WNTR are included in :ref:`advanced_simulation`. + +Reaction library +----------------- +WNTR also contains a library of MSX models that are accessed through the :class:`~wntr.msx.library.ReactionLibrary`. +This includes the following models: + +* `Arsenic Chloramine model `_ [SRU23]_ +* `Lead Plumbosolvency model `_ [BWMS20]_ +[TODO change the 2 links to usepa, add other models if they are referenced] + +The models are stored in JSON format. +Additional models can be loaded into the library by setting a user specified path. +Additional models could also be added to the WNTR Reactions library. + +The following example loads a MsxModel from the ReactionLibrary. + +.. doctest:: + + >>> msx_model = ... From 0b11e421145b71cbccdfca7643a177dca2449f9d Mon Sep 17 00:00:00 2001 From: Katherine Klise Date: Thu, 9 Nov 2023 17:01:54 -0800 Subject: [PATCH 43/75] minor updates --- documentation/hydraulics.rst | 2 +- documentation/waterquality_msx.rst | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/documentation/hydraulics.rst b/documentation/hydraulics.rst index 8a4714d82..f284024b7 100644 --- a/documentation/hydraulics.rst +++ b/documentation/hydraulics.rst @@ -9,7 +9,7 @@ Hydraulic simulation WNTR contains two simulators: the EpanetSimulator and the WNTRSimulator. See :ref:`software_framework` for more information on features and limitations of these simulators. -Additional hydraulic simulation options are included in :ref:`advanced_simulation`. +Additional hydraulic simulation options are discussed in :ref:`advanced_simulation`. EpanetSimulator ----------------- diff --git a/documentation/waterquality_msx.rst b/documentation/waterquality_msx.rst index 2fa6aa823..d6314097c 100644 --- a/documentation/waterquality_msx.rst +++ b/documentation/waterquality_msx.rst @@ -90,3 +90,4 @@ The following example loads a MsxModel from the ReactionLibrary. .. doctest:: >>> msx_model = ... +[TODO finish this example] From cdcb4d1732878f943b694c1fe9d15d19f9852e82 Mon Sep 17 00:00:00 2001 From: Katherine Klise Date: Fri, 10 Nov 2023 12:12:55 -0800 Subject: [PATCH 44/75] MSX docs update (#135) * Add scheduled testing to workflow * MSX documentation update * minor updates --------- Co-authored-by: Kirk Bonney <47759761+kbonney@users.noreply.github.com> --- .github/workflows/build_tests.yml | 2 + documentation/advancedsim.rst | 359 +++++++++++++++++++++++++++++ documentation/conf.py | 2 +- documentation/hydraulics.rst | 3 +- documentation/index.rst | 2 +- documentation/reference.rst | 4 + documentation/waterquality.rst | 12 +- documentation/waterquality_msx.rst | 93 ++++++++ 8 files changed, 471 insertions(+), 6 deletions(-) create mode 100644 documentation/waterquality_msx.rst diff --git a/.github/workflows/build_tests.yml b/.github/workflows/build_tests.yml index 06c3ce6a1..21509c083 100644 --- a/.github/workflows/build_tests.yml +++ b/.github/workflows/build_tests.yml @@ -8,6 +8,8 @@ on: branches: [ main, dev ] pull_request: branches: [ main, dev ] + schedule: + - cron: '0 0 1 * *' jobs: diff --git a/documentation/advancedsim.rst b/documentation/advancedsim.rst index 4a8be4fe7..1944c9c70 100644 --- a/documentation/advancedsim.rst +++ b/documentation/advancedsim.rst @@ -248,3 +248,362 @@ The solution for :math:`u` and :math:`v` is then returned and printed to four si 1.618 >>> np.round(m.v.value,4) 2.618 + +Building MSX models +------------------- + +The following two examples illustrate how to build :class:`~wntr.msx.model.MsxModel` objects in WNTR + +.. _msx_example1_lead: + +Plumbosolvency of lead +^^^^^^^^^^^^^^^^^^^^^^ + +The following example builds the plumbosolvency of lead model +described in [BWMS20]_. The model represents plumbosolvency +in lead pipes within a dwelling. +The MSX model is built without a specific water network model in mind. + +Model development starts by defining the model +name, +title, +description, and +reference. + +.. doctest:: + + >>> import wntr.msx + >>> msx = wntr.msx.MsxModel() + >>> msx.name = "lead_ppm" + >>> msx.title = "Lead Plumbosolvency Model (from Burkhardt et al 2020)" + >>> msx.desc = "Parameters for EPA HPS Simulator Model" + >>> msx.references.append( + ... """J. B. Burkhardt, et al. (2020) https://doi.org/10.1061/(asce)wr.1943-5452.0001304""" + ... ) + >>> msx + MultispeciesQualityModel(name='lead_ppm') + +Model options are added as follows: + +.. doctest:: + + >>> msx.options = { + ... "report": { + ... "species": {"PB2": "YES"}, + ... "species_precision": {"PB2": 5}, + ... "nodes": "all", + ... "links": "all", + ... }, + ... "timestep": 1, + ... "area_units": "M2", + ... "rate_units": "SEC", + ... "rtol": 1e-08, + ... "atol": 1e-08, + ... } + +There is only one species defined in this model, which is dissolved lead. + +======================== =============== ================================= ======================== +Name Type Units Note +------------------------ --------------- --------------------------------- ------------------------ +:math:`Pb` bulk species :math:`\mathrm{μg}_\mathrm{(Pb)}` dissolved lead +======================== =============== ================================= ======================== + +The species is added to the MsxModel using the using the +:meth:`~wntr.msx.model.MsxModel.add_species` method. +This method adds the new species to the model and also return a copy of the new species object. + +.. doctest:: + + >>> msx.add_species(name="PB2", species_type='bulk', units="ug", note="dissolved lead (Pb)") + Species(name='PB2', species_type=, units='ug', atol=None, rtol=None, note='dissolved lead (Pb)') + +The new species can be accessed by using the item's name and indexing on the model's +:attr:`~wntr.msx.model.MsxModel.reaction_system` attribute. + + >>> PB2 = msx.reaction_system['PB2'] + >>> PB2 + Species(name='PB2', species_type=, units='ug', atol=None, rtol=None, note='dissolved lead (Pb)') + +The model also includes two constants and one parameter. + +=============== =============== =============== ================================= ======================== +Type Name Value Units Note +--------------- --------------- --------------- --------------------------------- ------------------------ +constant :math:`M` 0.117 :math:`\mathrm{μg~m^{-2}~s^{-1}}` desorption rate +constant :math:`E` 140.0 :math:`\mathrm{μg~L^{-1}}` saturation level +parameter :math:`F` 0 `n/a` is pipe made of lead? +=============== =============== =============== ================================= ======================== + +These are added to the MsxModel using the using the +:meth:`~wntr.msx.model.MsxModel.add_constant` and +:meth:`~wntr.msx.model.MsxModel.add_parameter` methods. +methods. + +.. doctest:: + + >>> msx.add_constant("M", value=0.117, note="Desorption rate (ug/m^2/s)", units="ug * m^(-2) * s^(-1)") + >>> msx.add_constant("E", value=140.0, note="saturation/plumbosolvency level (ug/L)", units="ug/L") + >>> msx.add_parameter("F", global_value=0, note="determines which pipes have reactions") + +Note that all models must include both pipe and tank reactions. +Since the model only has reactions within +pipes, tank reactions need to be unchanging. +The system of equations defined as follows: + +.. math:: + + \frac{d}{dt}Pb_p &= F_p \, Av_p \, M \frac{\left( E - Pb_p \right)}{E}, &\quad\text{for all pipes}~p~\text{in network} \\ + \frac{d}{dt}Pb_t &= 0, & \quad\text{for all tanks}~t~\text{in network} + +Note that the pipe reaction has a variable that has not been defined, :math:`Av`; +this variable is a pre-defined hydraulic variable. The list of these variables can be found in +the EPANET-MSX documentation, and also in the :attr:`~wntr.msx.base.HYDRAULIC_VARIABLES` +documentation. The reactions are defined as follows: + +================ ============== ========================================================================== +Reaction type Dynamics type Reaction expression +---------------- -------------- -------------------------------------------------------------------------- +pipe rate :math:`F \cdot Av \cdot M \cdot \left( E - Pb \right) / E` +tank rate :math:`0` +================ ============== ========================================================================== + +The reactions are added to the MsxModel using the :meth:`~wntr.msx.model.MsxModel.add_reaction` +method. + +.. doctest:: + + >>> msx.add_reaction("PB2", "pipe", "RATE", expression="F * Av * M * (E - PB2) / E") + >>> msx.add_reaction(PB2, "tank", "rate", expression="0") + +Arsenic oxidation and adsorption +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +This example models monochloramine oxidation of arsenite/arsenate and wall +adsorption/desorption, as given in section 3 of the EPANET-MSX user manual [SRU23]_. + +The system of equations for the reaction in pipes is given in Eq. (2.4) through (2.7) +in [SRU23]_. This is a simplified model, taken from [GSCL94]_. + +.. math:: + + \frac{d}{dt}{(\mathsf{As}^\mathrm{III})} &= -k_a ~ {(\mathsf{As}^\mathrm{III})} ~ {(\mathsf{NH_2Cl})} \\ + \frac{d}{dt}{(\mathsf{As}^\mathrm{V})} &= k_a ~ {(\mathsf{As}^\mathrm{III})} ~ {(\mathsf{NH_2CL})} - Av \left( k_1 \left(S_\max - {(\mathsf{As}^\mathrm{V}_s)} \right) {(\mathsf{As}^\mathrm{V})} - k_2 ~ {(\mathsf{As}^\mathrm{V}_s)} \right) \\ + \frac{d}{dt}{(\mathsf{NH_2Cl})} &= -k_b ~ {(\mathsf{NH_2Cl})} \\ + {(\mathsf{As}^\mathrm{V}_s)} &= \frac{k_s ~ S_\max ~ {(\mathsf{As}^\mathrm{V})}}{1 + k_s {(\mathsf{As}^\mathrm{V})}} + + +where the various species, coefficients, and expressions are described in the tables below. + + +.. list-table:: Options + :header-rows: 1 + :widths: 3 3 10 + + * - Option + - Code + - Description + * - Rate units + - "HR" + - :math:`\mathrm{h}^{-1}` + * - Area units + - "M2" + - :math:`\mathrm{m}^2` + + +.. list-table:: Species + :header-rows: 1 + :widths: 2 2 2 3 4 6 + + * - Name + - Type + - Value + - Symbol + - Units + - Note + * - AS3 + - Bulk + - "UG" + - :math:`{\mathsf{As}^\mathrm{III}}` + - :math:`\require{upgreek}\upmu\mathrm{g~L^{-1}}` + - dissolved arsenite + * - AS5 + - Bulk + - "UG" + - :math:`{\mathsf{As}^\mathrm{V}}` + - :math:`\require{upgreek}\upmu\mathrm{g~L^{-1}}` + - dissolved arsenate + * - AStot + - Bulk + - "UG" + - :math:`{\mathsf{As}^\mathrm{tot}}` + - :math:`\require{upgreek}\upmu\mathrm{g~L^{-1}}` + - dissolved arsenic (total) + * - NH2CL + - Bulk + - "MG" + - :math:`{\mathsf{NH_2Cl}}` + - :math:`\mathrm{mg~L^{-1}}` + - dissolved monochloramine + * - AS5s + - Wall + - "UG" + - :math:`{\mathsf{As}^\mathrm{V}_{s}}` + - :math:`\require{upgreek}\upmu\mathrm{g}~\mathrm{m}^{-2}` + - adsorped arsenate (surface) + + +.. list-table:: Coefficients + :header-rows: 1 + :widths: 2 2 2 3 4 6 + + * - Name + - Type + - Value + - Symbol + - Units + - Note + * - Ka + - Const + - :math:`10` + - :math:`k_a` + - :math:`\mathrm{mg}^{-1}_{\left(\mathsf{NH_2Cl}\right)}~\mathrm{h}^{-1}` + - arsenite oxidation + * - Kb + - Const + - :math:`0.1` + - :math:`k_b` + - :math:`\mathrm{h}^{-1}` + - chloromine decay + * - K1 + - Const + - :math:`5.0` + - :math:`k_1` + - :math:`\require{upgreek}\textrm{L}~\upmu\mathrm{g}^{-1}_{\left(\mathsf{As}^\mathrm{V}\right)}~\mathrm{h}^{-1}` + - arsenate adsorption + * - K2 + - Const + - :math:`1.0` + - :math:`k_2` + - :math:`\textrm{L}~\mathrm{h}^{-1}` + - arsenate desorption + * - Smax + - Const + - :math:`50.0` + - :math:`S_{\max}` + - :math:`\require{upgreek}\upmu\mathrm{g}_{\left(\mathsf{As}^\mathrm{V}\right)}~\mathrm{m}^{-2}` + - arsenate adsorption limit + + +.. list-table:: Other terms + :header-rows: 1 + :widths: 3 3 2 3 10 + + * - Name + - Symbol + - Expression + - Units + - Note + * - Ks + - :math:`k_s` + - :math:`{k_1}/{k_2}` + - :math:`\require{upgreek}\upmu\mathrm{g}^{-1}_{\left(\mathsf{As}^\mathrm{V}\right)}` + - equilibrium adsorption coefficient + + +.. list-table:: Pipe reactions + :header-rows: 1 + :widths: 3 3 16 + + * - Species + - Type + - Expression + * - AS3 + - Rate + - :math:`-k_a \, {\mathsf{As}^\mathrm{III}} \, {\mathsf{NH_2Cl}}` + * - AS5 + - Rate + - :math:`k_a \, {\mathsf{As}^\mathrm{III}} \, {\mathsf{NH_2Cl}} -Av \left( k_1 \left(S_{\max}-{\mathsf{As}^\mathrm{V}_{s}} \right) {\mathsf{As}^\mathrm{V}} - k_2 \, {\mathsf{As}^\mathrm{V}_{s}} \right)` + * - NH2CL + - Rate + - :math:`-k_b \, {\mathsf{NH_2Cl}}` + * - AStot + - Formula + - :math:`{\mathsf{As}^\mathrm{III}} + {\mathsf{As}^\mathrm{V}}` + * - AS5s + - Equil + - :math:`k_s \, S_{\max} \frac{{\mathsf{As}^\mathrm{V}}}{1 + k_s \, {\mathsf{As}^\mathrm{V}}} - {\mathsf{As}^\mathrm{V}_{s}}` + + +.. list-table:: Tank reactions + :header-rows: 1 + :widths: 3 3 16 + + * - Species + - Type + - Expression + * - AS3 + - Rate + - :math:`-k_a \, {\mathsf{As}^\mathrm{III}} \, {\mathsf{NH_2Cl}}` + * - AS5 + - Rate + - :math:`k_a \, {\mathsf{As}^\mathrm{III}} \, {\mathsf{NH_2Cl}}` + * - NH2CL + - Rate + - :math:`-k_b \, {\mathsf{NH_2Cl}}` + * - AStot + - Formula + - :math:`{\mathsf{As}^\mathrm{III}} + {\mathsf{As}^\mathrm{V}}` + * - AS5s + - Equil + - :math:`0` (`not present in tanks`) + + +The model is created in WTNR as shown below. + +.. doctest:: + + >>> msx = wntr.msx.MsxModel() + >>> msx.name = "arsenic_chloramine" + >>> msx.title = "Arsenic Oxidation/Adsorption Example" + >>> msx.references.append(wntr.msx.library.cite_msx()) + + >>> AS3 = msx.add_species(name="AS3", species_type="BULK", units="UG", note="Dissolved arsenite") + >>> AS5 = msx.add_species(name="AS5", species_type="BULK", units="UG", note="Dissolved arsenate") + >>> AStot = msx.add_species(name="AStot", species_type="BULK", units="UG", + ... note="Total dissolved arsenic") + >>> AS5s = msx.add_species(name="AS5s", species_type="WALL", units="UG", note="Adsorbed arsenate") + >>> NH2CL = msx.add_species(name="NH2CL", species_type="BULK", units="MG", note="Monochloramine") + + >>> Ka = msx.add_constant("Ka", 10.0, units="1 / (MG * HR)", note="Arsenite oxidation rate coeff") + >>> Kb = msx.add_constant("Kb", 0.1, units="1 / HR", note="Monochloramine decay rate coeff") + >>> K1 = msx.add_constant("K1", 5.0, units="M^3 / (UG * HR)", note="Arsenate adsorption coeff") + >>> K2 = msx.add_constant("K2", 1.0, units="1 / HR", note="Arsenate desorption coeff") + >>> Smax = msx.add_constant("Smax", 50.0, units="UG / M^2", note="Arsenate adsorption limit") + + >>> Ks = msx.add_term(name="Ks", expression="K1/K2", note="Equil. adsorption coeff") + + >>> _ = msx.add_reaction(species_name="AS3", reaction_type="pipes", expression_type="rate", + ... expression="-Ka*AS3*NH2CL", note="Arsenite oxidation") + >>> _ = msx.add_reaction("AS5", "pipes", "rate", "Ka*AS3*NH2CL - Av*(K1*(Smax-AS5s)*AS5 - K2*AS5s)", + ... note="Arsenate production less adsorption") + >>> _ = msx.add_reaction( + ... species_name="NH2CL", reaction_type="pipes", expression_type="rate", expression="-Kb*NH2CL", + ... note="Monochloramine decay") + >>> _ = msx.add_reaction("AS5s", "pipe", "equil", "Ks*Smax*AS5/(1+Ks*AS5) - AS5s", + ... note="Arsenate adsorption") + >>> _ = msx.add_reaction(species_name="AStot", reaction_type="pipes", expression_type="formula", + ... expression="AS3 + AS5", note="Total arsenic") + >>> _ = msx.add_reaction(species_name="AS3", reaction_type="tank", expression_type="rate", + ... expression="-Ka*AS3*NH2CL", note="Arsenite oxidation") + >>> _ = msx.add_reaction(species_name="AS5", reaction_type="tank", expression_type="rate", + ... expression="Ka*AS3*NH2CL", note="Arsenate production") + >>> _ = msx.add_reaction(species_name="NH2CL", reaction_type="tank", expression_type="rate", + ... expression="-Kb*NH2CL", note="Monochloramine decay") + >>> _ = msx.add_reaction(species_name="AStot", reaction_type="tanks", expression_type="formula", + ... expression="AS3 + AS5", note="Total arsenic") + + >>> msx.options.area_units = "M2" + >>> msx.options.rate_units = "HR" + >>> msx.options.rtol = 0.001 + >>> msx.options.atol = 0.0001 diff --git a/documentation/conf.py b/documentation/conf.py index f9eef5dfc..d45b8e778 100644 --- a/documentation/conf.py +++ b/documentation/conf.py @@ -108,7 +108,7 @@ # If true, '()' will be appended to :func: etc. cross-reference text. #add_function_parentheses = True -autodoc_type_aliases = {'DataFrame': 'pandas DataFrame', 'MsxVariable': ':class:`~wntr.msx.model.MsxVariable`', 'NoteType': ':class:`~wntr.epanet.util.NoteType`'} +#autodoc_type_aliases = {'DataFrame': 'pandas DataFrame', 'MsxVariable': ':class:`~wntr.msx.model.MsxVariable`', 'NoteType': ':class:`~wntr.epanet.util.NoteType`'} # If true, the current module name will be prepended to all description # unit titles (such as .. function::). diff --git a/documentation/hydraulics.rst b/documentation/hydraulics.rst index 0c755bda5..f284024b7 100644 --- a/documentation/hydraulics.rst +++ b/documentation/hydraulics.rst @@ -9,10 +9,11 @@ Hydraulic simulation WNTR contains two simulators: the EpanetSimulator and the WNTRSimulator. See :ref:`software_framework` for more information on features and limitations of these simulators. +Additional hydraulic simulation options are discussed in :ref:`advanced_simulation`. EpanetSimulator ----------------- -The EpanetSimulator can be used to run EPANET 2.00.12 Programmer's Toolkit [Ross00]_ or EPANET 2.2.0 Programmer's Toolkit [RWTS20]_. +The EpanetSimulator can be used to run a hydraulic simulation using the EPANET 2.00.12 Programmer's Toolkit [Ross00]_ or EPANET 2.2.0 Programmer's Toolkit [RWTS20]_. EPANET 2.2.0 is used by default and runs demand-driven and pressure dependent hydraulic analysis. EPANET 2.00.12 runs demand-driven hydraulic analysis only. Both versions can also run water quality simulations, as described in :ref:`water_quality_simulation`. diff --git a/documentation/index.rst b/documentation/index.rst index f7d9e1c42..003bde8c1 100644 --- a/documentation/index.rst +++ b/documentation/index.rst @@ -21,6 +21,7 @@ designed to simulate and analyze resilience of water distribution networks. options hydraulics waterquality + waterquality_msx resultsobject disaster_models criticality @@ -30,7 +31,6 @@ designed to simulate and analyze resilience of water distribution networks. graphics gis advancedsim - advancedqual license whatsnew developers diff --git a/documentation/reference.rst b/documentation/reference.rst index 6d74bce38..3fadfd9d5 100644 --- a/documentation/reference.rst +++ b/documentation/reference.rst @@ -18,10 +18,14 @@ References .. [Bieni19] Bieniek, T., van Andel, B., and Bø, T.I. (2019). Bidirectional UTM-WGS84 converter for python, Retrieved on February 5, 2019 from https://github.com/Turbo87/utm. +.. [BWMS20] Burkhardt, J. B., Woo, J., Mason, J., Shang, F., Triantafyllidou, S., Schock, M.R., Lytle, D., and Murray, R. (2020). Framework for Modeling Lead in Premise Plumbing Systems Using EPANET. Journal of Water Resources Planning and Management, 146(12). https://doi.org/10.1061/(asce)wr.1943-5452.0001304 PMID:33627937. + .. [CrLo02] Crowl, D.A., and Louvar, J.F. (2011). Chemical Process Safety: Fundamentals with Applications, 3 edition. Upper Saddle River, NJ: Prentice Hall, 720p. .. [ELLT12] Eto, J.H., LaCommare, K.H., Larsen, P.H., Todd, A., and Fisher, E. (2012). An Examination of Temporal Trends in Electricity Reliability Based on Reports from U.S. Electric Utilities. Lawrence Berkeley National Laboratory Report Number LBNL-5268E. Berkeley, CA: Ernest Orlando Lawrence Berkeley National Laboratory, 68p. +.. [GSCL94] Gu, B., Schmitt, J., Chen, Z. Liang, L., and McCarthy, J.F. (1994) Adsorption and desorption of natural organic matter on iron oxide: mechanisms and models. Environmental Science and Technology, 28:38-46. + .. [JVFM21] Jordahl, K., Van den Bossche, J., Fleischmann, M, McBride, J. and others (2021) geopandas, 10.5281/zenodo.5573592. .. [Folium] python-visualization/folium. (n.d.). Retrieved on February 5, 2019 from https://github.com/python-visualization/folium. diff --git a/documentation/waterquality.rst b/documentation/waterquality.rst index fa784d531..8b8c6ee37 100644 --- a/documentation/waterquality.rst +++ b/documentation/waterquality.rst @@ -17,7 +17,12 @@ Water quality simulation ================================== Water quality simulations can only be run using the EpanetSimulator. - +This includes the ability to run +EPANET 2.00.12 Programmer's Toolkit [Ross00]_ or +EPANET 2.2.0 Programmer's Toolkit [RWTS20]_ for single species, water age, and tracer analysis. + +WNTR also includes the ability to run EPANET-MSX 2.0 [SRU23]_, see :ref:`msx_water_quality` for more information. + After defining water quality options and sources (described in the :ref:`wq_options` and :ref:`sources` sections below), a hydraulic and water quality simulation using the EpanetSimulator is run using the following code: @@ -34,7 +39,7 @@ The results include a quality value for each node (see :ref:`simulation_results` .. _wq_options: Water quality options ------------------------- +--------------------- Three types of water quality analysis are supported. These options include water age, tracer, and chemical concentration. * **Water age**: A water quality simulation can be used to compute water age at every node. @@ -83,7 +88,7 @@ More information on water network options can be found in :ref:`options`. .. _sources: Sources ------------- +------- Sources are required for CHEMICAL water quality analysis. Sources can still be defined, but *will not* be used if AGE, TRACE, or NONE water quality analysis is selected. Sources are added to the water network model using the :class:`~wntr.network.model.WaterNetworkModel.add_source` method. @@ -135,6 +140,7 @@ In the example below, the strength of the source is changed from 1000 to 1500. When creating a water network model from an EPANET INP file, the sources that are defined in the [SOURCES] section are added to the water network model. These sources are given the name 'INP#' where # is an integer representing the number of sources in the INP file. + .. The following is not shown in the UM _wq_pdd: diff --git a/documentation/waterquality_msx.rst b/documentation/waterquality_msx.rst new file mode 100644 index 000000000..d6314097c --- /dev/null +++ b/documentation/waterquality_msx.rst @@ -0,0 +1,93 @@ +.. raw:: latex + + \clearpage + +.. doctest:: + :hide: + + >>> import wntr + >>> try: + ... wn = wntr.network.model.WaterNetworkModel('../examples/networks/Net3.inp') + ... msx_filename = '../examples/data/something.msx' + ... except: + ... wn = wntr.network.model.WaterNetworkModel('examples/networks/Net3.inp') + ... msx_filename = 'examples/data/something.msx' + +.. _msx_water_quality: + +Multi-species water quality simulation +======================================= + +The EpanetSimulator can use EPANET-MSX 2.0 [SRU23]_ to run +multi-species water quality simulations. +Additional multi-species simulation options are discussed in :ref:`advanced_simulation`. + +A multi-species analysis is run if a :class:`~wntr.msx.model.MsxModel` is added to the +:class:`~wntr.network.model.WaterNetworkModel`, as shown below. +In this example, the MsxModel is created from a MSX file (see [SRU23]_ for more information on file format). + +.. doctest:: + + >>> msx_filename = 'data/something.msx') # doctest: +SKIP + >>> wn.msx = wntr.msx.MsxModel(msx_filename) + >>> sim = wntr.sim.EpanetSimulator(wn) + >>> results = sim.run_sim() +[TODO add an msx file that uses Net3 to the examples folder for documentation examples] + +The results include a quality value for each node, link, and species +(see :ref:`simulation_results` for more details). + +Multi-species model +------------------- +In addition to creating an MsxModel from a MSX file, the MsxModel +can be built from scratch and modified using WNTR. +For example, the user can +add and remove species using :class:`~wntr.msx.model.MsxModel.add_species` and :class:`~wntr.msx.model.MsxModel.remove_species`, or +add and remove reactions using :class:`~wntr.msx.model.MsxModel.add_reaction` and :class:`~wntr.msx.model.MsxModel.remove_reaction`. +See the API documentation for the :class:`~wntr.msx.model.MsxModel` for a complete list of methods. + +Variables +~~~~~~~~~ +Variables include **species**, **coefficients**, and **terms**. +These are used in **expressions** to define the dynamics of the reaction. All variables have at least two +attributes: a name and a note. +The variable name must be a valid EPANET-MSX id, which primarily +means no spaces are permitted. However, it may be useful to ensure that the name is a valid python +variable name, so that it can be used to identify the variable in your code as well. +The note can be a string, a dictionary with the keys "pre" and "post", or an :class:`~wntr.epanet.util.ENcomment` object +(which has a "pre" and "post" attribute). See the ENcomment documentation for details on the meaning; +in this example the string form of the note is used. + +There are two different types of coefficients that can be used in reaction expressions: **constants** +and **parameters**. Constants have a single value in every expression. Parameters have a global value +that is used by default, but which can be modified on a per-pipe or per-tank basis. + +Pre-defined hydraulic variable can be found in +the EPANET-MSX documentation, and are also defined in WNTR as :attr:`~wntr.msx.base.HYDRAULIC_VARIABLES`. + +Reactions +~~~~~~~~~ +All species must have two reactions defined for the model to be run successfully in EPANET-MSX by WNTR. +One is a **pipe reaction**, the other is a **tank reaction**. + +Examples that illustrate how to build MSX models in WNTR are included in :ref:`advanced_simulation`. + +Reaction library +----------------- +WNTR also contains a library of MSX models that are accessed through the :class:`~wntr.msx.library.ReactionLibrary`. +This includes the following models: + +* `Arsenic Chloramine model `_ [SRU23]_ +* `Lead Plumbosolvency model `_ [BWMS20]_ +[TODO change the 2 links to usepa, add other models if they are referenced] + +The models are stored in JSON format. +Additional models can be loaded into the library by setting a user specified path. +Additional models could also be added to the WNTR Reactions library. + +The following example loads a MsxModel from the ReactionLibrary. + +.. doctest:: + + >>> msx_model = ... +[TODO finish this example] From 6c93a6306efa4ebd0a45bc7d1dce9b4015b1a6fe Mon Sep 17 00:00:00 2001 From: Katherine Klise Date: Fri, 10 Nov 2023 12:29:20 -0800 Subject: [PATCH 45/75] API docs update, removed excess imports, removed cite_msx --- documentation/advancedqual.rst | 408 ------------------ documentation/reference.rst | 6 +- wntr/epanet/exceptions.py | 5 +- wntr/epanet/msx/__init__.py | 18 +- wntr/epanet/msx/enums.py | 143 +++--- wntr/epanet/msx/exceptions.py | 75 ++-- wntr/epanet/msx/io.py | 30 +- wntr/epanet/msx/toolkit.py | 267 ++++++------ wntr/msx/__init__.py | 8 +- .../msx/_library_data/arsenic_chloramine.json | 4 +- .../_library_data/batch_chloramine_decay.json | 2 +- wntr/msx/_library_data/lead_ppm.json | 2 +- wntr/msx/_library_data/nicotine.json | 2 +- wntr/msx/_library_data/nicotine_ri.json | 2 +- wntr/msx/base.py | 232 +++++----- wntr/msx/elements.py | 248 ++++++----- wntr/msx/library.py | 140 +++--- wntr/msx/model.py | 269 ++++++------ wntr/msx/options.py | 102 +++-- wntr/network/base.py | 5 +- wntr/tests/test_msx_elements.py | 2 +- wntr/utils/disjoint_mapping.py | 11 +- 22 files changed, 834 insertions(+), 1147 deletions(-) delete mode 100644 documentation/advancedqual.rst diff --git a/documentation/advancedqual.rst b/documentation/advancedqual.rst deleted file mode 100644 index b144cbb38..000000000 --- a/documentation/advancedqual.rst +++ /dev/null @@ -1,408 +0,0 @@ -.. raw:: latex - - \clearpage - -.. _advanced_simulation: - -Advanced water quality techniques -================================= - -This section describes several advanced simulation techniques using WNTR with MSX. - - - -.. _msx_example1_lead: - -Example 1: plumbosolvency of lead ---------------------------------- - -This model is described in [BWMS20]_, and represents plumbosolvency of lead in lead pipes -within a dwelling. -In this case, we will not assume that a water network model has been made for the dwelling, yet. - -Model creation -~~~~~~~~~~~~~~ - -We create a new model, give it a name, title, and description, and we add the reference -for the paper this model was described in. - -.. doctest:: - - >>> import wntr.msx - >>> msx = wntr.msx.MultispeciesQualityModel() - >>> msx.name = "lead_ppm" - >>> msx.title = "Lead Plumbosolvency Model (from Burkhardt et al 2020)" - >>> msx.desc = "Parameters for EPA HPS Simulator Model" - >>> msx.references.append( - ... """J. B. Burkhardt, et al. (2020) https://doi.org/10.1061/(asce)wr.1943-5452.0001304""" - ... ) - >>> msx - MultispeciesQualityModel(name='lead_ppm') - -Next, we will update certain options. - -.. doctest:: - - >>> msx.options = { - ... "report": { - ... "species": {"PB2": "YES"}, - ... "species_precision": {"PB2": 5}, - ... "nodes": "all", - ... "links": "all", - ... }, - ... "timestep": 1, - ... "area_units": "M2", - ... "rate_units": "SEC", - ... "rtol": 1e-08, - ... "atol": 1e-08, - ... } - - -Adding variables -~~~~~~~~~~~~~~~~ -The variables that are needed for a multispecies reaction system are: species, coefficients, and terms. -These are used in expressions to define the dynamics of the reaction. All variables have at least two -attributes: their name and a note. The variable name must be a valid EPANET-MSX id, which primarily -means no spaces are permitted. However, it may be useful to ensure that the name is a valid python -variable name, so that it can be used to identify the variable in your code as well. The note can be -a string, a dictionary with the keys "pre" and "post", or an :class:`~wntr.epanet.util.ENcomment` object -(which has a "pre" and "post" attribute). See the ENcomment documentation for details on the meaning; -in this example we will use the string form of the note. - --------------- - -There is only one species defined in this model, which is dissolved lead. - -======================== =============== ================================= ======================== -Name Type Units Note ------------------------- --------------- --------------------------------- ------------------------ -:math:`Pb` bulk species :math:`\mathrm{μg}_\mathrm{(Pb)}` dissolved lead -======================== =============== ================================= ======================== - -To add this species to the model, we can use the model's :meth:`~wntr.msx.multispecies.MultispeciesQualityModel.add_species` -method. -The method arguments are the name, the species_type (which can either be "bulk" or "wall"), the units, -and an optional note. -This method will add the new species to the model and also return a copy of the new species object. - -.. doctest:: - - >>> msx.add_species(name="PB2", species_type='bulk', units="ug", note="dissolved lead (Pb)") - Species(name='PB2', species_type=, units='ug', atol=None, rtol=None, note='dissolved lead (Pb)') - -The new species can be accessed by using the item's name and indexing on the model's -:attr:`~wntr.msx.multispecies.MultispeciesQualityModel.reaction_system` attribute. - - >>> PB2 = msx.reaction_system['PB2'] - >>> PB2 - Species(name='PB2', species_type=, units='ug', atol=None, rtol=None, note='dissolved lead (Pb)') - --------------- - -There are two different types of coefficients that can be used in reaction expressions: constants -and parameters. Constants have a single value in every expression. Parameters have a global value -that is used by default, but which can be modified on a per-pipe or per-tank basis. This model -has two constants and one parameter. - -=============== =============== =============== ================================= ======================== -Type Name Value Units Note ---------------- --------------- --------------- --------------------------------- ------------------------ -constant :math:`M` 0.117 :math:`\mathrm{μg~m^{-2}~s^{-1}}` desorption rate -constant :math:`E` 140.0 :math:`\mathrm{μg~L^{-1}}` saturation level -parameter :math:`F` 0 `n/a` is pipe made of lead? -=============== =============== =============== ================================= ======================== - -We can add these to the model as follows: - -.. doctest:: - - >>> msx.add_constant("M", value=0.117, note="Desorption rate (ug/m^2/s)", units="ug * m^(-2) * s^(-1)") - >>> msx.add_constant("E", value=140.0, note="saturation/plumbosolvency level (ug/L)", units="ug/L") - >>> msx.add_parameter("F", global_value=0, note="determines which pipes have reactions") - - -Adding reactions -~~~~~~~~~~~~~~~~ - -All species must have two reactions defined for the model to be run successfully in EPANET-MSX by WNTR. -One is a pipe reaction, the other is a tank reaction. In this case, we only have a reactions within -pipes, so we need to set the tank reaction to be unchanging. The system of equations is: - -.. math:: - - \frac{d}{dt}Pb_p &= F_p \, Av_p \, M \frac{\left( E - Pb_p \right)}{E}, &\quad\text{for all pipes}~p~\text{in network} \\ - \frac{d}{dt}Pb_t &= 0, & \quad\text{for all tanks}~t~\text{in network} - -Note that the pipe reaction has a variable that we have not defined, :math:`Av`, in its expression; -this variable is a pre-defined hydraulic variable. The list of these variables can be found in -the EPANET-MSX documentation, and also in the :attr:`~wntr.msx.base.HYDRAULIC_VARIABLES` -documentation. The reactions can be described in WNTR as - -================ ============== ========================================================================== -Reaction type Dynamics type Reaction expression ----------------- -------------- -------------------------------------------------------------------------- -pipe rate :math:`F \cdot Av \cdot M \cdot \left( E - Pb \right) / E` -tank rate :math:`0` -================ ============== ========================================================================== - -and then added to the reaction model using the :meth:`~wntr.msx.multispecies.MultispeciesQualityModel.add_reaction` -method. - -.. doctest:: - - >>> msx.add_reaction("PB2", "pipe", "RATE", expression="F * Av * M * (E - PB2) / E") - >>> msx.add_reaction(PB2, "tank", "rate", expression="0") - - - -Example 2: arsenic oxidation and adsorption -------------------------------------------- - -This example models monochloramine oxidation of arsenite/arsenate and wall -adsorption/desorption, as given in section 3 of the EPANET-MSX user manual [SRU23]_. -First, the model -will be restated here and then the code to create the model in wntr will be shown. - -Model Description -~~~~~~~~~~~~~~~~~ - -The system of equations for the reaction in pipes is given in Eq. (2.4) through (2.7) -in [SRU23]_. This is a simplified model, taken from [GSCL94]_. - -.. math:: - - \frac{d}{dt}{(\mathsf{As}^\mathrm{III})} &= -k_a ~ {(\mathsf{As}^\mathrm{III})} ~ {(\mathsf{NH_2Cl})} \\ - \frac{d}{dt}{(\mathsf{As}^\mathrm{V})} &= k_a ~ {(\mathsf{As}^\mathrm{III})} ~ {(\mathsf{NH_2CL})} - Av \left( k_1 \left(S_\max - {(\mathsf{As}^\mathrm{V}_s)} \right) {(\mathsf{As}^\mathrm{V})} - k_2 ~ {(\mathsf{As}^\mathrm{V}_s)} \right) \\ - \frac{d}{dt}{(\mathsf{NH_2Cl})} &= -k_b ~ {(\mathsf{NH_2Cl})} \\ - {(\mathsf{As}^\mathrm{V}_s)} &= \frac{k_s ~ S_\max ~ {(\mathsf{As}^\mathrm{V})}}{1 + k_s {(\mathsf{As}^\mathrm{V})}} - - -where the various species, coefficients, and expressions are described in the tables below. - - -.. list-table:: Options - :header-rows: 1 - :widths: 3 3 10 - - * - Option - - Code - - Description - * - Rate units - - "HR" - - :math:`\mathrm{h}^{-1}` - * - Area units - - "M2" - - :math:`\mathrm{m}^2` - - -.. list-table:: Species - :header-rows: 1 - :widths: 2 2 2 3 4 6 - - * - Name - - Type - - Value - - Symbol - - Units - - Note - * - AS3 - - Bulk - - "UG" - - :math:`{\mathsf{As}^\mathrm{III}}` - - :math:`\require{upgreek}\upmu\mathrm{g~L^{-1}}` - - dissolved arsenite - * - AS5 - - Bulk - - "UG" - - :math:`{\mathsf{As}^\mathrm{V}}` - - :math:`\require{upgreek}\upmu\mathrm{g~L^{-1}}` - - dissolved arsenate - * - AStot - - Bulk - - "UG" - - :math:`{\mathsf{As}^\mathrm{tot}}` - - :math:`\require{upgreek}\upmu\mathrm{g~L^{-1}}` - - dissolved arsenic (total) - * - NH2CL - - Bulk - - "MG" - - :math:`{\mathsf{NH_2Cl}}` - - :math:`\mathrm{mg~L^{-1}}` - - dissolved monochloramine - * - AS5s - - Wall - - "UG" - - :math:`{\mathsf{As}^\mathrm{V}_{s}}` - - :math:`\require{upgreek}\upmu\mathrm{g}~\mathrm{m}^{-2}` - - adsorped arsenate (surface) - - -.. list-table:: Coefficients - :header-rows: 1 - :widths: 2 2 2 3 4 6 - - * - Name - - Type - - Value - - Symbol - - Units - - Note - * - Ka - - Const - - :math:`10` - - :math:`k_a` - - :math:`\mathrm{mg}^{-1}_{\left(\mathsf{NH_2Cl}\right)}~\mathrm{h}^{-1}` - - arsenite oxidation - * - Kb - - Const - - :math:`0.1` - - :math:`k_b` - - :math:`\mathrm{h}^{-1}` - - chloromine decay - * - K1 - - Const - - :math:`5.0` - - :math:`k_1` - - :math:`\require{upgreek}\textrm{L}~\upmu\mathrm{g}^{-1}_{\left(\mathsf{As}^\mathrm{V}\right)}~\mathrm{h}^{-1}` - - arsenate adsorption - * - K2 - - Const - - :math:`1.0` - - :math:`k_2` - - :math:`\textrm{L}~\mathrm{h}^{-1}` - - arsenate desorption - * - Smax - - Const - - :math:`50.0` - - :math:`S_{\max}` - - :math:`\require{upgreek}\upmu\mathrm{g}_{\left(\mathsf{As}^\mathrm{V}\right)}~\mathrm{m}^{-2}` - - arsenate adsorption limit - - -.. list-table:: Other terms - :header-rows: 1 - :widths: 3 3 2 3 10 - - * - Name - - Symbol - - Expression - - Units - - Note - * - Ks - - :math:`k_s` - - :math:`{k_1}/{k_2}` - - :math:`\require{upgreek}\upmu\mathrm{g}^{-1}_{\left(\mathsf{As}^\mathrm{V}\right)}` - - equilibrium adsorption coefficient - - -.. list-table:: Pipe reactions - :header-rows: 1 - :widths: 3 3 16 - - * - Species - - Type - - Expression - * - AS3 - - Rate - - :math:`-k_a \, {\mathsf{As}^\mathrm{III}} \, {\mathsf{NH_2Cl}}` - * - AS5 - - Rate - - :math:`k_a \, {\mathsf{As}^\mathrm{III}} \, {\mathsf{NH_2Cl}} -Av \left( k_1 \left(S_{\max}-{\mathsf{As}^\mathrm{V}_{s}} \right) {\mathsf{As}^\mathrm{V}} - k_2 \, {\mathsf{As}^\mathrm{V}_{s}} \right)` - * - NH2CL - - Rate - - :math:`-k_b \, {\mathsf{NH_2Cl}}` - * - AStot - - Formula - - :math:`{\mathsf{As}^\mathrm{III}} + {\mathsf{As}^\mathrm{V}}` - * - AS5s - - Equil - - :math:`k_s \, S_{\max} \frac{{\mathsf{As}^\mathrm{V}}}{1 + k_s \, {\mathsf{As}^\mathrm{V}}} - {\mathsf{As}^\mathrm{V}_{s}}` - - -.. list-table:: Tank reactions - :header-rows: 1 - :widths: 3 3 16 - - * - Species - - Type - - Expression - * - AS3 - - Rate - - :math:`-k_a \, {\mathsf{As}^\mathrm{III}} \, {\mathsf{NH_2Cl}}` - * - AS5 - - Rate - - :math:`k_a \, {\mathsf{As}^\mathrm{III}} \, {\mathsf{NH_2Cl}}` - * - NH2CL - - Rate - - :math:`-k_b \, {\mathsf{NH_2Cl}}` - * - AStot - - Formula - - :math:`{\mathsf{As}^\mathrm{III}} + {\mathsf{As}^\mathrm{V}}` - * - AS5s - - Equil - - :math:`0` (`not present in tanks`) - - -Creation in WNTR -~~~~~~~~~~~~~~~~ - -.. doctest:: - - >>> msx = wntr.msx.MultispeciesQualityModel() - >>> msx.name = "arsenic_chloramine" - >>> msx.title = "Arsenic Oxidation/Adsorption Example" - >>> msx.references.append(wntr.msx.library.cite_msx()) - >>> AS3 = msx.add_species(name="AS3", species_type="BULK", units="UG", note="Dissolved arsenite") - >>> AS5 = msx.add_species(name="AS5", species_type="BULK", units="UG", note="Dissolved arsenate") - >>> AStot = msx.add_species(name="AStot", species_type="BULK", units="UG", note="Total dissolved arsenic") - >>> AS5s = msx.add_species(name="AS5s", species_type="WALL", units="UG", note="Adsorbed arsenate") - >>> NH2CL = msx.add_species(name="NH2CL", species_type="BULK", units="MG", note="Monochloramine") - >>> Ka = msx.add_constant("Ka", 10.0, units="1 / (MG * HR)", note="Arsenite oxidation rate coefficient") - >>> Kb = msx.add_constant("Kb", 0.1, units="1 / HR", note="Monochloramine decay rate coefficient") - >>> K1 = msx.add_constant("K1", 5.0, units="M^3 / (UG * HR)", note="Arsenate adsorption coefficient") - >>> K2 = msx.add_constant("K2", 1.0, units="1 / HR", note="Arsenate desorption coefficient") - >>> Smax = msx.add_constant("Smax", 50.0, units="UG / M^2", note="Arsenate adsorption limit") - >>> Ks = msx.add_term(name="Ks", expression="K1/K2", note="Equil. adsorption coeff.") - >>> _ = msx.add_reaction( - ... species_name="AS3", reaction_type="pipes", expression_type="rate", expression="-Ka*AS3*NH2CL", note="Arsenite oxidation" - ... ) - >>> _ = msx.add_reaction( - ... "AS5", "pipes", "rate", "Ka*AS3*NH2CL - Av*(K1*(Smax-AS5s)*AS5 - K2*AS5s)", note="Arsenate production less adsorption" - ... ) - >>> _ = msx.add_reaction( - ... species_name="NH2CL", reaction_type="pipes", expression_type="rate", expression="-Kb*NH2CL", note="Monochloramine decay" - ... ) - >>> _ = msx.add_reaction("AS5s", "pipe", "equil", "Ks*Smax*AS5/(1+Ks*AS5) - AS5s", note="Arsenate adsorption") - >>> _ = msx.add_reaction( - ... species_name="AStot", reaction_type="pipes", expression_type="formula", expression="AS3 + AS5", note="Total arsenic" - ... ) - >>> _ = msx.add_reaction( - ... species_name="AS3", reaction_type="tank", expression_type="rate", expression="-Ka*AS3*NH2CL", note="Arsenite oxidation" - ... ) - >>> _ = msx.add_reaction( - ... species_name="AS5", reaction_type="tank", expression_type="rate", expression="Ka*AS3*NH2CL", note="Arsenate production" - ... ) - >>> _ = msx.add_reaction( - ... species_name="NH2CL", reaction_type="tank", expression_type="rate", expression="-Kb*NH2CL", note="Monochloramine decay" - ... ) - >>> _ = msx.add_reaction( - ... species_name="AStot", reaction_type="tanks", expression_type="formula", expression="AS3 + AS5", note="Total arsenic" - ... ) - >>> msx.options.area_units = "M2" - >>> msx.options.rate_units = "HR" - >>> msx.options.rtol = 0.001 - >>> msx.options.atol = 0.0001 - - -References ----------- - -.. [BWMS20] - J. B. Burkhardt, et al. (2020) - "Framework for Modeling Lead in Premise Plumbing Systems Using EPANET". - `Journal of Water Resources Planning and Management`. - **146** (12). https://doi.org/10.1061/(asce)wr.1943-5452.0001304. PMID:33627937. - -.. [GSCL94] - B. Gu, J. Schmitt, Z. Chen, L. Liang, and J.F. McCarthy. "Adsorption and desorption of - natural organic matter on iron oxide: mechanisms and models". Environ. Sci. Technol., 28:38-46, January 1994. diff --git a/documentation/reference.rst b/documentation/reference.rst index 3fadfd9d5..bd638f8cf 100644 --- a/documentation/reference.rst +++ b/documentation/reference.rst @@ -10,7 +10,7 @@ References Due to limitations with cross referenced citations in reStructuredText (e.g., commas and spaces are not supported), citations are cross referenced using a 6 digit notation [*]_. -.. [ALA01] American Lifelines Alliance. (2001). Seismic Fragility Formulations for Water Systems, Part 1 and 2. Report for the American Lifelines Alliance, ASCE (Ed.) Reston, VA: American Society of Civil Engineers. April 2001. +.. [ALA01] American Lifelines Alliance. (2001). Seismic Fragility Formulations for Water Systems, Part 1 and 2. Report for the American Lifelines Alliance, ASCE (Ed.) Reston, VA: American Society of Civil Engineers. April 2001. .. [AwGB90] Awumah, K., Goulter, I., and Bhatt, S.K. (1990). Assessment of reliability in water distribution networks using entropy based measures. Stochastic Hydrology and Hydraulics, 4(4), 309-320. @@ -38,7 +38,7 @@ References .. [ICC12] International Code Council. (2011). 2012 International Fire Code, Appendix B - Fire-Flow Requirements for Buildings. Country Club Hills, IL: International Code Council, ISBN: 978-1-60983-046-5. -.. [JaSr08] Jayaram, N. and Srinivasan, K. (2008). Performance-based optimal design and rehabilitation of water distribution networks using life cycle costing. Water resources research, 44(1). +.. [JaSr08] Jayaram, N. and Srinivasan, K. (2008). Performance-based optimal design and rehabilitation of water distribution networks using life cycle costing. Water Resources Research, 44(1). .. [JCMG11] Joyner, D., Certik, O., Meurer, A., and Granger, B.E. (2012). Open source computer algebra systems, SymPy. ACM Communications in Computer Algebra, 45(4), 225-234. @@ -62,7 +62,7 @@ References .. [SPHC16] Sievert, C., Parmer, C., Hocking, T., Chamberlain, S., Ram, K., Corvellec, M., and Despouy, P. (2016). plotly: Create interactive web graphics via Plotly’s JavaScript graphing library [Software]. -.. [SRU23] Shang, F., Rossman, L. A., Uber, J.G. (2023). EPANET-MSX 2.0 User Manual. U.S. Environmental Protection Agency, Cincinnati, OH. EPA/600/R-22/199. +.. [SRU23] Shang, F., Rossman, L. A., and Uber, J.G. (2023). EPANET-MSX 2.0 User Manual. U.S. Environmental Protection Agency, Cincinnati, OH. EPA/600/R-22/199. .. [Todi00] Todini, E. (2000). Looped water distribution networks design using a resilience index based heuristic approach. Urban Water, 2(2), 115-122. diff --git a/wntr/epanet/exceptions.py b/wntr/epanet/exceptions.py index 82ce50f61..fdf405dd5 100644 --- a/wntr/epanet/exceptions.py +++ b/wntr/epanet/exceptions.py @@ -1,5 +1,8 @@ # coding: utf-8 -"""Exceptions for EPANET toolkit and IO operations.""" +""" +The wntr.epanet.expections module contains Exceptions for EPANET toolkit +and IO operations. +""" from typing import List diff --git a/wntr/epanet/msx/__init__.py b/wntr/epanet/msx/__init__.py index b7ae5c121..5fbc99912 100644 --- a/wntr/epanet/msx/__init__.py +++ b/wntr/epanet/msx/__init__.py @@ -1,15 +1,19 @@ -"""The wntr.epanet.msx package provides EPANET-MSX compatibility functions for WNTR. +# coding: utf-8 +""" +The wntr.epanet.msx package provides EPANET-MSX compatibility functions for +WNTR. -The following environment variable must be set, or the command `set_msx_path` must -be run prior to trying to instantiate the EPANET-MSX toolkit. +The following environment variable must be set, or the command `set_msx_path` +must be run prior to trying to instantiate the EPANET-MSX toolkit. .. envvar:: WNTR_PATH_TO_EPANETMSX - The full path to the directory where EPANET-MSX has been installed. Specifically, - the directory should contain both toolkit files, epanet2.dll and epanetmsx.dll - (or the appropriate equivalent files for your system architecture). - + The full path to the directory where EPANET-MSX has been installed. + Specifically, the directory should contain both toolkit files, epanet2.dll + and epanetmsx.dll (or the appropriate equivalent files for your system + architecture). """ + import os as _os def set_msx_path(path): diff --git a/wntr/epanet/msx/enums.py b/wntr/epanet/msx/enums.py index e2a77fead..73d7134fc 100644 --- a/wntr/epanet/msx/enums.py +++ b/wntr/epanet/msx/enums.py @@ -1,18 +1,22 @@ -"""EPANET-MSX enum types, for use in toolkit API calls.""" +# coding: utf-8 +""" +The wntr.epanet.msx.enums module contains EPANET-MSX enum types, for use in +toolkit API calls. +""" from enum import IntEnum from wntr.utils.enumtools import add_get @add_get(prefix='MSX_') class TkObjectType(IntEnum): - """The enumeration for object type used in EPANET-MSX. - + """Enumeration for object type used in EPANET-MSX. + .. warning:: These enum values start with 0. .. rubric:: Enum Members - The following enum names are defined, and, if using the :meth:`get` method, then - they are case insensitive and can be optionally prefixed with "MSX\_". + The following enum names are defined, and, if using the :meth:`get` method, + then they are case insensitive and can be optionally prefixed with "MSX\_". .. autosummary:: NODE @@ -48,14 +52,14 @@ class TkObjectType(IntEnum): @add_get(prefix='MSX_') class TkSourceType(IntEnum): - """The enumeration for source type used in EPANET-MSX. - + """Enumeration for source type used in EPANET-MSX. + .. warning:: These enum values start with -1. .. rubric:: Enum Members - The following enum names are defined, and, if using the :meth:`get` method, then - they are case insensitive and can be optionally prefixed with "MSX\_". + The following enum names are defined, and, if using the :meth:`get` method, + then they are case insensitive and can be optionally prefixed with "MSX\_". .. autosummary:: NOSOURCE @@ -78,14 +82,14 @@ class TkSourceType(IntEnum): @add_get(prefix='MSX_') class TkUnitSystem(IntEnum): - """The enumeration for the units system used in EPANET-MSX. - + """Enumeration for the units system used in EPANET-MSX. + .. warning:: These enum values start with 0. .. rubric:: Enum Members - The following enum names are defined, and, if using the :meth:`get` method, then - they are case insensitive and can be optionally prefixed with "MSX\_". + The following enum names are defined, and, if using the :meth:`get` method, + then they are case insensitive and can be optionally prefixed with "MSX\_". .. autosummary:: US @@ -99,14 +103,15 @@ class TkUnitSystem(IntEnum): @add_get(prefix='MSX_') class TkFlowUnits(IntEnum): - """The enumeration for the flow units used in EPANET-MSX (determined from EPANET INP file read in with the toolkit). - + """Enumeration for the flow units used in EPANET-MSX (determined from + EPANET INP file read in with the toolkit). + .. warning:: These enum values start with 0. .. rubric:: Enum Members - The following enum names are defined, and, if using the :meth:`get` method, then - they are case insensitive and can be optionally prefixed with "MSX\_". + The following enum names are defined, and, if using the :meth:`get` method, + then they are case insensitive and can be optionally prefixed with "MSX\_". .. autosummary:: CFS @@ -144,14 +149,14 @@ class TkFlowUnits(IntEnum): @add_get(prefix='MSX_') class TkMixType(IntEnum): - """The enumeration for the mixing model used in EPANET-MSX. - + """Enumeration for the mixing model used in EPANET-MSX. + .. warning:: These enum values start with 0. .. rubric:: Enum Members - The following enum names are defined, and, if using the :meth:`get` method, then - they are case insensitive and can be optionally prefixed with "MSX\_". + The following enum names are defined, and, if using the :meth:`get` method, + then they are case insensitive and can be optionally prefixed with "MSX\_". .. autosummary:: MIX1 @@ -171,14 +176,14 @@ class TkMixType(IntEnum): @add_get(prefix='MSX_') class TkSpeciesType(IntEnum): - """The enumeration for species type used in EPANET-MSX. + """Enumeration for species type used in EPANET-MSX. .. warning:: These enum values start with 0. .. rubric:: Enum Members - The following enum names are defined, and, if using the :meth:`get` method, then - they are case insensitive and can be optionally prefixed with "MSX\_". + The following enum names are defined, and, if using the :meth:`get` method, + then they are case insensitive and can be optionally prefixed with "MSX\_". .. autosummary:: BULK @@ -192,14 +197,14 @@ class TkSpeciesType(IntEnum): @add_get(prefix='MSX_') class TkExpressionType(IntEnum): - """The enumeration for the expression type used in EPANET-MSX. - + """Enumeration for the expression type used in EPANET-MSX. + .. warning:: These enum values start with 0. .. rubric:: Enum Members - The following enum names are defined, and, if using the :meth:`get` method, then - they are case insensitive and can be optionally prefixed with "MSX\_". + The following enum names are defined, and, if using the :meth:`get` method, + then they are case insensitive and can be optionally prefixed with "MSX\_". .. autosummary:: NO_EXPR @@ -219,14 +224,14 @@ class TkExpressionType(IntEnum): @add_get(prefix='MSX_') class TkSolverType(IntEnum): - """The enumeration for the solver type used in EPANET-MSX. - + """Enumeration for the solver type used in EPANET-MSX. + .. warning:: These enum values start with 0. .. rubric:: Enum Members - The following enum names are defined, and, if using the :meth:`get` method, then - they are case insensitive and can be optionally prefixed with "MSX\_". + The following enum names are defined, and, if using the :meth:`get` method, + then they are case insensitive and can be optionally prefixed with "MSX\_". .. autosummary:: EUL @@ -243,14 +248,14 @@ class TkSolverType(IntEnum): @add_get(prefix='MSX_') class TkCouplingType(IntEnum): - """The enumeration for the coupling type option used in EPANET-MSX. - + """Enumeration for the coupling type option used in EPANET-MSX. + .. warning:: These enum values start with 0. .. rubric:: Enum Members - The following enum names are defined, and, if using the :meth:`get` method, then - they are case insensitive and can be optionally prefixed with "MSX\_". + The following enum names are defined, and, if using the :meth:`get` method, + then they are case insensitive and can be optionally prefixed with "MSX\_". .. autosummary:: NO_COUPLING @@ -264,14 +269,14 @@ class TkCouplingType(IntEnum): @add_get(prefix='MSX_') class TkMassUnits(IntEnum): - """The enumeration for mass units used in EPANET-MSX. + """Enumeration for mass units used in EPANET-MSX. .. warning:: These enum values start with 0. .. rubric:: Enum Members - The following enum names are defined, and, if using the :meth:`get` method, then - they are case insensitive and can be optionally prefixed with "MSX\_". + The following enum names are defined, and, if using the :meth:`get` method, + then they are case insensitive and can be optionally prefixed with "MSX\_". .. autosummary:: MG @@ -291,14 +296,14 @@ class TkMassUnits(IntEnum): @add_get(prefix='MSX_') class TkAreaUnits(IntEnum): - """The enumeration for area units used in EPANET-MSX. - + """Enumeration for area units used in EPANET-MSX. + .. warning:: These enum values start with 0. .. rubric:: Enum Members - The following enum names are defined, and, if using the :meth:`get` method, then - they are case insensitive and can be optionally prefixed with "MSX\_". + The following enum names are defined, and, if using the :meth:`get` method, + then they are case insensitive and can be optionally prefixed with "MSX\_". .. autosummary:: FT2 @@ -315,14 +320,14 @@ class TkAreaUnits(IntEnum): @add_get(prefix='MSX_') class TkRateUnits(IntEnum): - """The enumeration for rate units used in EPANET-MSX. - + """Enumeration for rate units used in EPANET-MSX. + .. warning:: These enum values start with 0. .. rubric:: Enum Members - The following enum names are defined, and, if using the :meth:`get` method, then - they are case insensitive and can be optionally prefixed with "MSX\_". + The following enum names are defined, and, if using the :meth:`get` method, + then they are case insensitive and can be optionally prefixed with "MSX\_". .. autosummary:: SECONDS @@ -342,14 +347,14 @@ class TkRateUnits(IntEnum): @add_get(prefix='MSX_') class TkUnits(IntEnum): - """The position for units used in EPANET-MSX. - + """Position for units used in EPANET-MSX. + .. warning:: These enum values start with 0. .. rubric:: Enum Members - The following enum names are defined, and, if using the :meth:`get` method, then - they are case insensitive and can be optionally prefixed with "MSX\_". + The following enum names are defined, and, if using the :meth:`get` method, + then they are case insensitive and can be optionally prefixed with "MSX\_". .. autosummary:: LENGTH_UNITS @@ -379,14 +384,14 @@ class TkUnits(IntEnum): @add_get(prefix='MSX_') class TkHydVar(IntEnum): - """The enumeration for hydraulic variable used in EPANET-MSX. + """Enumeration for hydraulic variable used in EPANET-MSX. .. warning:: These enum values start with 0. .. rubric:: Enum Members - The following enum names are defined, and, if using the :meth:`get` method, then - they are case insensitive and can be optionally prefixed with "MSX\_". + The following enum names are defined, and, if using the :meth:`get` method, + then they are case insensitive and can be optionally prefixed with "MSX\_". .. autosummary:: DIAMETER @@ -422,14 +427,14 @@ class TkHydVar(IntEnum): @add_get(prefix='MSX_') class TkTstat(IntEnum): - """The enumeration used for time statistic in EPANET-MSX. - + """Enumeration used for time statistic in EPANET-MSX. + .. warning:: These enum values start with 0. .. rubric:: Enum Members - The following enum names are defined, and, if using the :meth:`get` method, then - they are case insensitive and can be optionally prefixed with "MSX\_". + The following enum names are defined, and, if using the :meth:`get` method, + then they are case insensitive and can be optionally prefixed with "MSX\_". .. autosummary:: SERIES @@ -452,14 +457,14 @@ class TkTstat(IntEnum): @add_get(prefix='MSX_') class TkOption(IntEnum): - """The enumeration used for choosing an option in EPANET-MSX toolkit. + """Enumeration used for choosing an option in EPANET-MSX toolkit. .. warning:: These enum values start with 0. .. rubric:: Enum Members - The following enum names are defined, and, if using the :meth:`get` method, then - they are case insensitive and can be optionally prefixed with "MSX\_". + The following enum names are defined, and, if using the :meth:`get` method, + then they are case insensitive and can be optionally prefixed with "MSX\_". .. autosummary:: AREA_UNITS_OPTION @@ -497,14 +502,14 @@ class TkOption(IntEnum): @add_get(prefix='MSX_') class TkCompiler(IntEnum): - """The enumeration used for specifying compiler options in EPANET-MSX. - + """Enumeration used for specifying compiler options in EPANET-MSX. + .. warning:: These enum values start with 0. .. rubric:: Enum Members - The following enum names are defined, and, if using the :meth:`get` method, then - they are case insensitive and can be optionally prefixed with "MSX\_". + The following enum names are defined, and, if using the :meth:`get` method, + then they are case insensitive and can be optionally prefixed with "MSX\_". .. autosummary:: NO_COMPILER @@ -521,14 +526,14 @@ class TkCompiler(IntEnum): @add_get(prefix='MSX_') class TkFileMode(IntEnum): - """The enumeration for file model used in EPANET-MSX. - + """Enumeration for file model used in EPANET-MSX. + .. warning:: These enum values start with 0. .. rubric:: Enum Members - The following enum names are defined, and, if using the :meth:`get` method, then - they are case insensitive and can be optionally prefixed with "MSX\_". + The following enum names are defined, and, if using the :meth:`get` method, + then they are case insensitive and can be optionally prefixed with "MSX\_". .. autosummary:: SCRATCH_FILE diff --git a/wntr/epanet/msx/exceptions.py b/wntr/epanet/msx/exceptions.py index 2ed33e506..a1dcc6ee4 100644 --- a/wntr/epanet/msx/exceptions.py +++ b/wntr/epanet/msx/exceptions.py @@ -1,12 +1,12 @@ # coding: utf-8 -"""EPANET-MSX error and exception classes.""" +""" +The wntr.epanet.msx.exceptions module contains Exceptions for EPANET-MSX +IO operations. +""" -from enum import IntEnum from typing import List -from wntr.utils.enumtools import add_get - -from ..exceptions import EN_ERROR_CODES, EpanetException +from ..exceptions import EpanetException MSX_ERROR_CODES = { # MSX syntax errors @@ -52,21 +52,25 @@ :meta hide-value: """ + class EpanetMsxException(EpanetException): - def __init__(self, code: int, *args: List[object], line_num=None, line=None) -> None: - """An Exception class for EPANET-MSX Toolkit and IO exceptions. + def __init__(self, code: int, *args: List[object], line_num=None, + line=None) -> None: + """Exception class for EPANET-MSX Toolkit and IO exceptions Parameters ---------- code : int or str or MSXErrors - The EPANET-MSX error code (int) or a string mapping to the MSXErrors enum members + EPANET-MSX error code (int) or a string mapping to the MSXErrors + enum members args : additional non-keyword arguments, optional - If there is a string-format within the error code's text, these will be used to - replace the format, otherwise they will be output at the end of the Exception message. + If there is a string-format within the error code's text, these + will be used to replace the format, otherwise they will be output + at the end of the Exception message. line_num : int, optional - The line number, if reading an INP file, by default None + Line number, if reading an INP file, by default None line : str, optional - The contents of the line, by default None + Contents of the line, by default None """ if not code or int(code) < 400: return super().__init__(code, *args, line_num=line_num, line=line) @@ -87,61 +91,68 @@ def __init__(self, code: int, *args: List[object], line_num=None, line=None) -> class MSXSyntaxError(EpanetMsxException, SyntaxError): def __init__(self, code, *args, line_num=None, line=None) -> None: - """An MSX-specific error that is due to a syntax error in an msx-file. + """MSX-specific error that is due to a syntax error in an msx-file. Parameters ---------- code : int or str or MSXErrors - The EPANET-MSX error code (int) or a string mapping to the MSXErrors enum members + EPANET-MSX error code (int) or a string mapping to the MSXErrors + enum members args : additional non-keyword arguments, optional - If there is a string-format within the error code's text, these will be used to - replace the format, otherwise they will be output at the end of the Exception message. + If there is a string-format within the error code's text, these + will be used to replace the format, otherwise they will be output + at the end of the Exception message. line_num : int, optional - The line number, if reading an INP file, by default None + Line number, if reading an INP file, by default None line : str, optional - The contents of the line, by default None + Contents of the line, by default None """ super().__init__(code, *args, line_num=line_num, line=line) class MSXKeyError(EpanetMsxException, KeyError): def __init__(self, code, name, *args, line_num=None, line=None) -> None: - """An MSX-specific error that is due to a missing or unacceptably named variable/speces/etc. + """MSX-specific error that is due to a missing or unacceptably named + variable/speces/etc. Parameters ---------- code : int or str or MSXErrors - The EPANET-MSX error code (int) or a string mapping to the MSXErrors enum members + EPANET-MSX error code (int) or a string mapping to the MSXErrors + enum members name : str - The key/name/id that is missing + Key/name/id that is missing args : additional non-keyword arguments, optional - If there is a string-format within the error code's text, these will be used to - replace the format, otherwise they will be output at the end of the Exception message. + If there is a string-format within the error code's text, these + will be used to replace the format, otherwise they will be output + at the end of the Exception message. line_num : int, optional - The line number, if reading an INP file, by default None + Line number, if reading an INP file, by default None line : str, optional - The contents of the line, by default None + Contents of the line, by default None """ super().__init__(code, name, *args, line_num=line_num, line=line) class MSXValueError(EpanetMsxException, ValueError): def __init__(self, code, value, *args, line_num=None, line=None) -> None: - """An MSX-specific error that is related to an invalid value. + """MSX-specific error that is related to an invalid value. Parameters ---------- code : int or str or MSXErrors - The EPANET-MSX error code (int) or a string mapping to the MSXErrors enum members + EPANET-MSX error code (int) or a string mapping to the MSXErrors + enum members value : Any - The value that is invalid + Value that is invalid args : additional non-keyword arguments, optional - If there is a string-format within the error code's text, these will be used to - replace the format, otherwise they will be output at the end of the Exception message. + If there is a string-format within the error code's text, these + will be used to replace the format, otherwise they will be output + at the end of the Exception message. line_num : int, optional - The line number, if reading an INP file, by default None + Line number, if reading an INP file, by default None line : str, optional - The contents of the line, by default None + Contents of the line, by default None """ super().__init__(code, value, *args, line_num=line_num, line=line) diff --git a/wntr/epanet/msx/io.py b/wntr/epanet/msx/io.py index e1a87ae31..fc271d30e 100644 --- a/wntr/epanet/msx/io.py +++ b/wntr/epanet/msx/io.py @@ -1,5 +1,8 @@ # coding: utf-8 -"""I/O functions for EPANET-MSX toolkit compatibility""" +""" +The wntr.epanet.msx io module contains methods for reading/writing EPANET +MSX input and output files. +""" import datetime import logging @@ -13,8 +16,7 @@ import wntr.network from wntr.epanet.msx.exceptions import EpanetMsxException, MSXValueError from wntr.epanet.util import ENcomment -from wntr.network.elements import Source -from wntr.msx.base import ReactionType, VariableType, SpeciesType +from wntr.msx.base import VariableType, SpeciesType from wntr.msx.model import MsxModel sys_default_enc = sys.getdefaultencoding() @@ -79,20 +81,22 @@ def __init__(self): @classmethod def read(cls, msx_filename: str, rxn_model: MsxModel = None): """ - Read an EPANET-MSX input file (.msx) and load data into a water quality - reactions model. Only MSX 2.0 files are recognized. + Read an EPANET-MSX input file (.msx) and load data into a MsxModel. + Only MSX 2.0 files are recognized. Parameters ---------- msx_file : str - the filename of the .msx file to read in - rxn_model : WaterQualityReactionsModel, optional - the model to put data into, by default None (new model) + Filename of the .msx file to read in + rxn_model : MsxModel, optional + Multi-species water quality model to put data into, + by default None (new model) Returns ------- - WaterQualityReactionsModel - the model with the new species, reactions and other options added + MsxModel + Multi-species water quality model with the new species, reactions + and other options added """ if rxn_model is None: rxn_model = MsxModel() @@ -180,9 +184,9 @@ def write(cls, filename: str, msx: MsxModel): Parameters ---------- filename : str - the filename to write - rxn : MultispeciesQualityModel - the multispecies reaction model + Filename to write + rxn : MsxModel + Multi-species water quality model """ obj = cls() obj.rxn = msx diff --git a/wntr/epanet/msx/toolkit.py b/wntr/epanet/msx/toolkit.py index 20aea7cd8..e7ffdd78e 100644 --- a/wntr/epanet/msx/toolkit.py +++ b/wntr/epanet/msx/toolkit.py @@ -1,18 +1,18 @@ +# coding: utf-8 """ -The wntr.reaction.toolkit module is a Python extension for the EPANET MSX +The wntr.epanet.msx.toolkit module is a Python extension for the EPANET-MSX Programmers Toolkit DLLs. .. note:: - Code in this section based on code from "EPANET-MSX-Python-wrapper", - licensed under the BSD license. See LICENSE.txt for details. + Code in this section is based on code from "EPANET-MSX-Python-wrapper", + licensed under the BSD license. See LICENSE.md for details. """ import ctypes import os import os.path import platform import sys -from ctypes import byref from typing import Union from pkg_resources import resource_filename @@ -20,7 +20,6 @@ from wntr.epanet.msx.enums import TkObjectType, TkSourceType from ..toolkit import ENepanet -from ..util import SizeLimits from .exceptions import MSX_ERROR_CODES, EpanetMsxException, MSXKeyError, MSXValueError epanet_toolkit = "wntr.epanet.toolkit" @@ -119,14 +118,14 @@ def _error(self, *args): raise EpanetMsxException(self.errcode) return - # ----------running the simulation----------------------------------------------------- + # ----------running the simulation----------------------------------------- def MSXopen(self, msxfile): """Opens the MSX Toolkit to analyze a particular distribution system. Parameters ---------- msxfile : str - name of the MSX input file + Name of the MSX input file """ if msxfile is not None: msxfile = ctypes.c_char_p(msxfile.encode()) @@ -141,7 +140,8 @@ def MSXclose(self): raise EpanetMsxException(ierr) def MSXusehydfile(self, filename): - """Uses the contents of the specified file as the current binary hydraulics file + """Uses the contents of the specified file as the current binary + hydraulics file Parameters ---------- @@ -160,22 +160,25 @@ def MSXsolveH(self): raise EpanetMsxException(ierr) def MSXinit(self, saveFlag=0): - """Initializes the MSX system before solving for water quality results in step-wise fashion - set saveFlag to 1 if water quality results should be saved to a scratch binary file, or to 0 is not saved to file""" + """Initializes the MSX system before solving for water quality results + in step-wise fashion set saveFlag to 1 if water quality results should + be saved to a scratch binary file, or to 0 is not saved to file""" saveFlag = int(saveFlag) ierr = self.ENlib.MSXinit(saveFlag) if ierr != 0: raise EpanetMsxException(ierr) def MSXsolveQ(self): - """solves for water quality over the entire simulation period and saves the results to an internal scratch file""" + """Solves for water quality over the entire simulation period and saves + the results to an internal scratch file""" ierr = self.ENlib.MSXsolveQ() if ierr != 0: raise EpanetMsxException(ierr) def MSXstep(self): """Advances the water quality simulation one water quality time step. - The time remaining in the overall simulation is returned as tleft, the current time as t.""" + The time remaining in the overall simulation is returned as tleft, the + current time as t.""" t = ctypes.c_long() tleft = ctypes.c_long() ierr = self.ENlib.MSXstep(ctypes.byref(t), ctypes.byref(tleft)) @@ -185,8 +188,9 @@ def MSXstep(self): return out def MSXsaveoutfile(self, filename): - """saves water quality results computed for each node, link and reporting time period to a named binary file - + """Saves water quality results computed for each node, link and + reporting time period to a named binary file + Parameters ---------- filename : str @@ -197,45 +201,47 @@ def MSXsaveoutfile(self, filename): raise EpanetMsxException(ierr) def MSXsavemsxfile(self, filename): - """saves the data associated with the current MSX project into a new MSX input file - + """Saves the data associated with the current MSX project into a new + MSX input file + Parameters ---------- filename : str - the name of the MSX input file to create + Name of the MSX input file to create """ ierr = self.ENlib.MSXsavemsxfile(ctypes.c_char_p(filename.encode())) if ierr != 0: raise EpanetMsxException(ierr, filename) def MSXreport(self): - """Writes water quality simulations results as instructed by the MSX input file to a text file""" + """Writes water quality simulations results as instructed by the MSX + input file to a text file""" ierr = self.ENlib.MSXreport() if ierr != 0: raise EpanetMsxException(ierr) - # ---------get parameters--------------------------------------------------------------- + # ---------get parameters-------------------------------------------------- def MSXgetindex(self, _type: Union[int, TkObjectType], name): - """Retrieves the internal index of an MSX object given its name. + """Gets the internal index of an MSX object given its name. Parameters ---------- _type : int, str or ObjectType - The type of object to get an index for + Type of object to get an index for name : str - The name of the object to get an index for + Name of the object to get an index for Returns ------- int - The internal index + Internal index Raises ------ MSXKeyError - if an invalid str is passed for _type + If an invalid str is passed for _type MSXValueError - if _type is not a valid MSX object type + If _type is not a valid MSX object type """ try: _type = TkObjectType.get(_type) @@ -249,19 +255,20 @@ def MSXgetindex(self, _type: Union[int, TkObjectType], name): return ind.value def MSXgetIDlen(self, _type, index): - """Retrieves the number of characters in the ID name of an MSX object given its internal index number. + """Get the number of characters in the ID name of an MSX object + given its internal index number. Parameters ---------- _type : int, str or ObjectType - The type of object to get an index for - index : int - The index of the object to get the ID length for + Type of object to get an index for + index : int + Index of the object to get the ID length for Returns ------- int - the length of the object ID + Length of the object ID """ try: _type = TkObjectType.get(_type) @@ -275,19 +282,19 @@ def MSXgetIDlen(self, _type, index): return len.value def MSXgetID(self, _type, index): - """Retrieves the ID name of an object given its internal index number + """Get the ID name of an object given its internal index number Parameters ---------- _type : int, str or ObjectType - The type of object to get an index for - index : int - The index of the object to get the ID for + Type of object to get an index for + index : int + Index of the object to get the ID for Returns ------- str - the object ID + Object ID """ try: _type = TkObjectType.get(_type) @@ -303,31 +310,31 @@ def MSXgetID(self, _type, index): return id.value.decode() def MSXgetinitqual(self, _type, node_link_index, species_index): - """Retrieves the initial concentration of a particular chemical species assigned to a specific node - or link of the pipe network + """Get the initial concentration of a particular chemical species + assigned to a specific node or link of the pipe network Parameters ---------- _type : str, int or ObjectType - the type of object + Type of object node_link_index : int - the object index + Object index species_index : int - the species index + Species index Returns ------- float - the initial quality value for that node or link + Initial quality value for that node or link Raises ------ MSXKeyError - the type passed in for ``_type`` is not valid + Type passed in for ``_type`` is not valid MSXValueError - the value for ``_type`` is not valid + Value for ``_type`` is not valid EpanetMsxException - any other error from the C-API + Any other error from the C-API """ try: _type = TkObjectType.get(_type) @@ -343,30 +350,31 @@ def MSXgetinitqual(self, _type, node_link_index, species_index): return iniqual.value def MSXgetqual(self, _type, node_link_index, species_index): - """Retrieves a chemical species concentration at a given node or the average concentration along a link at the current simulation time step + """Get a chemical species concentration at a given node or the + average concentration along a link at the current simulation time step Parameters ---------- _type : str, int or ObjectType - the type of object + Type of object node_link_index : int - the object index + Object index species_index : int - the species index + Species index Returns ------- float - the current quality value for that node or link + Current quality value for that node or link Raises ------ MSXKeyError - the type passed in for ``_type`` is not valid + Type passed in for ``_type`` is not valid MSXValueError - the value for ``_type`` is not valid + Value for ``_type`` is not valid EpanetMsxException - any other error from the C-API + Any other error from the C-API """ try: _type = TkObjectType.get(_type) @@ -382,22 +390,22 @@ def MSXgetqual(self, _type, node_link_index, species_index): return qual.value def MSXgetconstant(self, constant_index): - """Retrieves the value of a particular reaction constant + """Get the value of a particular reaction constant Parameters ---------- constant_index : int - index to the constant + Index to the constant Returns ------- float - the value of the constant + Value of the constant Raises ------ EpanetMsxException - a toolkit error occurred + Toolkit error occurred """ const = ctypes.c_double() ierr = self.ENlib.MSXgetconstant(constant_index, ctypes.byref(const)) @@ -406,30 +414,31 @@ def MSXgetconstant(self, constant_index): return const.value def MSXgetparameter(self, _type, node_link_index, param_index): - """Retrieves the value of a particular reaction parameter for a given TANK or PIPE. + """Get the value of a particular reaction parameter for a given + TANK or PIPE. Parameters ---------- _type : int or str or Enum - get the type of the parameter + Get the type of the parameter node_link_index : int - the link index + Link index param_index : int - the parameter variable index + Parameter variable index Returns ------- float - the parameter value + Parameter value Raises ------ MSXKeyError - if there is no such _type + If there is no such _type MSXValueError - if the _type is improper + If the _type is improper EpanetMsxException - any other error + Any other error """ try: _type = TkObjectType.get(_type) @@ -445,10 +454,24 @@ def MSXgetparameter(self, _type, node_link_index, param_index): return param.value def MSXgetsource(self, node_index, species_index): - """Retrieves information on any external source of a particular chemical species assigned to a specific node of the pipe network + """Get information on any external source of a particular + chemical species assigned to a specific node of the pipe network + + Parameters + ---------- + node_index : int + Node index + species_index : int + Species index + + Returns + ------- + list + [source type, level, and pattern] where level is the baseline + concentration (or mass flow rate) of the source and pattern the + index of the time pattern used to add variability to the source's + baseline level (0 if no pattern defined for the source) """ - #level is returned with the baseline concentration (or mass flow rate) of the source - #pat is returned with the index of the time pattern used to add variability to the source's baseline level (0 if no pattern defined for the source)""" level = ctypes.c_double() _type = ctypes.c_int() pat = ctypes.c_int() @@ -459,17 +482,17 @@ def MSXgetsource(self, node_index, species_index): return src_out def MSXgetpatternlen(self, pat): - """Retrieves the number of time periods within a SOURCE time pattern. + """Get the number of time periods within a SOURCE time pattern. Parameters ---------- pat : int - pattern index + Pattern index Returns ------- int - number of time periods in the pattern + Number of time periods in the pattern """ len = ctypes.c_int() ierr = self.ENlib.MSXgetpatternlen(pat, ctypes.byref(len)) @@ -478,19 +501,19 @@ def MSXgetpatternlen(self, pat): return len.value def MSXgetpatternvalue(self, pat, period): - """Retrieves the multiplier at a specific time period for a given SOURCE time pattern + """Get the multiplier at a specific time period for a given + SOURCE time pattern Parameters ---------- pat : int - pattern index + Pattern index period : int 1-indexed period of the pattern to retrieve Returns ------- - float - the multiplier + Multiplier """ val = ctypes.c_double() ierr = self.ENlib.MSXgetpatternvalue(pat, period, ctypes.byref(val)) @@ -499,22 +522,22 @@ def MSXgetpatternvalue(self, pat, period): return val.value def MSXgetcount(self, _type): - """Retrieves the number of objects of a specified type. + """Get the number of objects of a specified type. Parameters ---------- _type : int or str or Enum - the type of object to count + Type of object to count Returns ------- int - the number of objects of specified type + Number of objects of specified type Raises ------ MSXKeyError - if the _type is invalid + If the _type is invalid """ try: _type = TkObjectType.get(_type) @@ -528,18 +551,19 @@ def MSXgetcount(self, _type): return count.value def MSXgetspecies(self, species_index): - """Retrieves the attributes of a chemical species given its internal index number. - species is the sequence number of the species (starting from 1 as listed in the MSX input file + """Get the attributes of a chemical species given its internal + index number. Parameters ---------- species_index : int - the species to query + Species index to query (starting from 1 as listed in the MSX input + file) Returns ------- int, str, float, float - the type, units, aTol, and rTol for the species + Type, units, aTol, and rTol for the species """ type_ind = ctypes.c_int() units = ctypes.create_string_buffer(15) @@ -552,25 +576,25 @@ def MSXgetspecies(self, species_index): return spe_out def MSXgeterror(self, errcode, len=100): - """returns the text for an error message given its error code + """Get the text for an error message given its error code Parameters ---------- errcode : int - the error code + Error code len : int, optional - the length of the error message, by default 100 and minimum 80 + Length of the error message, by default 100 and minimum 80 Returns ------- str - returns a string decoded from the DLL + String decoded from the DLL Warning ------- - Getting string parameters in this way is not recommended, because it requires - setting up string arrays that may or may not be the correct size. Use the - wntr.epanet.msx.enums package to get error information. + Getting string parameters in this way is not recommended, because it + requires setting up string arrays that may or may not be the correct + size. Use the wntr.epanet.msx.enums package to get error information. """ errmsg = ctypes.create_string_buffer(len) self.ENlib.MSXgeterror(errcode, ctypes.byref(errmsg), len) @@ -579,39 +603,40 @@ def MSXgeterror(self, errcode, len=100): # --------------set parameters----------------------------------- def MSXsetconstant(self, ind, value): - """assigns a new value to a specific reaction constant + """Set a new value to a specific reaction constant Parameters ---------- ind : int - the index to the variable + Index to the variable value : float - the value to give the constant + Value to give the constant """ ierr = self.ENlib.MSXsetconstant(ctypes.c_int(ind), ctypes.c_double(value)) if ierr != 0: raise EpanetMsxException(ierr) def MSXsetparameter(self, _type, ind, param, value): - """assigns a value to a particular reaction parameter for a given TANK or PIPE + """Set a value to a particular reaction parameter for a given TANK + or PIPE Parameters ---------- _type : int or str or enum - the type of value to set + Type of value to set ind : int - the tank or pipe index + Tank or pipe index param : int - the parameter variable index + Parameter variable index value : float - the value to be set + Value to be set Raises ------ MSXKeyError - if there is no such _type + If there is no such _type MSXValueError - if the _type is invalid + If the _type is invalid """ try: _type = TkObjectType.get(_type) @@ -625,19 +650,19 @@ def MSXsetparameter(self, _type, ind, param, value): raise EpanetMsxException(ierr) def MSXsetinitqual(self, _type, ind, spe, value): - """Retrieves the initial concentration of a particular chemical species assigned to a specific node - or link of the pipe network. + """Set the initial concentration of a particular chemical species + assigned to a specific node or link of the pipe network. Parameters ---------- _type : int or str or enum - what type of network element is being set + Type of network element to set ind : int - the index of the network element + Index of the network element spe : int - the index of the species + Index of the species value : float - the initial quality value + Initial quality value """ try: _type = TkObjectType.get(_type) @@ -651,20 +676,21 @@ def MSXsetinitqual(self, _type, ind, spe, value): raise EpanetMsxException(ierr) def MSXsetsource(self, node, spe, _type, level, pat): - """sets the attributes of an external source of a particular chemical species in a specific node of the pipe network + """Set the attributes of an external source of a particular chemical + species in a specific node of the pipe network Parameters ---------- node : int - the node index + Node index spe : int - the species index + Species index _type : int or str or enum - the type of source + Type of source level : float - the source quality value + Source quality value pat : int - the pattern index + Pattern index """ try: _type = TkSourceType.get(_type) @@ -676,14 +702,14 @@ def MSXsetsource(self, node, spe, _type, level, pat): raise EpanetMsxException(ierr) def MSXsetpattern(self, pat, mult): - """assigns a new set of multipliers to a given MSX SOURCE time pattern + """Set multipliers to a given MSX SOURCE time pattern Parameters ---------- pat : int - the pattern index + Pattern index mult : list-like - the pattern multipliers + Pattern multipliers """ length = len(mult) cfactors_type = ctypes.c_double * length @@ -695,28 +721,29 @@ def MSXsetpattern(self, pat, mult): raise EpanetMsxException(ierr) def MSXsetpatternvalue(self, pat, period, value): - """Sets the multiplier factor for a specific period within a SOURCE time pattern. + """Set the multiplier factor for a specific period within a SOURCE time + pattern. Parameters ---------- pat : int - the pattern index + Pattern index period : int - the 1-indexed pattern time period index + 1-indexed pattern time period index value : float - the value to set at that time period + Value to set at that time period """ ierr = self.ENlib.MSXsetpatternvalue(ctypes.c_int(pat), ctypes.c_int(period), ctypes.c_double(value)) if ierr != 0: raise EpanetMsxException(ierr) def MSXaddpattern(self, patternid): - """Adds a new, empty MSX source time pattern to an MSX project. + """Add a new, empty MSX source time pattern to an MSX project. Parameters ---------- patternid : str - the name of the new pattern + Name of the new pattern """ ierr = self.ENlib.MSXaddpattern(ctypes.c_char_p(patternid.encode())) if ierr != 0: diff --git a/wntr/msx/__init__.py b/wntr/msx/__init__.py index e44b248fe..d563c9a97 100644 --- a/wntr/msx/__init__.py +++ b/wntr/msx/__init__.py @@ -1,11 +1,13 @@ -# -*- coding: utf-8 -*- -"""Contains definitions for EPANET Multispecies Extension (MSX) water quality modeling. +# coding: utf-8 +""" +The wntr.msx package contains methods to define EPANET Multi-species Extension +(MSX) water quality models. """ from .base import VariableType, SpeciesType, ReactionType, ExpressionType from .elements import Species, Constant, Parameter, Term, Reaction, HydraulicVariable, MathFunction from .model import MsxModel from .options import MsxSolverOptions -from .library import ReactionLibrary, cite_msx +from .library import ReactionLibrary from . import base, elements, library, model, options diff --git a/wntr/msx/_library_data/arsenic_chloramine.json b/wntr/msx/_library_data/arsenic_chloramine.json index c67e1dc13..8661afaa3 100644 --- a/wntr/msx/_library_data/arsenic_chloramine.json +++ b/wntr/msx/_library_data/arsenic_chloramine.json @@ -1,10 +1,10 @@ { - "wntr-version": "1.0.0", + "wntr-version": "", "name": "arsenic_chloramine", "title": "Arsenic Oxidation/Adsorption Example", "description": "This example models monochloramine oxidation of arsenite/arsenate and wall adsoption/desorption, as given in section 3 of the EPANET-MSX user manual", "references": [ - "Shang, F. and Rossman, L.A. and Uber, J.G. (2023) \"EPANET-MSX 2.0 User Manual\". (Cincinnati, OH: Water Infrastructure Division (CESER), U.S. Environmental Protection Agency). EPA/600/R-22/199." + "Shang, F., Rossman, L. A., and Uber, J.G. (2023). EPANET-MSX 2.0 User Manual. U.S. Environmental Protection Agency, Cincinnati, OH. EPA/600/R-22/199." ], "reaction_system": { "species": [ diff --git a/wntr/msx/_library_data/batch_chloramine_decay.json b/wntr/msx/_library_data/batch_chloramine_decay.json index fc4c416db..6563c38e0 100644 --- a/wntr/msx/_library_data/batch_chloramine_decay.json +++ b/wntr/msx/_library_data/batch_chloramine_decay.json @@ -1,5 +1,5 @@ { - "wntr-version": "1.0.0", + "wntr-version": "", "name": "batch_chloramine_decay", "title": "Batch chloramine decay example", "description": null, diff --git a/wntr/msx/_library_data/lead_ppm.json b/wntr/msx/_library_data/lead_ppm.json index 63a69e852..7d483200b 100644 --- a/wntr/msx/_library_data/lead_ppm.json +++ b/wntr/msx/_library_data/lead_ppm.json @@ -1,5 +1,5 @@ { - "wntr-version": "1.0.0", + "wntr-version": "", "name": "lead_ppm", "title": "Lead Plumbosolvency Model (from Burkhardt et al 2020)", "description": "Parameters for EPA HPS Simulator Model", diff --git a/wntr/msx/_library_data/nicotine.json b/wntr/msx/_library_data/nicotine.json index 7603d684d..999f7b888 100644 --- a/wntr/msx/_library_data/nicotine.json +++ b/wntr/msx/_library_data/nicotine.json @@ -1,5 +1,5 @@ { - "wntr-version": "1.0.0", + "wntr-version": "", "name": "nicotine", "title": "Nicotine - Chlorine reaction", "description": null, diff --git a/wntr/msx/_library_data/nicotine_ri.json b/wntr/msx/_library_data/nicotine_ri.json index f73267661..6554f0469 100644 --- a/wntr/msx/_library_data/nicotine_ri.json +++ b/wntr/msx/_library_data/nicotine_ri.json @@ -1,5 +1,5 @@ { - "wntr-version": "1.0.0", + "wntr-version": "", "name": "nicotine_ri", "title": "Nicotine - Chlorine reaction with reactive intermediate", "description": null, diff --git a/wntr/msx/base.py b/wntr/msx/base.py index e795616c7..6bc035ddc 100644 --- a/wntr/msx/base.py +++ b/wntr/msx/base.py @@ -1,7 +1,9 @@ -# -*- coding: utf-8 -*- +# coding: utf-8 +""" +The wntr.msx.base module includes base classes for the multi-species water +quality model -"""The base classes for the the WNTR quality extensions module. -Other than the enum classes, the classes in this module are all abstract +Other than the enum classes, the classes in this module are all abstract and/or mixin classes, and should not be instantiated directly. """ @@ -9,8 +11,8 @@ import os from abc import ABC, abstractclassmethod, abstractmethod, abstractproperty from enum import Enum -from typing import Any, Dict, Iterator, List, Union, Generator -from wntr.epanet.util import ENcomment, NoteType +from typing import Any, Dict, Iterator, Generator +from wntr.epanet.util import NoteType from wntr.utils.disjoint_mapping import DisjointMapping from wntr.utils.enumtools import add_get @@ -59,11 +61,11 @@ def coth(x): {"name": "Av", "note": "Surface area per unit volume (area units/L) "}, {"name": "Len", "note": "Pipe length (feet or meters)"}, ] -"""The hydraulic variables defined in EPANET-MSX. +"""Hydraulic variables defined in EPANET-MSX. For reference, the valid values are provided in :numref:`table-msx-hyd-vars`. .. _table-msx-hyd-vars: -.. table:: Valid hydraulic variables in multispecies quality model expressions. +.. table:: Valid hydraulic variables in multi-species quality model expressions. ============== ================================================ **Name** **Description** @@ -149,7 +151,7 @@ def coth(x): + tuple([k.upper() for k in EXPR_FUNCTIONS.keys()]) + tuple([k.capitalize() for k in EXPR_FUNCTIONS.keys()]) ) -"""The WNTR reserved names. This includes the MSX hydraulic variables +"""WNTR reserved names. This includes the MSX hydraulic variables (see :numref:`table-msx-hyd-vars`) and the MSX defined functions (see :numref:`table-msx-funcs`). @@ -167,7 +169,7 @@ def coth(x): @add_get(abbrev=True) class VariableType(Enum): - """The type of reaction variable. + """Type of reaction variable. The following types are defined, and aliases of just the first character are also defined. @@ -190,15 +192,15 @@ class VariableType(Enum): """ SPECIES = 3 - """A chemical or biological water quality species""" + """Chemical or biological water quality species""" TERM = 4 - """A functional term, or named expression, for use in reaction expressions""" + """Functional term, or named expression, for use in reaction expressions""" PARAMETER = 5 - """A reaction expression coefficient that is parameterized by tank or pipe""" + """Reaction expression coefficient that is parameterized by tank or pipe""" CONSTANT = 6 - """A constant coefficient for use in reaction expressions""" + """Constant coefficient for use in reaction expressions""" RESERVED = 9 - """A variable that is either a hydraulic variable or other reserved word""" + """Variable that is either a hydraulic variable or other reserved word""" S = SPEC = SPECIES T = TERM @@ -209,7 +211,7 @@ class VariableType(Enum): @add_get(abbrev=True) class SpeciesType(Enum): - """The enumeration for species type. + """Enumeration for species type .. warning:: These enum values are not the same as the MSX SpeciesType. @@ -228,9 +230,9 @@ class SpeciesType(Enum): """ BULK = 1 - """bulk species""" + """Bulk species""" WALL = 2 - """wall species""" + """Wall species""" B = BULK W = WALL @@ -238,7 +240,7 @@ class SpeciesType(Enum): @add_get(abbrev=True) class ReactionType(Enum): - """What type of network component does this reaction occur in + """Reaction type which specifies the location where the reaction occurs The following types are defined, and aliases of just the first character are also defined. @@ -256,9 +258,9 @@ class ReactionType(Enum): """ PIPE = 1 - """The expression describes a reaction in pipes""" + """Expression describes a reaction in pipes""" TANK = 2 - """The expression describes a reaction in tanks""" + """Expression describes a reaction in tanks""" P = PIPE T = TANK @@ -266,7 +268,7 @@ class ReactionType(Enum): @add_get(abbrev=True) class ExpressionType(Enum): - """The type of reaction expression. + """Type of reaction expression The following types are defined, and aliases of just the first character are also defined. @@ -287,12 +289,14 @@ class ExpressionType(Enum): """ EQUIL = 1 - """used for equilibrium expressions where it is assumed that the expression supplied is being equated to zero""" + """Equilibrium expressions where equation is being equated to zero""" RATE = 2 - """used to supply the equation that expresses the rate of change of the given species with respect to time as a function - of the other species in the model""" + """Rate expression where the equation expresses the rate of change of + the given species with respect to time as a function of the other species + in the model""" FORMULA = 3 - """used when the concentration of the named species is a simple function of the remaining species""" + """Formula expression where the concentration of the named species is a + simple function of the remaining species""" E = EQUIL R = RATE @@ -300,27 +304,27 @@ class ExpressionType(Enum): class ReactionBase(ABC): - """A water quality reaction class. + """Water quality reaction class This is an abstract class for water quality reactions with partial concrete - attribute and method definitions. All parameters - and methods documented here must be defined by a subclass except for the following: + attribute and method definitions. All parameters and methods documented + here must be defined by a subclass except for the following: - .. rubric:: Concrete attribtues + .. rubric:: Concrete attributes - The :meth:`__init__` method defines the following attributes concretely. Thus, - a subclass should call :code:`super().__init__(species_name, note=note)` at the beginning of its own - initialization. + The :meth:`__init__` method defines the following attributes concretely. + Thus, a subclass should call :code:`super().__init__(species_name, note=note)` + at the beginning of its own initialization. .. autosummary:: ~ReactionBase._species_name ~ReactionBase.note - .. rubric:: Concrete properies + .. rubric:: Concrete properties - The species name is protected, and a reaction cannot be manually assigned a new species. - Therefore, the following property is defined concretely. + The species name is protected, and a reaction cannot be manually assigned + a new species. Therefore, the following property is defined concretely. .. autosummary:: @@ -338,14 +342,15 @@ class ReactionBase(ABC): """ def __init__(self, species_name: str, *, note: NoteType = None) -> None: - """A water quality reaction definition. + """Water quality reaction definition This abstract class must be subclassed. Parameters ---------- species_name : str - The name of the chemical or biological species being modeled using this reaction. + Name of the chemical or biological species being modeled using this + reaction note : (str | dict | ENcomment), optional keyword Supplementary information regarding this reaction, by default None (see-also :class:`~wntr.epanet.util.NoteType`) @@ -353,52 +358,54 @@ def __init__(self, species_name: str, *, note: NoteType = None) -> None: Raises ------ TypeError - if expression_type is invalid + If expression_type is invalid """ if species_name is None: raise TypeError("The species_name cannot be None") self._species_name: str = str(species_name) - """The protected name of the species""" + """Protected name of the species""" self.note: NoteType = note - """An optional note regarding the reaction (see :class:`~wntr.epanet.util.NoteType`) + """Optional note regarding the reaction (see :class:`~wntr.epanet.util.NoteType`) """ @property def species_name(self) -> str: - """The name of the species that has a reaction being defined.""" + """Name of the species that has a reaction being defined.""" return self._species_name @abstractproperty def reaction_type(self) -> Enum: - """The reaction type (reaction location).""" + """Reaction type (reaction location).""" raise NotImplementedError def __str__(self) -> str: - """Return the name of the species and the reaction type, indicated by an arrow. E.g., 'HOCL->PIPE for chlorine reaction in pipes.""" + """Return the name of the species and the reaction type, indicated by + an arrow. E.g., 'HOCL->PIPE for chlorine reaction in pipes.""" return "{}->{}".format(self.species_name, self.reaction_type.name) def __repr__(self) -> str: - """Return a representation of the reaction from the dictionary representation - see :meth:`to_dict`""" + """Return a representation of the reaction from the dictionary + representation - see :meth:`to_dict`""" return "{}(".format(self.__class__.__name__) + ", ".join(["{}={}".format(k, repr(getattr(self, k))) for k, v in self.to_dict().items()]) + ")" @abstractmethod def to_dict(self) -> dict: - """Represent the object as a dictionary.""" + """Represent the object as a dictionary""" raise NotImplementedError class VariableBase(ABC): - """A multi-species water quality model variable. + """Multi-species water quality model variable - This is an abstract class for water quality model variables with partial definition - of concrete attributes and methods. Parameters - and methods documented here must be defined by a subclass except for the following: + This is an abstract class for water quality model variables with partial + definition of concrete attributes and methods. Parameters and methods + documented here must be defined by a subclass except for the following: - .. rubric:: Concrete attribtues + .. rubric:: Concrete attributes - The :meth:`__init__` method defines the following attributes concretely. Thus, - a subclass should call :code:`super().__init__()` at the beginning of its own - initialization. + The :meth:`__init__` method defines the following attributes concretely. + Thus, a subclass should call :code:`super().__init__()` at the beginning + of its own initialization. .. autosummary:: @@ -417,12 +424,12 @@ class VariableBase(ABC): """ def __init__(self, name: str, *, note: NoteType = None) -> None: - """Multi-species variable constructor arguments. + """Multi-species variable constructor arguments Parameters ---------- name : str - The name/symbol for the variable. Must be a valid MSX variable name. + Name/symbol for the variable. Must be a valid MSX variable name note : (str | dict | ENcomment), optional keyword Supplementary information regarding this variable, by default None (see-also :class:`~wntr.epanet.util.NoteType`) @@ -430,21 +437,21 @@ def __init__(self, name: str, *, note: NoteType = None) -> None: Raises ------ KeyExistsError - the name is already taken + Name is already taken ValueError - the name is a reserved word + Name is a reserved word """ if name in RESERVED_NAMES: raise ValueError("Name cannot be a reserved name") self.name: str = name - """The name/ID of this variable, must be a valid EPANET/MSX ID""" + """Name/ID of this variable, must be a valid EPANET/MSX ID""" self.note: NoteType = note - """An optional note regarding the variable (see :class:`~wntr.epanet.util.NoteType`) + """Optional note regarding the variable (see :class:`~wntr.epanet.util.NoteType`) """ @abstractproperty def var_type(self) -> Enum: - """The type of reaction variable""" + """Type of reaction variable""" raise NotImplementedError @abstractmethod @@ -457,24 +464,27 @@ def __str__(self) -> str: return self.name def __repr__(self) -> str: - """Return a representation of the variable from the dictionary representation - see :meth:`to_dict`""" + """Return a representation of the variable from the dictionary + representation - see :meth:`to_dict`""" return "{}(".format(self.__class__.__name__) + ", ".join(["{}={}".format(k, repr(getattr(self, k))) for k, v in self.to_dict().items()]) + ")" class ReactionSystemBase(ABC): - """Abstract class for reaction systems, which contains variables and reaction expressions. + """Abstract class for reaction systems, which contains variables and + reaction expressions. This class contains the functions necessary to perform dictionary-style addressing of *variables* by their name. It does not allow dictionary-style addressing of reactions. - This is an abstract class with some concrete attributes and methods. Parameters - and methods documented here must be defined by a subclass except for the following: + This is an abstract class with some concrete attributes and methods. + Parameters and methods documented here must be defined by a subclass + except for the following: .. rubric:: Concrete attributes - The :meth:`__init__` method defines the following attributes concretely. Thus, - a subclass should call :code:`super().__init__()` or :code:`super().__init__(filename)`. + The :meth:`__init__` method defines the following attributes concretely. + Thus, a subclass should call :code:`super().__init__()` or :code:`super().__init__(filename)`. .. autosummary:: @@ -483,8 +493,8 @@ class ReactionSystemBase(ABC): .. rubric:: Concrete methods - The following special methods are concretely provided to directly access items - in the :attr:`_vars` attribute. + The following special methods are concretely provided to directly access + items in the :attr:`_vars` attribute. .. autosummary:: :nosignatures: @@ -498,11 +508,12 @@ class ReactionSystemBase(ABC): """ def __init__(self) -> None: - """The constructor for the reaction system.""" + """Constructor for the reaction system.""" self._vars: DisjointMapping = DisjointMapping() - """The variables registry, which is mapped to dictionary functions on the reaction system object""" + """Variables registry, which is mapped to dictionary functions on the + reaction system object""" self._rxns: Dict[str, Any] = dict() - """The reactions dictionary""" + """Reactions dictionary""" @abstractmethod def add_variable(self, obj: VariableBase) -> None: @@ -516,12 +527,12 @@ def add_reaction(self, obj: ReactionBase) -> None: @abstractmethod def variables(self) -> Generator[Any, Any, Any]: - """A generator looping through all variables""" + """Generator looping through all variables""" raise NotImplementedError @abstractmethod def reactions(self) -> Generator[Any, Any, Any]: - """A generator looping through all reactions""" + """Generator looping through all reactions""" raise NotImplementedError @abstractmethod @@ -549,11 +560,11 @@ def __len__(self) -> int: class VariableValuesBase(ABC): - """Abstract class for a variable's network-specific values. + """Abstract class for a variable's network-specific values This class should contain values for different pipes, tanks, etc., that correspond to a specific network for the reaction - system. It can be used for intial concentration values, or + system. It can be used for initial concentration values, or for initial settings on parameters, but should be information that is clearly tied to a specific type of variable. @@ -563,23 +574,17 @@ class VariableValuesBase(ABC): @abstractproperty def var_type(self) -> Enum: - """The type of variable this object holds data for.""" + """Type of variable this object holds data for.""" raise NotImplementedError @abstractmethod def to_dict(self) -> dict: - """Represent a specific variable's network-specific values as a dictionary. - - Returns - ------- - dict - the network-specific values for a specific variable - """ + """Represent the object as a dictionary""" raise NotImplementedError class NetworkDataBase(ABC): - """Abstract class containing network specific data. + """Abstract class containing network specific data This class should be populated with things like initial quality, sources, parameterized values, etc. @@ -590,26 +595,21 @@ class NetworkDataBase(ABC): @abstractmethod def to_dict(self) -> dict: - """Represent the quality-relevant network-specific data as a dictionary. - - Returns - ------- - dict - the quality-relevant network data - """ + """Represent the object as a dictionary""" raise NotImplementedError class QualityModelBase(ABC): - """Abstract water quality model. + """Abstract multi-species water quality model - This is an abstract class for a water quality model. All parameters - and methods documented here must be defined by a subclass except for the following: + This is an abstract class for a water quality model. All parameters and + methods documented here must be defined by a subclass except for the + following: .. rubric:: Concrete attributes - The :meth:`__init__` method defines the following attributes concretely. Thus, - a subclass should call :code:`super().__init__()` or :code:`super().__init__(filename)`. + The :meth:`__init__` method defines the following attributes concretely. + Thus, a subclass should call :code:`super().__init__()` or :code:`super().__init__(filename)`. .. autosummary:: @@ -624,34 +624,34 @@ class QualityModelBase(ABC): """ def __init__(self, filename=None): - """Abstract water quality model. + """Abstract water quality model Parameters ---------- filename : str, optional - the file to use to populate the initial data + File to use to populate the initial data """ self.name: str = None if filename is None else os.path.splitext(os.path.split(filename)[1])[0] - """A name for the model, or the MSX model filename (no spaces allowed)""" + """Name for the model, or the MSX model filename (no spaces allowed)""" self.title: str = None - """The title line from the MSX file, must be a single line""" + """Title line from the MSX file, must be a single line""" self.description: str = None - """A longer description; note that multi-line descriptions may not be + """Longer description; note that multi-line descriptions may not be represented well in dictionary form""" self._orig_file: str = filename - """The protected original filename, if provided in the constructor""" + """Protected original filename, if provided in the constructor""" self._options = None - """The protected options data object""" + """Protected options data object""" self._rxn_system: ReactionSystemBase = None - """The protected reaction system object""" + """Protected reaction system object""" self._net_data: NetworkDataBase = None - """The protected network data object""" + """Protected network data object""" self._wn = None - """The protected water network object""" + """Protected water network object""" @abstractproperty def options(self): - """The model options structure. + """Model options structure Concrete classes should implement this with the appropriate typing and also implement a setter method. @@ -660,7 +660,7 @@ def options(self): @abstractproperty def reaction_system(self) -> ReactionSystemBase: - """The reaction variables defined for this model. + """Reaction variables defined for this model Concrete classes should implement this with the appropriate typing. """ @@ -668,7 +668,7 @@ def reaction_system(self) -> ReactionSystemBase: @abstractproperty def network_data(self) -> NetworkDataBase: - """The network-specific values added to this model. + """Network-specific values added to this model Concrete classes should implement this with the appropriate typing. """ @@ -676,27 +676,21 @@ def network_data(self) -> NetworkDataBase: @abstractmethod def to_dict(self) -> dict: - """Represent the model as a dictionary. - - Returns - ------- - dict - A dictionary representation of a water quality model - """ + """Represent the object as a dictionary""" raise NotImplementedError @abstractclassmethod def from_dict(self, data: dict) -> "QualityModelBase": - """Create a new model from a dictionary. + """Create a new model from a dictionary Parameters ---------- data : dict - A dictionary representation of a water quality model + Dictionary representation of the model Returns ------- QualityModelBase - the new concrete water quality model + New concrete model """ raise NotImplementedError diff --git a/wntr/msx/elements.py b/wntr/msx/elements.py index 82fa4236f..3499a59ef 100644 --- a/wntr/msx/elements.py +++ b/wntr/msx/elements.py @@ -1,11 +1,14 @@ -# -*- coding: utf-8 -*- - -"""Concrete implementations of MSX classes. +# coding: utf-8 +""" +The wntr.msx.elements module includes concrete implementations of the +multi-species water quality model elements, including species, constants, +parameters, terms, and reactions. """ + from __future__ import annotations import logging -from typing import Any, Dict, Literal, Tuple, Union +from typing import Any, Dict, Tuple, Union from wntr.epanet.util import ENcomment, NoteType from wntr.utils.disjoint_mapping import KeyExistsError @@ -25,7 +28,7 @@ class Species(VariableBase): - """A biological or chemical species that impacts water quality. + """Biological or chemical species """ def __init__( @@ -41,44 +44,46 @@ def __init__( _vars: ReactionSystemBase = None, _vals: VariableValuesBase = None, ) -> None: - """A biological or chemical species. + """Biological or chemical species Parameters ---------- name - The species name + Species name species_type - The species type + Species type units - The units of mass for this species, see :attr:`units` property. + Units of mass for this species, see :attr:`units` property. atol : float | None - The absolute tolerance when solving this species' equations, by default None + Absolute tolerance when solving this species' equations, by default + None rtol : float | None - The relative tolerance when solving this species' equations, by default None + Relative tolerance when solving this species' equations, by default + None note Supplementary information regarding this variable, by default None (see :class:`~wntr.epanet.util.NoteType`) diffusivity Diffusivity of the species in water, by default None _vars - the reaction system this species is a part of, by default None + Reaction system this species is a part of, by default None _vals - the initial quality values for this species, by default None + Initial quality values for this species, by default None Raises ------ KeyExistsError - if the name has already been used + If the name has already been used TypeError - if `atol` and `rtol` are not the same type + If `atol` and `rtol` are not the same type ValueError - if `atol` or `rtol` ≤ 0 + If `atol` or `rtol` ≤ 0 Notes ----- - EPANET-MSX requires that `atol` and `rtol` either both be omitted, or both be provided. - In order to enforce this, the arguments passed for `atol` and `rtol` must both be None - or both be positive values. + EPANET-MSX requires that `atol` and `rtol` either both be omitted, or + both be provided. In order to enforce this, the arguments passed for + `atol` and `rtol` must both be None or both be positive values. """ super().__init__(name, note=note) if _vars is not None and not isinstance(_vars, ReactionSystemBase): @@ -94,12 +99,12 @@ def __init__( self._tolerances: Tuple[float, float] = None self.set_tolerances(atol, rtol) self.units: str = units - """The units of mass for this species. - For bulk species, concentration is this unit divided by liters, for wall species, concentration is this unit - divided by the model's area-unit (see options). + """Units of mass for this species. For bulk species, concentration is + this unit divided by liters, for wall species, concentration is this + unit divided by the model's area-unit (see options). """ self.diffusivity: float = diffusivity - """The diffusivity of this species in water, if being used, by default None""" + """Diffusivity of this species in water, if being used, by default None""" self._vars: ReactionSystemBase = _vars self._vals: InitialQuality = _vals @@ -112,16 +117,16 @@ def set_tolerances(self, atol: float, rtol: float): Parameters ---------- atol - The absolute tolerance to use + Absolute tolerance to use rtol - The relative tolerance to use + Relative tolerance to use Raises ------ TypeError - if only one of `atol` or `rtol` is a float + If only one of `atol` or `rtol` is a float ValueError - if `atol` or `rtol` ≤ 0 + If `atol` or `rtol` ≤ 0 """ if (atol is None) ^ (rtol is None): raise TypeError("atol and rtol must both be float or both be None") @@ -138,41 +143,43 @@ def get_tolerances(self) -> Union[Tuple[float, float], None]: Returns ------- (atol, rtol) : (float, float) or None - absolute and relative tolerances, respectively, if they are set + Absolute and relative tolerances, respectively, if they are set """ return self._tolerances def clear_tolerances(self): - """Set both tolerances to None, reverting to the global options value.""" + """Set both tolerances to None, reverting to the global options value. + """ self._tolerances = None @property def atol(self) -> float: - """The absolute tolerance. Must be set using :meth:`set_tolerances`""" + """Absolute tolerance. Must be set using :meth:`set_tolerances`""" if self._tolerances is not None: return self._tolerances[0] return None @property def rtol(self) -> float: - """The relative tolerance. Must be set using :meth:`set_tolerances`""" + """Relative tolerance. Must be set using :meth:`set_tolerances`""" if self._tolerances is not None: return self._tolerances[1] return None @property def var_type(self) -> VariableType: - """The type of variable, :attr:`~wntr.msx.base.VariableType.SPECIES`.""" + """Type of variable, :attr:`~wntr.msx.base.VariableType.SPECIES`.""" return VariableType.SPECIES @property def species_type(self) -> SpeciesType: - """The type of species, either :attr:`~wntr.msx.base.SpeciesType.BULK` or :attr:`~wntr.msx.base.SpeciesType.WALL`""" + """Type of species, either :attr:`~wntr.msx.base.SpeciesType.BULK` + or :attr:`~wntr.msx.base.SpeciesType.WALL`""" return self._species_type @property def initial_quality(self) -> 'InitialQuality': - """If a specific network has been linked, then the initial quality values for the network""" + """Initial quality values for the network""" if self._vals is not None: return self._vals else: @@ -180,7 +187,7 @@ def initial_quality(self) -> 'InitialQuality': @property def pipe_reaction(self) -> 'Reaction': - """The pipe reaction definition""" + """Pipe reaction definition""" if self._vars is not None: return self._vars.pipe_reactions[self.name] else: @@ -188,14 +195,14 @@ def pipe_reaction(self) -> 'Reaction': @property def tank_reaction(self) -> 'Reaction': - """The tank reaction definition""" + """Tank reaction definition""" if self._vars is not None: return self._vars.tank_reactions[self.name] else: raise AttributeError("This species is not connected to a ReactionSystem") def to_dict(self) -> Dict[str, Any]: - """Create a dictionary representation of the object + """Dictionary representation of the object The species dictionary has the following format, as described using a json schema. @@ -249,23 +256,23 @@ def to_dict(self) -> Dict[str, Any]: class Constant(VariableBase): - """A constant coefficient for use in reaction expressions.""" + """Constant coefficient for use in expressions""" def __init__(self, name: str, value: float, *, units: str = None, note: Union[str, dict, ENcomment] = None, _vars: ReactionSystemBase = None) -> None: - """A variable representing a constant value. + """Constant coefficient for use in expressions Parameters ---------- name - The name of the variable. + Name of the variable. value - The constant value. + Constant value. units Units for the variable, by default None note Supplementary information regarding this variable, by default None _vars - the reaction system this constant is a part of, by default None + Reaction system this constant is a part of, by default None """ super().__init__(name, note=note) if _vars is not None and not isinstance(_vars, ReactionSystemBase): @@ -273,9 +280,9 @@ def __init__(self, name: str, value: float, *, units: str = None, note: Union[st if _vars is not None and name in _vars: raise KeyExistsError("This variable name is already taken") self.value: float = float(value) - """The value of the constant""" + """Value of the constant""" self.units: str = units - """The units of the constant""" + """Units of the constant""" self._vars: ReactionSystemBase = _vars def __call__(self, *, t=None) -> Any: @@ -283,10 +290,11 @@ def __call__(self, *, t=None) -> Any: @property def var_type(self) -> VariableType: - """The type of variable, :attr:`~wntr.msx.base.VariableType.CONSTANT`.""" + """Type of variable, :attr:`~wntr.msx.base.VariableType.CONSTANT`.""" return VariableType.CONSTANT def to_dict(self) -> Dict[str, Any]: + """Dictionary representation of the object""" ret = dict(name=self.name, value=self.value) if self.units: ret["units"] = self.units @@ -298,27 +306,27 @@ def to_dict(self) -> Dict[str, Any]: class Parameter(VariableBase): - """A coefficient that is parameterized by pipe/tank.""" + """Parameterized variable for use in expressions""" def __init__( self, name: str, global_value: float, *, units: str = None, note: Union[str, dict, ENcomment] = None, _vars: ReactionSystemBase = None, _vals: VariableValuesBase = None ) -> None: - """A parameterized variable for use in expressions. + """Parameterized variable for use in expressions Parameters ---------- name - The name of this parameter. + Name of this parameter. global_value - The global value for the parameter if otherwise unspecified. + Global value for the parameter if otherwise unspecified. units - The units for this parameter, by default None + Units for this parameter, by default None note Supplementary information regarding this variable, by default None _vars - the reaction system this parameter is a part of, by default None + Reaction system this parameter is a part of, by default None _vals - the netork-specific values for this parameter, by default None + Network-specific values for this parameter, by default None """ super().__init__(name, note=note) if _vars is not None and not isinstance(_vars, ReactionSystemBase): @@ -343,21 +351,22 @@ def __call__(self, *, pipe: str = None, tank: str = None) -> float: Parameters ---------- pipe - the name of a pipe to get the parameter value for, by default None + Name of a pipe to get the parameter value for, by default None tank - the name of a pipe to get the parameter value for, by default None + Name of a pipe to get the parameter value for, by default None Returns ------- float - the value at the specified pipe or tank, or the global value + Value at the specified pipe or tank, or the global value Raises ------ TypeError - if both pipe and tank are specified + If both pipe and tank are specified ValueError - if there is no ParameterValues object defined for and linked to this parameter + If there is no ParameterValues object defined for and linked to + this parameter """ if pipe is not None and tank is not None: raise TypeError("Both pipe and tank cannot be specified at the same time") @@ -371,10 +380,11 @@ def __call__(self, *, pipe: str = None, tank: str = None) -> float: @property def var_type(self) -> VariableType: - """The type of variable, :attr:`~wntr.msx.base.VariableType.PARAMETER`.""" + """Type of variable, :attr:`~wntr.msx.base.VariableType.PARAMETER`.""" return VariableType.PARAMETER def to_dict(self) -> Dict[str, Any]: + """Dictionary representation of the object""" ret = dict(name=self.name, global_value=self.global_value) if self.units: ret["units"] = self.units @@ -386,21 +396,23 @@ def to_dict(self) -> Dict[str, Any]: class Term(VariableBase): - """A named expression that can be used as a term in other expressions.""" + """Named expression (term) that can be used in expressions""" - def __init__(self, name: str, expression: str, *, note: Union[str, dict, ENcomment] = None, _vars: ReactionSystemBase = None) -> None: - """A named expression that can be used as a term in other expressions. + def __init__(self, name: str, expression: str, *, + note: Union[str, dict, ENcomment] = None, + _vars: ReactionSystemBase = None) -> None: + """Named expression (term) that can be used in expressions Parameters ---------- name - The variable name. + Variable name. expression - The mathematical expression to be aliased + Mathematical expression to be aliased note Supplementary information regarding this variable, by default None _vars - the reaction system this species is a part of, by default None + Reaction system this species is a part of, by default None """ super().__init__(name, note=note) if _vars is not None and not isinstance(_vars, ReactionSystemBase): @@ -408,15 +420,16 @@ def __init__(self, name: str, expression: str, *, note: Union[str, dict, ENcomme if _vars is not None and name in _vars: raise KeyExistsError("This variable name is already taken") self.expression: str = expression - """The expression that is aliased by this term""" + """Expression that is aliased by this term""" self._vars: ReactionSystemBase = _vars @property def var_type(self) -> VariableType: - """The type of variable, :attr:`~wntr.msx.base.VariableType.TERM`.""" + """Type of variable, :attr:`~wntr.msx.base.VariableType.TERM`.""" return VariableType.TERM def to_dict(self) -> Dict[str, Any]: + """Dictionary representation of the object""" ret = dict(name=self.name, expression=self.expression) if isinstance(self.note, ENcomment): ret["note"] = self.note.to_dict() @@ -426,70 +439,71 @@ def to_dict(self) -> Dict[str, Any]: class ReservedName(VariableBase): - """An object representing a reserved name that should not be used by the user.""" + """Reserved name that should not be used""" def __init__(self, name: str, *, note: Union[str, dict, ENcomment] = None) -> None: - """An object representing a reserved name that should not be used by the user. + """Reserved name that should not be used Parameters ---------- name - The reserved name. + Reserved name. note Supplementary information regarding this variable, by default None Raises ------ KeyExistsError - if the name has already been registered + If the name has already been registered """ self.name: str = name self.note: Union[str, dict, ENcomment] = note @property def var_type(self) -> VariableType: - """The type of variable, :attr:`~wntr.msx.base.VariableType.RESERVED`.""" + """Type of variable, :attr:`~wntr.msx.base.VariableType.RESERVED`.""" return VariableType.RESERVED def to_dict(self) -> Dict[str, Any]: + """Dictionary representation of the object""" return "{}({})".format(self.__class__.__name__, ", ".join(["name={}".format(repr(self.name)), "note={}".format(repr(self.note))])) class HydraulicVariable(ReservedName): - """A variable representing instantaneous hydraulics data.""" + """Reserved name for hydraulic variables""" def __init__(self, name: str, units: str = None, *, note: Union[str, dict, ENcomment] = None) -> None: - """A variable representing instantaneous hydraulics data. + """Reserved name for hydraulic variables The user should not need to create any variables using this class, they - are created automatically by the MultispeciesModel object during initialization. + are created automatically by the MsxModel object during initialization. Parameters ---------- name - The name of the variable (predefined by MSX) + Name of the variable (predefined by MSX) units - The units for hydraulic variable, by default None + Units for hydraulic variable, by default None note Supplementary information regarding this variable, by default None """ super().__init__(name, note=note) self.units: str = units - """The hydraulic variable's units""" + """Hydraulic variable's units""" class MathFunction(ReservedName): - """A variable that is actually a mathematical function defined by MSX.""" + """Reserved name for math functions""" def __init__(self, name: str, func: callable, *, note: Union[str, dict, ENcomment] = None) -> None: - """A variable that is actually a mathematical function defined by MSX. + """Reserved name for math functions Parameters ---------- name - The function name + Function name func - The callable function + Callable function note Supplementary information regarding this variable, by default None """ @@ -503,7 +517,7 @@ def __call__(self, *args: Any, **kwds: Any) -> Any: class Reaction(ReactionBase): - """A water quality biochemical reaction dynamics definition for a specific species.""" + """Water quality reaction dynamics definition for a specific species""" def __init__( self, @@ -515,22 +529,24 @@ def __init__( note: Union[str, dict, ENcomment] = None, _vars: ReactionSystemBase = None, ) -> None: - """A water quality biochemical reaction dynamics definition for a specific species. + """Water quality reaction dynamics definition for a specific species Parameters ---------- species_name - The species (object or name) this reaction is applicable to. + Species (object or name) this reaction is applicable to. reaction_type - The type of reaction, either PIPE or TANK + Reaction type (location), from {PIPE, TANK} expression_type - The type of reaction dynamics being described by the expression: one of RATE, FORMULA, or EQUIL. + Expression type (left-hand-side) of the equation, from + {RATE, EQUIL, FORMULA} expression - The mathematical expression for the right-hand-side of the reaction equation. + Mathematical expression for the right-hand-side of the reaction + equation. note Supplementary information regarding this variable, by default None _vars - the reaction system this species is a part of, by default None + Reaction system this species is a part of, by default None """ super().__init__(species_name=species_name, note=note) if _vars is not None and not isinstance(_vars, ReactionSystemBase): @@ -546,20 +562,26 @@ def __init__( if not expression: raise TypeError("expression cannot be None") self.expression: str = expression - """The mathematical expression (right-hand-side)""" + """Mathematical expression (right-hand-side)""" self._vars: ReactionSystemBase = _vars @property def expression_type(self) -> ExpressionType: - """The expression type (left-hand-side), either :attr:`~wntr.msx.base.ExpressionType.RATE`, :attr:`~wntr.msx.base.ExpressionType.EQUIL`, or :attr:`~wntr.msx.base.ExpressionType.FORMULA`""" + """Expression type (left-hand-side), either + :attr:`~wntr.msx.base.ExpressionType.RATE`, + :attr:`~wntr.msx.base.ExpressionType.EQUIL`, or + :attr:`~wntr.msx.base.ExpressionType.FORMULA`""" return self._expr_type @property def reaction_type(self) -> ReactionType: - """The reaction type (reaction location), either :attr:`~wntr.msx.base.ReactionType.PIPE` or :attr:`~wntr.msx.base.ReactionType.TANK`""" + """Reaction type (location), either + :attr:`~wntr.msx.base.ReactionType.PIPE` or + :attr:`~wntr.msx.base.ReactionType.TANK`""" return self.__rxn_type def to_dict(self) -> dict: + """Dictionary representation of the object""" ret = dict(species_name=str(self.species_name), expression_type=self.expression_type.name.lower(), expression=self.expression) if isinstance(self.note, ENcomment): ret["note"] = self.note.to_dict() @@ -569,22 +591,24 @@ def to_dict(self) -> dict: class InitialQuality(VariableValuesBase): - """A container for initial quality values for a species in a specific network.""" + """Initial quality values for a species in a specific network""" def __init__(self, global_value: float = 0.0, node_values: dict = None, link_values: dict = None): - """The initial quality values for a species. + """Initial quality values for a species in a specific network Parameters ---------- global_value - the global initial quality value, by default 0.0 + Global initial quality value, by default 0.0 node_values - any different initial quality values for specific nodes, by default None + Any different initial quality values for specific nodes, + by default None link_values - any different initial quality values for specific links, by default None + Any different initial quality values for specific links, + by default None """ self.global_value = global_value - """The global initial quality values for this species.""" + """Global initial quality values for this species.""" self._node_values = node_values if node_values is not None else dict() self._link_values = link_values if link_values is not None else dict() @@ -595,35 +619,41 @@ def __repr__(self) -> str: @property def var_type(self) -> VariableType: - """The type of variable, :attr:`~wntr.msx.base.VariableType.SPECIES`, this object holds data for.""" + """Type of variable, :attr:`~wntr.msx.base.VariableType.SPECIES`, + this object holds data for.""" return VariableType.SPECIES @property def node_values(self) -> Dict[str, float]: - """A mapping that overrides the global_value of the initial quality at specific nodes""" + """Mapping that overrides the global_value of the initial quality at + specific nodes""" return self._node_values @property def link_values(self) -> Dict[str, float]: - """A mapping that overrides the global_value of the initial quality in specific links""" + """Mapping that overrides the global_value of the initial quality in + specific links""" return self._link_values def to_dict(self) -> Dict[str, Dict[str, float]]: + """Dictionary representation of the object""" return dict(global_value=self.global_value, node_values=self._node_values.copy(), link_values=self._link_values.copy()) class ParameterValues(VariableValuesBase): - """A container for pipe and tank specific values of a parameter for a specific network.""" + """Pipe and tank specific values of a parameter for a specific network""" def __init__(self, *, pipe_values: dict = None, tank_values: dict = None) -> None: - """The non-global values for a parameter. + """Pipe and tank specific values of a parameter for a specific network Parameters ---------- pipe_values - any different values for this parameter for specific pipes, by default None + Any different values for this parameter for specific pipes, + by default None tank_values - any different values for this parameter for specific tanks, by default None + Any different values for this parameter for specific tanks, + by default None """ self._pipe_values = pipe_values if pipe_values is not None else dict() self._tank_values = tank_values if tank_values is not None else dict() @@ -633,18 +663,22 @@ def __repr__(self) -> str: @property def var_type(self) -> VariableType: - """The type of variable, :attr:`~wntr.msx.base.VariableType.PARAMETER`, this object holds data for.""" + """Type of variable, :attr:`~wntr.msx.base.VariableType.PARAMETER`, + this object holds data for.""" return VariableType.PARAMETER @property def pipe_values(self) -> Dict[str, float]: - """A mapping that overrides the global_value of a parameter for a specific pipe""" + """Mapping that overrides the global_value of a parameter for a + specific pipe""" return self._pipe_values @property def tank_values(self) -> Dict[str, float]: - """A mapping that overrides the global_value of a parameter for a specific tank""" + """Mapping that overrides the global_value of a parameter for a + specific tank""" return self._tank_values def to_dict(self) -> Dict[str, Dict[str, float]]: + """Dictionary representation of the object""" return dict(pipe_values=self._pipe_values.copy(), tank_values=self._tank_values.copy()) diff --git a/wntr/msx/library.py b/wntr/msx/library.py index 76f00a173..62ce4d1ea 100644 --- a/wntr/msx/library.py +++ b/wntr/msx/library.py @@ -1,18 +1,19 @@ -# -*- coding: utf-8 -*- - -r"""A library of common MSX reactions. - +# coding: utf-8 +""" +The wntr.msx.library module includes a library of multi-species water +models .. rubric:: Environment Variable .. envvar:: WNTR_RXN_LIBRARY_PATH This environment variable, if set, will add additional folder(s) to the - path to search for quality model files, (files with an ".msx", ".yaml", - or ".json" file extension). + path to search for multi-species water quality model files, + (files with an ".msx", ".yaml", or ".json" file extension). Multiple folders should be separated using the "``;``" character. See :class:`~wntr.msx.library.ReactionLibrary` for more details. """ + from __future__ import annotations import json @@ -44,67 +45,49 @@ logger = logging.getLogger(__name__) -def cite_msx() -> dict: - """A citation generator for the EPANET-MSX user guide. - - Returns - ------- - str - Shang, F. and Rossman, L.A. and Uber, J.G. (2023) "EPANET-MSX 2.0 User Manual". (Cincinnati, OH: Water Infrastructure Division (CESER), U.S. Environmental Protection Agency). EPA/600/R-22/199. - """ - return 'Shang, F. and Rossman, L.A. and Uber, J.G. (2023) "EPANET-MSX 2.0 User Manual". (Cincinnati, OH: Water Infrastructure Division (CESER), U.S. Environmental Protection Agency). EPA/600/R-22/199.' - # return dict( - # entry_type="report", - # key="SRU23", - # fields=dict( - # title="EPANET-MSX 2.0 User Manual", - # year=2023, - # author="Shang, F. and Rossman, L.A. and Uber, J.G.", - # institution="Water Infrastructure Division (CESER), U.S. Environmental Protection Agency", - # location="Cincinnati, OH", - # number="EPA/600/R-22/199", - # ), - # ) - - class ReactionLibrary: - """A library of multispecies reaction definitions. + """Library of multi-species water quality models - This object can be accessed and treated like a dictionary, where keys are the model - names and the values are the model objects. + This object can be accessed and treated like a dictionary, where keys are + the model names and the values are the model objects. Paths are added/processed in the following order: 1. the builtin directory of reactions, - 2. any paths specified in the environment variable described below, with directories listed - first having the highest priority, - 3. any extra paths specified in the constructor, searched in the order provided. + 2. any paths specified in the environment variable described below, with + directories listed first having the highest priority, + 3. any extra paths specified in the constructor, searched in the order + provided. + + Once created, the library paths cannot be modified. However, a model can + be added to the library using :meth:`add_model_from_file` or + :meth:`add_models_from_dir`. - Once created, the library paths cannot be modified. However, a model can be added - to the library using :meth:`add_model_from_file` or :meth:`add_models_from_dir`. """ - def __init__(self, extra_paths: List[str] = None, include_builtins=True, include_envvar_paths=True, load=True) -> None: - """A library of multispecies reaction definitions. + def __init__(self, extra_paths: List[str] = None, include_builtins=True, + include_envvar_paths=True, load=True) -> None: + """Library of multi-species water quality models Parameters ---------- extra_paths : list of str, optional - user-specified list of reaction library directories, by default None + User-specified list of reaction library directories, by default + None include_builtins : bool, optional - load files built-in with wntr, by default True + Load files built-in with WNTR, by default True include_envvar_paths : bool, optional - load files from the paths specified in :envvar:`WNTR_RXN_LIBRARY_PATH`, by default True + Load files from the paths specified in + :envvar:`WNTR_RXN_LIBRARY_PATH`, by default True load : bool or str, optional - load the files immediately on creation, by default True. - + Load the files immediately on creation, by default True. If a string, then it will be passed as the `duplicates` argument to the load function. See :meth:`reset_and_reload` for details. Raises ------ TypeError - if `extra_paths` is not a list + If `extra_paths` is not a list """ if extra_paths is None: extra_paths = list() @@ -142,20 +125,20 @@ def __repr__(self) -> str: return "{}({})".format(self.__class__.__name__, repr(self.__library_paths)) def path_list(self) -> List[str]: - """Get the original list of paths used for this library. + """List of paths used to populate the library Returns ------- list of str - a copy of the paths used to **initially** populate this library + Copy of the paths used to **initially** populate the library """ return self.__library_paths.copy() def reset_and_reload(self, duplicates: str = "error") -> List[Tuple[str, str, Any]]: - """Load data from the configured directories into a library of models. + """Load data from the configured directories into a library of models - Note, this function is not recursive and does not 'walk' any of the library's - directories to look for subfolders. + Note, this function is not recursive and does not 'walk' any of the + library's directories to look for subfolders. The ``duplicates`` argument specifies how models that have the same name, or that have the same filename if a name isn't specified in the file, @@ -187,13 +170,13 @@ def reset_and_reload(self, duplicates: str = "error") -> List[Tuple[str, str, An Raises ------ TypeError - if `duplicates` is not a string + If `duplicates` is not a string ValueError - if `duplicates` is not a valid value + If `duplicates` is not a valid value IOError - if `path_to_folder` is not a directory + If `path_to_folder` is not a directory KeyError - if `duplicates` is ``"error"`` and two models have the same name + If `duplicates` is ``"error"`` and two models have the same name """ if duplicates and not isinstance(duplicates, str): raise TypeError("The `duplicates` argument must be None or a string") @@ -207,44 +190,43 @@ def reset_and_reload(self, duplicates: str = "error") -> List[Tuple[str, str, An return load_errors def add_models_from_dir(self, path_to_dir: str, duplicates: str = "error") -> List[Tuple[str, str, Union[MsxModel, Exception]]]: - """Load all valid model files in a folder. - - Note, this function is not recursive and does not 'walk' a directory tree. + """Load all valid model files in a folder - The ``duplicates`` argument specifies how models that have the same name, - or that have the same filename if a name isn't specified in the file, - are handled. **Warning**, if two files in the same directory have models - with the same name, there is no guarantee which will be read in first. + Note, this function is not recursive and does not 'walk' a directory + tree. Parameters ---------- path_to_dir : str - the path to the folder to search + Path to the folder to search duplicates : {"error", "skip", "replace"}, optional + Specifies how models that have the same name, or that have the same + filename if a name isn't specified in the file, are handled. + **Warning**, if two files in the same directory have models with + the same name, there is no guarantee which will be read in first, by default ``"error"`` - - - A value of of ``"error"`` raises an exception and stops execution. - - A value of ``"skip"`` will skip models with the same `name` as a model that already - exists in the library. - - A value of ``"replace"`` will replace any existing model with a model that is read - in that has the same `name`. + - A value of of ``"error"`` raises an exception and stops execution + - A value of ``"skip"`` will skip models with the same `name` as a + model that already exists in the library. + - A value of ``"replace"`` will replace any existing model with a + model that is read in that has the same `name`. Returns ------- (filename, reason, obj) : tuple[str, str, Any] - the file not read in, the cause of the problem, and the object that was skipped/overwritten - or the exception raised + File not read in, the cause of the problem, and the object that was + skipped/overwritten or the exception raised Raises ------ TypeError - if `duplicates` is not a string + If `duplicates` is not a string ValueError - if `duplicates` is not a valid value + If `duplicates` is not a valid value IOError - if `path_to_folder` is not a directory + If `path_to_folder` is not a directory KeyError - if `duplicates` is ``"error"`` and two models have the same name + If `duplicates` is ``"error"`` and two models have the same name """ if duplicates and not isinstance(duplicates, str): raise TypeError("The `duplicates` argument must be None or a string") @@ -309,7 +291,7 @@ def add_models_from_dir(self, path_to_dir: str, duplicates: str = "error") -> Li return load_errors def add_model_from_file(self, path_and_filename: str, name: str = None): - """Load a reaction model from a file and add it to the model. + """Load a model from a file and add it to the library Note, this **does not check** to see if a model exists with the same name, and it will automatically overwrite the existing model if one @@ -349,22 +331,22 @@ def add_model_from_file(self, path_and_filename: str, name: str = None): self.__data[new.name] = new def get_model(self, name: str) -> MsxModel: - """Get a reaction model from the library by model name. + """Get a model from the library by model name Parameters ---------- name : str - the name of the model + Name of the model Returns ------- MsxModel - the model object + Model object """ return self.__data[name] def model_name_list(self) -> List[str]: - """Get the names of all models in the library. + """Get the names of all models in the library Returns ------- diff --git a/wntr/msx/model.py b/wntr/msx/model.py index 4d9749c3d..49bf90058 100644 --- a/wntr/msx/model.py +++ b/wntr/msx/model.py @@ -1,13 +1,15 @@ -# -*- coding: utf-8 -*- - -"""The WNTR MSX model. +# coding: utf-8 +""" +The wntr.msx.model module includes methods to build a multi-species water +quality model. """ + from __future__ import annotations import logging import warnings -from typing import Any, Dict, Generator, List, NewType, Union -from wntr.epanet.util import ENcomment, NoteType +from typing import Dict, Generator, List, Union +from wntr.epanet.util import NoteType from wntr.utils.disjoint_mapping import KeyExistsError @@ -18,7 +20,6 @@ ReactionBase, NetworkDataBase, ReactionSystemBase, - VariableBase, ExpressionType, ReactionType, SpeciesType, @@ -34,7 +35,8 @@ class MsxReactionSystem(ReactionSystemBase): - """A registry for all the variables registered in the multispecies reactions model. + """Registry for all the variables registered in the multi-species reactions + model. This object can be used like a mapping. """ @@ -53,32 +55,32 @@ def __init__(self) -> None: @property def species(self) -> Dict[str, Species]: - """The dictionary view onto only species""" + """Dictionary view onto only species""" return self._species @property def constants(self) -> Dict[str, Constant]: - """The dictionary view onto only constants""" + """Dictionary view onto only constants""" return self._const @property def parameters(self) -> Dict[str, Parameter]: - """The dictionary view onto only parameters""" + """Dictionary view onto only parameters""" return self._param @property def terms(self) -> Dict[str, Term]: - """The dictionary view onto only named terms""" + """Dictionary view onto only named terms""" return self._term @property def pipe_reactions(self) -> Dict[str, Reaction]: - """The dictionary view onto pipe reactions""" + """Dictionary view onto pipe reactions""" return self._pipes @property def tank_reactions(self) -> Dict[str, Reaction]: - """The dictionary view onto tank reactions""" + """Dictionary view onto tank reactions""" return self._tanks def add_variable(self, variable: MsxVariable) -> None: @@ -90,14 +92,14 @@ def add_variable(self, variable: MsxVariable) -> None: Parameters ---------- variable - The variable to add. + Variable to add. Raises ------ TypeError - if `variable` is not an MsxVariable + If `variable` is not an MsxVariable KeyExistsError - if `variable` has a name that is already used in the registry + If `variable` has a name that is already used in the registry """ if not isinstance(variable, (Species, Constant, Parameter, Term, MathFunction, HydraulicVariable)): raise TypeError("Expected AVariable object") @@ -112,14 +114,14 @@ def add_reaction(self, reaction: Reaction) -> None: Parameters ---------- reaction : Reaction - a water quality reaction definition + Water quality reaction definition Raises ------ TypeError - if `reaction` is not a Reaction + If `reaction` is not a Reaction KeyError - if the `species_name` in the `reaction` does not exist in the model + If the `species_name` in the `reaction` does not exist in the model """ if not isinstance(reaction, Reaction): raise TypeError("Expected a Reaction object") @@ -129,17 +131,18 @@ def add_reaction(self, reaction: Reaction) -> None: def variables(self) -> Generator[tuple, None, None]: # FIXME: rename without "all_" for this - """A generator looping through all variables""" + """Generator looping through all variables""" for k, v in self._vars.items(): yield k, v.var_type.name.lower(), v def reactions(self) -> Generator[tuple, None, None]: - """A generator looping through all reactions""" + """Generator looping through all reactions""" for k2, v in self._rxns.items(): for k1, v1 in v.items(): yield k1, k2, v1 def to_dict(self) -> dict: + """Dictionary representation of the MsxModel.""" return dict( species=[v.to_dict() for v in self._species.values()], constants=[v.to_dict() for v in self._const.values()], @@ -151,38 +154,46 @@ def to_dict(self) -> dict: class MsxNetworkData(NetworkDataBase): - """A container for network-specific values associated with a multispecies water quality model.""" - def __init__(self, patterns: Dict[str, List[float]] = None, sources: Dict[str, Dict[str, dict]] = None, initial_quality: Dict[str, Union[dict,InitialQuality]] = None, parameter_values: Dict[str, Union[dict, ParameterValues]] = None) -> None: - """A container for network-specific values associated with a multispecies water quality model. + def __init__(self, patterns: Dict[str, List[float]] = None, + sources: Dict[str, Dict[str, dict]] = None, + initial_quality: Dict[str, Union[dict, InitialQuality]] = None, + parameter_values: Dict[str, Union[dict, ParameterValues]] = None) -> None: + """Network-specific values associated with a multi-species water + quality model - Data is copied from dictionaries passed in, so once created, the dictionaries passed are not connected - to this object. + Data is copied from dictionaries passed in, so once created, the + dictionaries passed are not connected to this object. Parameters ---------- patterns : dict, optional - patterns to use for sources + Patterns to use for sources sources : dict, optional - sources defined for the model + Sources defined for the model initial_quality : dict, optional - initial values for different species at different nodes, links, and the global value + Initial values for different species at different nodes, links, and + the global value parameter_values : dict, optional - parameter values for different pipes and tanks + Parameter values for different pipes and tanks Notes ----- ``patterns`` - A dictionary keyed by pattern name (str) with values being the multipliers (list of float) + Dictionary keyed by pattern name (str) with values being the + multipliers (list of float) ``sources`` - A dictionary keyed by species name (str) with values being dictionaries keyed by junction name (str) with values being the + Dictionary keyed by species name (str) with values being + dictionaries keyed by junction name (str) with values being the dictionary of settings for the source ``initial_quality`` - A dictionary keyed by species name (str) with values being either an :class:`~wntr.msx.elements.InitialQuality` object or - the appropriate dictionary representation thereof. + Dictionary keyed by species name (str) with values being either an + :class:`~wntr.msx.elements.InitialQuality` object or the + appropriate dictionary representation thereof. ``parameter_values`` - A dictionary keyed by parameter name (str) with values being either a :class:`~wntr.msx.elements.ParameterValues` object or - the appropriate dictionary representation thereof. + Dictionary keyed by parameter name (str) with values being either + a :class:`~wntr.msx.elements.ParameterValues` object or the + appropriate dictionary representation thereof. """ if sources is None: sources = dict() @@ -206,53 +217,55 @@ def __init__(self, patterns: Dict[str, List[float]] = None, sources: Dict[str, D @property def sources(self): - """A dictionary of sources, keyed by species name""" + """Dictionary of sources, keyed by species name""" return self._source_dict @property def initial_quality(self) -> Dict[str, InitialQuality]: - """A dictionary of initial quality values, keyed by species name""" + """Dictionary of initial quality values, keyed by species name""" return self._initial_quality_dict @property def patterns(self): - """A dictionary of patterns, specific for the water quality model, keyed by pattern name. + """Dictionary of patterns, specific for the water quality model, keyed + by pattern name. - .. note:: the WaterNetworkModel cannot see these patterns, so names can be reused, so be - careful. Likewise, this model cannot see the WaterNetworkModel patterns, so this could be - a source of some confusion. + .. note:: the WaterNetworkModel cannot see these patterns, so names can + be reused, so be careful. Likewise, this model cannot see the + WaterNetworkModel patterns, so this could be a source of some + confusion. """ return self._pattern_dict @property def parameter_values(self) -> Dict[str, ParameterValues]: - """A dictionary of parameter values, keyed by parameter name""" + """Dictionary of parameter values, keyed by parameter name""" return self._parameter_value_dict def add_pattern(self, name: str, multipliers: List[float]): - """Add a water-quality-model-specific pattern. + """Add a water quality model specific pattern. Arguments --------- name : str - The pattern name + Pattern name multipliers : list of float - The pattern multipliers + Pattern multipliers """ self._pattern_dict[name] = multipliers def init_new_species(self, species: Species): - """(Re)set the initial quality values for a species to a new container + """(Re)set the initial quality values for a species Arguments --------- species : Species - The species to (re)initialized. + Species to (re)initialized. Returns ------- InitialQuality - the new initial quality values container + New initial quality values """ self._initial_quality_dict[str(species)] = InitialQuality() if isinstance(species, Species): @@ -260,12 +273,12 @@ def init_new_species(self, species: Species): return self._initial_quality_dict[str(species)] def remove_species(self, species: Union[Species, str]): - """Remove a species from the network specific model. + """Remove a species from the network specific model Arguments --------- species : Species or str - a species to be removed from the network data + Species to be removed from the network data """ if isinstance(species, Species): species._vals = None @@ -275,17 +288,17 @@ def remove_species(self, species: Union[Species, str]): pass def init_new_parameter(self, param: Parameter): - """(Re)initialize parameter values for a parameter. + """(Re)initialize parameter values for a parameter Arguments --------- param : Parameter - a parameter to be (re)initialized with network data + Parameter to be (re)initialized with network data Returns ------- ParameterValues - the new network data for the specific parameter + New network data for the specific parameter """ self._parameter_value_dict[str(param)] = ParameterValues() if isinstance(param, Parameter): @@ -293,14 +306,14 @@ def init_new_parameter(self, param: Parameter): return self._parameter_value_dict[str(param)] def remove_parameter(self, param: Union[Parameter, str]): - """Remove values associated with a specific parameter. + """Remove values associated with a specific parameter Ignores non-parameters. Arguments --------- param : Parameter or str - the parameter or parameter name to be removed from the network data + Parameter or parameter name to be removed from the network data """ if isinstance(param, Parameter): param._vals = None @@ -321,15 +334,15 @@ def to_dict(self) -> dict: class MsxModel(QualityModelBase): - """A multispecies water quality model for use with WNTR EPANET-MSX simulator.""" + """Multi-species water quality model""" def __init__(self, msx_file_name=None) -> None: - """A full, multi-species water quality model. + """Multi-species water quality model Arguments --------- msx_file_name : str, optional - an MSX file to read in, by default None + MSX file to to load into the MsxModel object, by default None """ super().__init__(msx_file_name) self._references: List[Union[str, Dict[str, str]]] = list() @@ -363,47 +376,48 @@ def __repr__(self) -> str: @property def references(self) -> List[Union[str, Dict[str, str]]]: - """A list of strings or mappings that provide references for this model. + """List of strings or mappings that provide references for this model .. note:: - This property is a list, and should be modified using append/insert/remove. - Members of the list should be json seriealizable (i.e., strings or dicts of strings). + This property is a list, and should be modified using + append/insert/remove. Members of the list should be json + serializable (i.e., strings or dicts of strings). """ return self._references @property def reaction_system(self) -> MsxReactionSystem: - """The reaction variables defined for this model.""" + """Reaction variables defined for this model""" return self._rxn_system @property def network_data(self) -> MsxNetworkData: - """The network-specific values added to this model.""" + """Network-specific values added to this model""" return self._net_data @property def options(self) -> MsxSolverOptions: - """The MSX model options""" + """MSX model options""" return self._options @property def species_name_list(self) -> List[str]: - """all defined species names""" + """Get a list of species names""" return list(self.reaction_system.species.keys()) @property def constant_name_list(self) -> List[str]: - """all defined coefficient names""" + """Get a list of coefficient names""" return list(self.reaction_system.constants.keys()) @property def parameter_name_list(self) -> List[str]: - """all defined coefficient names""" + """Get a list of coefficient names""" return list(self.reaction_system.parameters.keys()) @property def term_name_list(self) -> List[str]: - """all defined function (MSX 'terms') names""" + """Get a list of function (MSX 'terms') names""" return list(self.reaction_system.terms.keys()) @options.setter @@ -411,7 +425,7 @@ def options(self, value: Union[dict, MsxSolverOptions]): if isinstance(value, dict): self._options = MsxSolverOptions.factory(value) elif not isinstance(value, MsxSolverOptions): - raise TypeError("Expected a MultispeciesOptions object, got {}".format(type(value))) + raise TypeError("Expected a MsxSolverOptions object, got {}".format(type(value))) else: self._options = value @@ -430,32 +444,32 @@ def add_species( Arguments --------- name : str - the species name + Species name species_type : SpeciesType - the type of species, either BULK or WALL + Type of species, either BULK or WALL units : str - the mass units for this species + Mass units for this species atol : float, optional unless rtol is not None - the absolute solver tolerance for this species, by default None + Absolute solver tolerance for this species, by default None rtol : float, optional unless atol is not None - the relative solver tolerance for this species, by default None + Relative solver tolerance for this species, by default None note : NoteType, optional keyword - supplementary information regarding this variable, by default None + Supplementary information regarding this variable, by default None (see also :class:`~wntr.epanet.util.ENcomment`) diffusivity : float, optional - diffusivity of this species in water + Diffusivity of this species in water Raises ------ KeyExistsError - if a variable with this name already exists + If a variable with this name already exists ValueError - if `atol` or `rtol` ≤ 0 + If `atol` or `rtol` ≤ 0 Returns ------- Species - the new species + New species """ if name in self._rxn_system: raise KeyExistsError("Variable named {} already exists in model as type {}".format(name, self._rxn_system._vars.get_groupname(name))) @@ -476,19 +490,19 @@ def add_species( return new def remove_species(self, variable_or_name): - """Remove a species from the model. + """Remove a species from the model Removes from both the reaction_system and the network_data. Parameters ---------- variable_or_name : Species or str - the species (or name of the species) to be removed + Species (or name of the species) to be removed Raises ------ KeyError - if `variable_or_name` is not a species in the model + If `variable_or_name` is not a species in the model """ name = str(variable_or_name) if name not in self.reaction_system.species: @@ -498,28 +512,28 @@ def remove_species(self, variable_or_name): self.reaction_system.__delitem__(name) def add_constant(self, name: str, value: float, units: str = None, note: NoteType = None) -> Constant: - """Add a constant coefficient to the model. + """Add a constant coefficient to the model Arguments --------- name : str - the name of the coefficient + Name of the coefficient value : float - the constant value of the coefficient + Constant value of the coefficient units : str, optional - the units for this coefficient, by default None + Units for this coefficient, by default None note : NoteType, optional - supplementary information regarding this variable, by default None + Supplementary information regarding this variable, by default None Raises ------ KeyExistsError - a variable with this name already exists + Variable with this name already exists Returns ------- Constant - the new constant coefficient + New constant coefficient """ if name in self._rxn_system: raise KeyExistsError("Variable named {} already exists in model as type {}".format(name, self._rxn_system._vars.get_groupname(name))) @@ -528,17 +542,17 @@ def add_constant(self, name: str, value: float, units: str = None, note: NoteTyp return new def remove_constant(self, variable_or_name): - """Remove a constant coefficient from the model. + """Remove a constant coefficient from the model Parameters ---------- variable_or_name : Constant or str - the constant (or name of the constant) to be removed + Constant (or name of the constant) to be removed Raises ------ KeyError - if `variable_or_name` is not a constant coefficient in the model + If `variable_or_name` is not a constant coefficient in the model """ name = str(variable_or_name) if name not in self.reaction_system.constants: @@ -547,16 +561,17 @@ def remove_constant(self, variable_or_name): self.reaction_system.__delitem__(name) def add_parameter(self, name: str, global_value: float, units: str = None, note: NoteType = None) -> Parameter: - """Add a parameterized coefficient to the model. + """Add a parameterized coefficient to the model Arguments --------- name : str - the name of the parameter + Name of the parameter global_value : float - the global value of the coefficient (can be overridden for specific pipes/tanks) + Global value of the coefficient (can be overridden for specific + pipes/tanks) units : str, optional - the units for the coefficient, by default None + Units for the coefficient, by default None note : NoteType, optional keyword Supplementary information regarding this variable, by default None (see also :class:`~wntr.epanet.util.ENcomment`). @@ -564,12 +579,12 @@ def add_parameter(self, name: str, global_value: float, units: str = None, note: Raises ------ KeyExistsError - if a variable with this name already exists + If a variable with this name already exists Returns ------- Parameter - the new parameterized coefficient + New parameterized coefficient """ if name in self._rxn_system: raise KeyExistsError("Variable named {} already exists in model as type {}".format(name, self._rxn_system._vars.get_groupname(name))) @@ -579,17 +594,17 @@ def add_parameter(self, name: str, global_value: float, units: str = None, note: return new def remove_parameter(self, variable_or_name): - """Remove a parameterized coefficient from the model. + """Remove a parameterized coefficient from the model Parameters ---------- variable_or_name : Parameter or str - the parameter (or name of the parameter) to be removed + Parameter (or name of the parameter) to be removed Raises ------ KeyError - if `variable_or_name` is not a parameter in the model + If `variable_or_name` is not a parameter in the model """ name = str(variable_or_name) if name not in self.reaction_system.parameters: @@ -599,14 +614,14 @@ def remove_parameter(self, variable_or_name): self.reaction_system.__delitem__(name) def add_term(self, name: str, expression: str, note: NoteType = None) -> Term: - """Add a named expression (term) to the model. + """Add a named expression (term) to the model Parameters ---------- name : str - the name of the functional term to be added + Name of the functional term to be added expression : str - the expression that the term defines + Expression that the term defines note : NoteType, optional keyword Supplementary information regarding this variable, by default None (see also :class:`~wntr.epanet.util.ENcomment`) @@ -619,7 +634,7 @@ def add_term(self, name: str, expression: str, note: NoteType = None) -> Term: Returns ------- Term - the new term + New term """ if name in self._rxn_system: raise KeyError("Variable named {} already exists in model as type {}".format(name, self._rxn_system._vars.get_groupname(name))) @@ -628,17 +643,17 @@ def add_term(self, name: str, expression: str, note: NoteType = None) -> Term: return new def remove_term(self, variable_or_name): - """Remove a named expression (term) from the model. + """Remove a named expression (term) from the model Parameters ---------- variable_or_name : Term or str - the term (or name of the term) to be deleted + Term (or name of the term) to be deleted Raises ------ KeyError - if `variable_or_name` is not a term in the model + If `variable_or_name` is not a term in the model """ name = str(variable_or_name) # FIXME: validate deletion @@ -647,25 +662,26 @@ def remove_term(self, variable_or_name): self.reaction_system.__delitem__(name) def add_reaction(self, species_name: Union[Species, str], reaction_type: ReactionType, expression_type: ExpressionType, expression: str, note: NoteType = None) -> ReactionBase: - """Add a reaction to a species in the model. + """Add a reaction to a species in the model - Note that all species need to have both a pipe and tank reaction defined - unless all species are bulk species and - the tank reactions are identical to the pipe reactions. However, it is not - recommended that users take this approach. + Note that all species need to have both a pipe and tank reaction + defined unless all species are bulk species and the tank reactions are + identical to the pipe reactions. However, it is not recommended that + users take this approach. Once added, access the reactions from the species' object. Arguments --------- species_name : Species or str - the species (or name of species) the reaction is being defined for + Species (or name of species) the reaction is being defined for reaction_type: ReactionType - where this reaction takes place, from {PIPE, TANK} + Reaction type (location), from {PIPE, TANK} expression_type : ExpressionType - the type (LHS) of the equation the expression belongs to, from {RATE, EQUIL, FORMULA} + Expression type (left-hand-side) of the equation, from {RATE, + EQUIL, FORMULA} expression : str - the expression defining the reaction + Expression defining the reaction note : NoteType, optional keyword Supplementary information regarding this reaction, by default None (see also :class:`~wntr.epanet.util.ENcomment`) @@ -673,12 +689,12 @@ def add_reaction(self, species_name: Union[Species, str], reaction_type: Reactio Raises ------ TypeError - if a variable that is not species is passed + If a variable that is not species is passed Returns ------- - MultispeciesReaction - the new reaction object + MsxReactionSystem + New reaction object """ species_name = str(species_name) species = self.reaction_system.species[species_name] @@ -697,20 +713,21 @@ def add_reaction(self, species_name: Union[Species, str], reaction_type: Reactio return new def remove_reaction(self, species_name: str, reaction_type: ReactionType) -> None: - """Remove a reaction at a specified location from a species. + """Remove a reaction at a specified location from a species Parameters ---------- species : Species or str - the species (or name of the species) of the reaction to remove + Species (or name of the species) of the reaction to remove reaction_type : ReactionType - the reaction type (location) of the reaction to remove + Reaction type (location) of the reaction to remove """ reaction_type = ReactionType.get(reaction_type, allow_none=False) species_name = str(species_name) del self.reaction_system.reactions[reaction_type.name.lower()][species_name] def to_dict(self) -> dict: + """Dictionary representation of the MsxModel""" from wntr import __version__ return { @@ -726,12 +743,12 @@ def to_dict(self) -> dict: @classmethod def from_dict(cls, data) -> "MsxModel": - """Create a new multispecies reaction model from a dictionary. + """Create a new multi-species water quality model from a dictionary Parameters ---------- data : dict - The model data + Model data """ from wntr import __version__ diff --git a/wntr/msx/options.py b/wntr/msx/options.py index e99645352..70bed47f2 100644 --- a/wntr/msx/options.py +++ b/wntr/msx/options.py @@ -1,5 +1,7 @@ # coding: utf-8 -"""Options for multispecies reaction models. +""" +The wntr.msx.options module includes options for multi-species water quality +models """ import logging @@ -12,7 +14,7 @@ class MsxReportOptions(_OptionsBase): """ - Options related to EPANET-MSX report outputs. + Report options """ def __init__( @@ -25,44 +27,39 @@ def __init__( links: Union[Literal["ALL"], List[str]] = None, ): """ - Options related to EPANET-MSX report outputs. + Report options Parameters ---------- report_filename : str - Provides the filename to use for outputting an EPANET report file, - by default this will be the prefix plus ".rpt". - + Filename for the EPANET-MSX report file, by default this will be + the prefix plus ".rpt". species : dict[str, bool] Output species concentrations - species_precision : dict[str, float] Output species concentrations with the specified precision - nodes : None, "ALL", or list - Output node information in report file. If a list of node names is provided, - EPANET only provides report information for those nodes. - + Output node information. If a list of node names is provided, + EPANET-MSX only provides report information for those nodes. links : None, "ALL", or list - Output link information in report file. If a list of link names is provided, - EPANET only provides report information for those links. - + Output link information. If a list of link names is provided, + EPANET-MSX only provides report information for those links. pagesize : str - Page size for EPANET report output + Page size for EPANET-MSX report output """ self.pagesize = pagesize - """The pagesize for the report""" + """Pagesize for the report""" self.report_filename = report_filename - """The prefix of the report filename (will add .rpt)""" + """Prefix of the report filename (will add .rpt)""" self.species = species if species is not None else dict() """Turn individual species outputs on and off, by default no species are output""" self.species_precision = species_precision if species_precision is not None else dict() - """Set the output precision for the concentration of a specific species""" + """Output precision for the concentration of a specific species""" self.nodes = nodes - """A list of nodes to print output for, or 'ALL' for all nodes, by default None""" + """List of nodes to print output for, or 'ALL' for all nodes, by default None""" self.links = links - """A list of links to print output for, or 'ALL' for all links, by default None""" + """List of links to print output for, or 'ALL' for all links, by default None""" def __setattr__(self, name, value): if name not in ["pagesize", "report_filename", "species", "nodes", "links", "species_precision"]: @@ -71,9 +68,7 @@ def __setattr__(self, name, value): class MsxSolverOptions(_OptionsBase): - """ - Multispecies quality model options. - """ + """Solver options""" def __init__( self, @@ -91,56 +86,73 @@ def __init__( report: MsxReportOptions = None, ): """ - Multispecies quality model options. + Solver options Parameters ---------- timestep : int >= 1 Water quality timestep (seconds), by default 60 (one minute). area_units : str, optional - The units of area to use in surface concentration forms, by default ``M2``. Valid values are ``FT2``, ``M2``, or ``CM2``. + Units of area to use in surface concentration forms, by default + ``M2``. Valid values are ``FT2``, ``M2``, or ``CM2``. rate_units : str, optional - The time units to use in all rate reactions, by default ``MIN``. Valid values are ``SEC``, ``MIN``, ``HR``, or ``DAY``. + Time units to use in all rate reactions, by default ``MIN``. Valid + values are ``SEC``, ``MIN``, ``HR``, or ``DAY``. solver : str, optional - The solver to use, by default ``RK5``. Options are ``RK5`` (5th order Runge-Kutta method), ``ROS2`` (2nd order Rosenbrock method), or ``EUL`` (Euler method). + Solver to use, by default ``RK5``. Options are ``RK5`` (5th order + Runge-Kutta method), ``ROS2`` (2nd order Rosenbrock method), or + ``EUL`` (Euler method). coupling : str, optional - Use coupling method for solution, by default ``NONE``. Valid options are ``FULL`` or ``NONE``. + Use coupling method for solution, by default ``NONE``. Valid + options are ``FULL`` or ``NONE``. atol : float, optional - Absolute concentration tolerance, by default 0.01 (regardless of species concentration units). + Absolute concentration tolerance, by default 0.01 (regardless of + species concentration units). rtol : float, optional Relative concentration tolerance, by default 0.001 (±0.1%). compiler : str, optional - Whether to use a compiler, by default ``NONE``. Valid options are ``VC``, ``GC``, or ``NONE`` + Whether to use a compiler, by default ``NONE``. Valid options are + ``VC``, ``GC``, or ``NONE`` segments : int, optional - Maximum number of segments per pipe (MSX 2.0 or newer only), by default 5000. + Maximum number of segments per pipe (MSX 2.0 or newer only), by + default 5000. peclet : int, optional - Peclet threshold for applying dispersion (MSX 2.0 or newer only), by default 1000. - report : ReportOptions or dict + Peclet threshold for applying dispersion (MSX 2.0 or newer only), + by default 1000. + report : MsxReportOptions or dict Options on how to report out results. """ self.timestep: int = timestep - """The timestep, in seconds, by default 360""" + """Timestep, in seconds, by default 360""" self.area_units: str = area_units - """The units used to express pipe wall surface area where, by default FT2. Valid values are FT2, M2, and CM2.""" + """Units used to express pipe wall surface area where, by default FT2. + Valid values are FT2, M2, and CM2.""" self.rate_units: str = rate_units - """The units in which all reaction rate terms are expressed, by default HR. Valid values are HR, MIN, SEC, and DAY.""" + """Units in which all reaction rate terms are expressed, by default HR. + Valid values are HR, MIN, SEC, and DAY.""" self.solver: str = solver - """The solver to use, by default EUL. Valid values are EUL, RK5, and ROS2.""" + """Solver to use, by default EUL. Valid values are EUL, RK5, and + ROS2.""" self.coupling: str = coupling - """Whether coupling should occur during solving, by default NONE. Valid values are NONE and FULL.""" + """Whether coupling should occur during solving, by default NONE. Valid + values are NONE and FULL.""" self.rtol: float = rtol - """The relative tolerance used during solvers ROS2 and RK5, by default 0.001 for all species. Can be overridden on a per-species basis.""" + """Relative tolerance used during solvers ROS2 and RK5, by default + 0.001 for all species. Can be overridden on a per-species basis.""" self.atol: float = atol - """The absolute tolerance used by the solvers, by default 0.01 for all species regardless of concentration units. Can be overridden on a per-species basis.""" + """Absolute tolerance used by the solvers, by default 0.01 for all + species regardless of concentration units. Can be overridden on a + per-species basis.""" self.compiler: str = compiler - """A compier to use if the equations should be compiled by EPANET-MSX, by default NONE. Valid options are VC, GC and NONE.""" + """Compiler to use if the equations should be compiled by EPANET-MSX, + by default NONE. Valid options are VC, GC and NONE.""" self.segments: int = segments - """The number of segments per-pipe to use, by default 5000.""" + """Number of segments per-pipe to use, by default 5000.""" self.peclet: int = peclet - """The threshold for applying dispersion, by default 1000.""" + """Threshold for applying dispersion, by default 1000.""" self.report: MsxReportOptions = MsxReportOptions.factory(report) - """The reporting output options.""" + """Reporting output options.""" def __setattr__(self, name, value): if name == "report": @@ -163,7 +175,7 @@ def __setattr__(self, name, value): except ValueError: raise ValueError("%s must be a number", name) elif name not in ["area_units", "rate_units", "solver", "coupling", "compiler"]: - raise ValueError("%s is not a valid member of MultispeciesOptions") + raise ValueError("%s is not a valid member of MsxSolverOptions") self.__dict__[name] = value def to_dict(self): diff --git a/wntr/network/base.py b/wntr/network/base.py index 20ddc94eb..7dcf3ae8b 100644 --- a/wntr/network/base.py +++ b/wntr/network/base.py @@ -245,7 +245,8 @@ def tag(self, tag): @property def initial_quality(self): - """float or dict: The initial quality (concentration) at the node, or a dict of species-->quality for multispecies quality""" + """float or dict: Initial quality (concentration) at the node, or + a dict of species-->quality for multi-species quality""" if not self._initial_quality: return 0.0 return self._initial_quality @@ -257,7 +258,7 @@ def initial_quality(self, value): @property def coordinates(self): - """tuple: The node coordinates, (x,y)""" + """tuple: Node coordinates, (x,y)""" return self._coordinates @coordinates.setter def coordinates(self, coordinates): diff --git a/wntr/tests/test_msx_elements.py b/wntr/tests/test_msx_elements.py index 39cc09188..e65f796f3 100644 --- a/wntr/tests/test_msx_elements.py +++ b/wntr/tests/test_msx_elements.py @@ -157,7 +157,7 @@ def test_Reaction(self): self.assertEqual(formula1.expression, "-Ka + Kb * Cl + T0") self.assertEqual(formula1.expression_type, wntr.msx.ExpressionType.FORMULA) - def test_WaterQualityReactionsModel_creation_specific_everything(self): + def test_MsxModel_creation_specific_everything(self): rxn_model1 = wntr.msx.MsxModel() bulk1 = wntr.msx.Species("Cl", 'b', "mg") wall1 = wntr.msx.Species("ClOH", 'w', "mg", 0.01, 0.0001, note="Testing stuff") diff --git a/wntr/utils/disjoint_mapping.py b/wntr/utils/disjoint_mapping.py index 27dc32c34..fd2572bf8 100644 --- a/wntr/utils/disjoint_mapping.py +++ b/wntr/utils/disjoint_mapping.py @@ -1,7 +1,8 @@ # coding: utf-8 -"""A set of utility classes that is similar to the 'registry' objects in the wntr.network -class, but more general, and therefore usable for other extensions, such as multispecies -reaction modeling. +""" +A set of utility classes that is similar to the 'registry' objects in the wntr.network +class, but more general, and therefore usable for other extensions, such as multi-species +water quality models. """ from collections.abc import MutableMapping @@ -10,13 +11,11 @@ class WrongGroupError(KeyError): """The key exists but is in a different disjoint group""" - pass class KeyExistsError(KeyError): - """The name already exists in the reaction model""" - + """The name already exists in the model""" pass From 9bc4140ffc9b60ae3f191ee6d83b1993c39efe01 Mon Sep 17 00:00:00 2001 From: Katherine Klise Date: Fri, 10 Nov 2023 13:20:45 -0800 Subject: [PATCH 46/75] API docs update, removed excess imports, removed cite_msx (#136) * Add scheduled testing to workflow * MSX documentation update * minor updates * API docs update, removed excess imports, removed cite_msx --------- Co-authored-by: Kirk Bonney <47759761+kbonney@users.noreply.github.com> --- documentation/advancedqual.rst | 408 ------------------ documentation/reference.rst | 6 +- wntr/epanet/exceptions.py | 5 +- wntr/epanet/msx/__init__.py | 18 +- wntr/epanet/msx/enums.py | 143 +++--- wntr/epanet/msx/exceptions.py | 75 ++-- wntr/epanet/msx/io.py | 30 +- wntr/epanet/msx/toolkit.py | 267 ++++++------ wntr/msx/__init__.py | 8 +- .../msx/_library_data/arsenic_chloramine.json | 4 +- .../_library_data/batch_chloramine_decay.json | 2 +- wntr/msx/_library_data/lead_ppm.json | 2 +- wntr/msx/_library_data/nicotine.json | 2 +- wntr/msx/_library_data/nicotine_ri.json | 2 +- wntr/msx/base.py | 232 +++++----- wntr/msx/elements.py | 248 ++++++----- wntr/msx/library.py | 140 +++--- wntr/msx/model.py | 269 ++++++------ wntr/msx/options.py | 102 +++-- wntr/network/base.py | 5 +- wntr/tests/test_msx_elements.py | 2 +- wntr/utils/disjoint_mapping.py | 11 +- 22 files changed, 834 insertions(+), 1147 deletions(-) delete mode 100644 documentation/advancedqual.rst diff --git a/documentation/advancedqual.rst b/documentation/advancedqual.rst deleted file mode 100644 index b144cbb38..000000000 --- a/documentation/advancedqual.rst +++ /dev/null @@ -1,408 +0,0 @@ -.. raw:: latex - - \clearpage - -.. _advanced_simulation: - -Advanced water quality techniques -================================= - -This section describes several advanced simulation techniques using WNTR with MSX. - - - -.. _msx_example1_lead: - -Example 1: plumbosolvency of lead ---------------------------------- - -This model is described in [BWMS20]_, and represents plumbosolvency of lead in lead pipes -within a dwelling. -In this case, we will not assume that a water network model has been made for the dwelling, yet. - -Model creation -~~~~~~~~~~~~~~ - -We create a new model, give it a name, title, and description, and we add the reference -for the paper this model was described in. - -.. doctest:: - - >>> import wntr.msx - >>> msx = wntr.msx.MultispeciesQualityModel() - >>> msx.name = "lead_ppm" - >>> msx.title = "Lead Plumbosolvency Model (from Burkhardt et al 2020)" - >>> msx.desc = "Parameters for EPA HPS Simulator Model" - >>> msx.references.append( - ... """J. B. Burkhardt, et al. (2020) https://doi.org/10.1061/(asce)wr.1943-5452.0001304""" - ... ) - >>> msx - MultispeciesQualityModel(name='lead_ppm') - -Next, we will update certain options. - -.. doctest:: - - >>> msx.options = { - ... "report": { - ... "species": {"PB2": "YES"}, - ... "species_precision": {"PB2": 5}, - ... "nodes": "all", - ... "links": "all", - ... }, - ... "timestep": 1, - ... "area_units": "M2", - ... "rate_units": "SEC", - ... "rtol": 1e-08, - ... "atol": 1e-08, - ... } - - -Adding variables -~~~~~~~~~~~~~~~~ -The variables that are needed for a multispecies reaction system are: species, coefficients, and terms. -These are used in expressions to define the dynamics of the reaction. All variables have at least two -attributes: their name and a note. The variable name must be a valid EPANET-MSX id, which primarily -means no spaces are permitted. However, it may be useful to ensure that the name is a valid python -variable name, so that it can be used to identify the variable in your code as well. The note can be -a string, a dictionary with the keys "pre" and "post", or an :class:`~wntr.epanet.util.ENcomment` object -(which has a "pre" and "post" attribute). See the ENcomment documentation for details on the meaning; -in this example we will use the string form of the note. - --------------- - -There is only one species defined in this model, which is dissolved lead. - -======================== =============== ================================= ======================== -Name Type Units Note ------------------------- --------------- --------------------------------- ------------------------ -:math:`Pb` bulk species :math:`\mathrm{μg}_\mathrm{(Pb)}` dissolved lead -======================== =============== ================================= ======================== - -To add this species to the model, we can use the model's :meth:`~wntr.msx.multispecies.MultispeciesQualityModel.add_species` -method. -The method arguments are the name, the species_type (which can either be "bulk" or "wall"), the units, -and an optional note. -This method will add the new species to the model and also return a copy of the new species object. - -.. doctest:: - - >>> msx.add_species(name="PB2", species_type='bulk', units="ug", note="dissolved lead (Pb)") - Species(name='PB2', species_type=, units='ug', atol=None, rtol=None, note='dissolved lead (Pb)') - -The new species can be accessed by using the item's name and indexing on the model's -:attr:`~wntr.msx.multispecies.MultispeciesQualityModel.reaction_system` attribute. - - >>> PB2 = msx.reaction_system['PB2'] - >>> PB2 - Species(name='PB2', species_type=, units='ug', atol=None, rtol=None, note='dissolved lead (Pb)') - --------------- - -There are two different types of coefficients that can be used in reaction expressions: constants -and parameters. Constants have a single value in every expression. Parameters have a global value -that is used by default, but which can be modified on a per-pipe or per-tank basis. This model -has two constants and one parameter. - -=============== =============== =============== ================================= ======================== -Type Name Value Units Note ---------------- --------------- --------------- --------------------------------- ------------------------ -constant :math:`M` 0.117 :math:`\mathrm{μg~m^{-2}~s^{-1}}` desorption rate -constant :math:`E` 140.0 :math:`\mathrm{μg~L^{-1}}` saturation level -parameter :math:`F` 0 `n/a` is pipe made of lead? -=============== =============== =============== ================================= ======================== - -We can add these to the model as follows: - -.. doctest:: - - >>> msx.add_constant("M", value=0.117, note="Desorption rate (ug/m^2/s)", units="ug * m^(-2) * s^(-1)") - >>> msx.add_constant("E", value=140.0, note="saturation/plumbosolvency level (ug/L)", units="ug/L") - >>> msx.add_parameter("F", global_value=0, note="determines which pipes have reactions") - - -Adding reactions -~~~~~~~~~~~~~~~~ - -All species must have two reactions defined for the model to be run successfully in EPANET-MSX by WNTR. -One is a pipe reaction, the other is a tank reaction. In this case, we only have a reactions within -pipes, so we need to set the tank reaction to be unchanging. The system of equations is: - -.. math:: - - \frac{d}{dt}Pb_p &= F_p \, Av_p \, M \frac{\left( E - Pb_p \right)}{E}, &\quad\text{for all pipes}~p~\text{in network} \\ - \frac{d}{dt}Pb_t &= 0, & \quad\text{for all tanks}~t~\text{in network} - -Note that the pipe reaction has a variable that we have not defined, :math:`Av`, in its expression; -this variable is a pre-defined hydraulic variable. The list of these variables can be found in -the EPANET-MSX documentation, and also in the :attr:`~wntr.msx.base.HYDRAULIC_VARIABLES` -documentation. The reactions can be described in WNTR as - -================ ============== ========================================================================== -Reaction type Dynamics type Reaction expression ----------------- -------------- -------------------------------------------------------------------------- -pipe rate :math:`F \cdot Av \cdot M \cdot \left( E - Pb \right) / E` -tank rate :math:`0` -================ ============== ========================================================================== - -and then added to the reaction model using the :meth:`~wntr.msx.multispecies.MultispeciesQualityModel.add_reaction` -method. - -.. doctest:: - - >>> msx.add_reaction("PB2", "pipe", "RATE", expression="F * Av * M * (E - PB2) / E") - >>> msx.add_reaction(PB2, "tank", "rate", expression="0") - - - -Example 2: arsenic oxidation and adsorption -------------------------------------------- - -This example models monochloramine oxidation of arsenite/arsenate and wall -adsorption/desorption, as given in section 3 of the EPANET-MSX user manual [SRU23]_. -First, the model -will be restated here and then the code to create the model in wntr will be shown. - -Model Description -~~~~~~~~~~~~~~~~~ - -The system of equations for the reaction in pipes is given in Eq. (2.4) through (2.7) -in [SRU23]_. This is a simplified model, taken from [GSCL94]_. - -.. math:: - - \frac{d}{dt}{(\mathsf{As}^\mathrm{III})} &= -k_a ~ {(\mathsf{As}^\mathrm{III})} ~ {(\mathsf{NH_2Cl})} \\ - \frac{d}{dt}{(\mathsf{As}^\mathrm{V})} &= k_a ~ {(\mathsf{As}^\mathrm{III})} ~ {(\mathsf{NH_2CL})} - Av \left( k_1 \left(S_\max - {(\mathsf{As}^\mathrm{V}_s)} \right) {(\mathsf{As}^\mathrm{V})} - k_2 ~ {(\mathsf{As}^\mathrm{V}_s)} \right) \\ - \frac{d}{dt}{(\mathsf{NH_2Cl})} &= -k_b ~ {(\mathsf{NH_2Cl})} \\ - {(\mathsf{As}^\mathrm{V}_s)} &= \frac{k_s ~ S_\max ~ {(\mathsf{As}^\mathrm{V})}}{1 + k_s {(\mathsf{As}^\mathrm{V})}} - - -where the various species, coefficients, and expressions are described in the tables below. - - -.. list-table:: Options - :header-rows: 1 - :widths: 3 3 10 - - * - Option - - Code - - Description - * - Rate units - - "HR" - - :math:`\mathrm{h}^{-1}` - * - Area units - - "M2" - - :math:`\mathrm{m}^2` - - -.. list-table:: Species - :header-rows: 1 - :widths: 2 2 2 3 4 6 - - * - Name - - Type - - Value - - Symbol - - Units - - Note - * - AS3 - - Bulk - - "UG" - - :math:`{\mathsf{As}^\mathrm{III}}` - - :math:`\require{upgreek}\upmu\mathrm{g~L^{-1}}` - - dissolved arsenite - * - AS5 - - Bulk - - "UG" - - :math:`{\mathsf{As}^\mathrm{V}}` - - :math:`\require{upgreek}\upmu\mathrm{g~L^{-1}}` - - dissolved arsenate - * - AStot - - Bulk - - "UG" - - :math:`{\mathsf{As}^\mathrm{tot}}` - - :math:`\require{upgreek}\upmu\mathrm{g~L^{-1}}` - - dissolved arsenic (total) - * - NH2CL - - Bulk - - "MG" - - :math:`{\mathsf{NH_2Cl}}` - - :math:`\mathrm{mg~L^{-1}}` - - dissolved monochloramine - * - AS5s - - Wall - - "UG" - - :math:`{\mathsf{As}^\mathrm{V}_{s}}` - - :math:`\require{upgreek}\upmu\mathrm{g}~\mathrm{m}^{-2}` - - adsorped arsenate (surface) - - -.. list-table:: Coefficients - :header-rows: 1 - :widths: 2 2 2 3 4 6 - - * - Name - - Type - - Value - - Symbol - - Units - - Note - * - Ka - - Const - - :math:`10` - - :math:`k_a` - - :math:`\mathrm{mg}^{-1}_{\left(\mathsf{NH_2Cl}\right)}~\mathrm{h}^{-1}` - - arsenite oxidation - * - Kb - - Const - - :math:`0.1` - - :math:`k_b` - - :math:`\mathrm{h}^{-1}` - - chloromine decay - * - K1 - - Const - - :math:`5.0` - - :math:`k_1` - - :math:`\require{upgreek}\textrm{L}~\upmu\mathrm{g}^{-1}_{\left(\mathsf{As}^\mathrm{V}\right)}~\mathrm{h}^{-1}` - - arsenate adsorption - * - K2 - - Const - - :math:`1.0` - - :math:`k_2` - - :math:`\textrm{L}~\mathrm{h}^{-1}` - - arsenate desorption - * - Smax - - Const - - :math:`50.0` - - :math:`S_{\max}` - - :math:`\require{upgreek}\upmu\mathrm{g}_{\left(\mathsf{As}^\mathrm{V}\right)}~\mathrm{m}^{-2}` - - arsenate adsorption limit - - -.. list-table:: Other terms - :header-rows: 1 - :widths: 3 3 2 3 10 - - * - Name - - Symbol - - Expression - - Units - - Note - * - Ks - - :math:`k_s` - - :math:`{k_1}/{k_2}` - - :math:`\require{upgreek}\upmu\mathrm{g}^{-1}_{\left(\mathsf{As}^\mathrm{V}\right)}` - - equilibrium adsorption coefficient - - -.. list-table:: Pipe reactions - :header-rows: 1 - :widths: 3 3 16 - - * - Species - - Type - - Expression - * - AS3 - - Rate - - :math:`-k_a \, {\mathsf{As}^\mathrm{III}} \, {\mathsf{NH_2Cl}}` - * - AS5 - - Rate - - :math:`k_a \, {\mathsf{As}^\mathrm{III}} \, {\mathsf{NH_2Cl}} -Av \left( k_1 \left(S_{\max}-{\mathsf{As}^\mathrm{V}_{s}} \right) {\mathsf{As}^\mathrm{V}} - k_2 \, {\mathsf{As}^\mathrm{V}_{s}} \right)` - * - NH2CL - - Rate - - :math:`-k_b \, {\mathsf{NH_2Cl}}` - * - AStot - - Formula - - :math:`{\mathsf{As}^\mathrm{III}} + {\mathsf{As}^\mathrm{V}}` - * - AS5s - - Equil - - :math:`k_s \, S_{\max} \frac{{\mathsf{As}^\mathrm{V}}}{1 + k_s \, {\mathsf{As}^\mathrm{V}}} - {\mathsf{As}^\mathrm{V}_{s}}` - - -.. list-table:: Tank reactions - :header-rows: 1 - :widths: 3 3 16 - - * - Species - - Type - - Expression - * - AS3 - - Rate - - :math:`-k_a \, {\mathsf{As}^\mathrm{III}} \, {\mathsf{NH_2Cl}}` - * - AS5 - - Rate - - :math:`k_a \, {\mathsf{As}^\mathrm{III}} \, {\mathsf{NH_2Cl}}` - * - NH2CL - - Rate - - :math:`-k_b \, {\mathsf{NH_2Cl}}` - * - AStot - - Formula - - :math:`{\mathsf{As}^\mathrm{III}} + {\mathsf{As}^\mathrm{V}}` - * - AS5s - - Equil - - :math:`0` (`not present in tanks`) - - -Creation in WNTR -~~~~~~~~~~~~~~~~ - -.. doctest:: - - >>> msx = wntr.msx.MultispeciesQualityModel() - >>> msx.name = "arsenic_chloramine" - >>> msx.title = "Arsenic Oxidation/Adsorption Example" - >>> msx.references.append(wntr.msx.library.cite_msx()) - >>> AS3 = msx.add_species(name="AS3", species_type="BULK", units="UG", note="Dissolved arsenite") - >>> AS5 = msx.add_species(name="AS5", species_type="BULK", units="UG", note="Dissolved arsenate") - >>> AStot = msx.add_species(name="AStot", species_type="BULK", units="UG", note="Total dissolved arsenic") - >>> AS5s = msx.add_species(name="AS5s", species_type="WALL", units="UG", note="Adsorbed arsenate") - >>> NH2CL = msx.add_species(name="NH2CL", species_type="BULK", units="MG", note="Monochloramine") - >>> Ka = msx.add_constant("Ka", 10.0, units="1 / (MG * HR)", note="Arsenite oxidation rate coefficient") - >>> Kb = msx.add_constant("Kb", 0.1, units="1 / HR", note="Monochloramine decay rate coefficient") - >>> K1 = msx.add_constant("K1", 5.0, units="M^3 / (UG * HR)", note="Arsenate adsorption coefficient") - >>> K2 = msx.add_constant("K2", 1.0, units="1 / HR", note="Arsenate desorption coefficient") - >>> Smax = msx.add_constant("Smax", 50.0, units="UG / M^2", note="Arsenate adsorption limit") - >>> Ks = msx.add_term(name="Ks", expression="K1/K2", note="Equil. adsorption coeff.") - >>> _ = msx.add_reaction( - ... species_name="AS3", reaction_type="pipes", expression_type="rate", expression="-Ka*AS3*NH2CL", note="Arsenite oxidation" - ... ) - >>> _ = msx.add_reaction( - ... "AS5", "pipes", "rate", "Ka*AS3*NH2CL - Av*(K1*(Smax-AS5s)*AS5 - K2*AS5s)", note="Arsenate production less adsorption" - ... ) - >>> _ = msx.add_reaction( - ... species_name="NH2CL", reaction_type="pipes", expression_type="rate", expression="-Kb*NH2CL", note="Monochloramine decay" - ... ) - >>> _ = msx.add_reaction("AS5s", "pipe", "equil", "Ks*Smax*AS5/(1+Ks*AS5) - AS5s", note="Arsenate adsorption") - >>> _ = msx.add_reaction( - ... species_name="AStot", reaction_type="pipes", expression_type="formula", expression="AS3 + AS5", note="Total arsenic" - ... ) - >>> _ = msx.add_reaction( - ... species_name="AS3", reaction_type="tank", expression_type="rate", expression="-Ka*AS3*NH2CL", note="Arsenite oxidation" - ... ) - >>> _ = msx.add_reaction( - ... species_name="AS5", reaction_type="tank", expression_type="rate", expression="Ka*AS3*NH2CL", note="Arsenate production" - ... ) - >>> _ = msx.add_reaction( - ... species_name="NH2CL", reaction_type="tank", expression_type="rate", expression="-Kb*NH2CL", note="Monochloramine decay" - ... ) - >>> _ = msx.add_reaction( - ... species_name="AStot", reaction_type="tanks", expression_type="formula", expression="AS3 + AS5", note="Total arsenic" - ... ) - >>> msx.options.area_units = "M2" - >>> msx.options.rate_units = "HR" - >>> msx.options.rtol = 0.001 - >>> msx.options.atol = 0.0001 - - -References ----------- - -.. [BWMS20] - J. B. Burkhardt, et al. (2020) - "Framework for Modeling Lead in Premise Plumbing Systems Using EPANET". - `Journal of Water Resources Planning and Management`. - **146** (12). https://doi.org/10.1061/(asce)wr.1943-5452.0001304. PMID:33627937. - -.. [GSCL94] - B. Gu, J. Schmitt, Z. Chen, L. Liang, and J.F. McCarthy. "Adsorption and desorption of - natural organic matter on iron oxide: mechanisms and models". Environ. Sci. Technol., 28:38-46, January 1994. diff --git a/documentation/reference.rst b/documentation/reference.rst index 3fadfd9d5..bd638f8cf 100644 --- a/documentation/reference.rst +++ b/documentation/reference.rst @@ -10,7 +10,7 @@ References Due to limitations with cross referenced citations in reStructuredText (e.g., commas and spaces are not supported), citations are cross referenced using a 6 digit notation [*]_. -.. [ALA01] American Lifelines Alliance. (2001). Seismic Fragility Formulations for Water Systems, Part 1 and 2. Report for the American Lifelines Alliance, ASCE (Ed.) Reston, VA: American Society of Civil Engineers. April 2001. +.. [ALA01] American Lifelines Alliance. (2001). Seismic Fragility Formulations for Water Systems, Part 1 and 2. Report for the American Lifelines Alliance, ASCE (Ed.) Reston, VA: American Society of Civil Engineers. April 2001. .. [AwGB90] Awumah, K., Goulter, I., and Bhatt, S.K. (1990). Assessment of reliability in water distribution networks using entropy based measures. Stochastic Hydrology and Hydraulics, 4(4), 309-320. @@ -38,7 +38,7 @@ References .. [ICC12] International Code Council. (2011). 2012 International Fire Code, Appendix B - Fire-Flow Requirements for Buildings. Country Club Hills, IL: International Code Council, ISBN: 978-1-60983-046-5. -.. [JaSr08] Jayaram, N. and Srinivasan, K. (2008). Performance-based optimal design and rehabilitation of water distribution networks using life cycle costing. Water resources research, 44(1). +.. [JaSr08] Jayaram, N. and Srinivasan, K. (2008). Performance-based optimal design and rehabilitation of water distribution networks using life cycle costing. Water Resources Research, 44(1). .. [JCMG11] Joyner, D., Certik, O., Meurer, A., and Granger, B.E. (2012). Open source computer algebra systems, SymPy. ACM Communications in Computer Algebra, 45(4), 225-234. @@ -62,7 +62,7 @@ References .. [SPHC16] Sievert, C., Parmer, C., Hocking, T., Chamberlain, S., Ram, K., Corvellec, M., and Despouy, P. (2016). plotly: Create interactive web graphics via Plotly’s JavaScript graphing library [Software]. -.. [SRU23] Shang, F., Rossman, L. A., Uber, J.G. (2023). EPANET-MSX 2.0 User Manual. U.S. Environmental Protection Agency, Cincinnati, OH. EPA/600/R-22/199. +.. [SRU23] Shang, F., Rossman, L. A., and Uber, J.G. (2023). EPANET-MSX 2.0 User Manual. U.S. Environmental Protection Agency, Cincinnati, OH. EPA/600/R-22/199. .. [Todi00] Todini, E. (2000). Looped water distribution networks design using a resilience index based heuristic approach. Urban Water, 2(2), 115-122. diff --git a/wntr/epanet/exceptions.py b/wntr/epanet/exceptions.py index 82ce50f61..fdf405dd5 100644 --- a/wntr/epanet/exceptions.py +++ b/wntr/epanet/exceptions.py @@ -1,5 +1,8 @@ # coding: utf-8 -"""Exceptions for EPANET toolkit and IO operations.""" +""" +The wntr.epanet.expections module contains Exceptions for EPANET toolkit +and IO operations. +""" from typing import List diff --git a/wntr/epanet/msx/__init__.py b/wntr/epanet/msx/__init__.py index b7ae5c121..5fbc99912 100644 --- a/wntr/epanet/msx/__init__.py +++ b/wntr/epanet/msx/__init__.py @@ -1,15 +1,19 @@ -"""The wntr.epanet.msx package provides EPANET-MSX compatibility functions for WNTR. +# coding: utf-8 +""" +The wntr.epanet.msx package provides EPANET-MSX compatibility functions for +WNTR. -The following environment variable must be set, or the command `set_msx_path` must -be run prior to trying to instantiate the EPANET-MSX toolkit. +The following environment variable must be set, or the command `set_msx_path` +must be run prior to trying to instantiate the EPANET-MSX toolkit. .. envvar:: WNTR_PATH_TO_EPANETMSX - The full path to the directory where EPANET-MSX has been installed. Specifically, - the directory should contain both toolkit files, epanet2.dll and epanetmsx.dll - (or the appropriate equivalent files for your system architecture). - + The full path to the directory where EPANET-MSX has been installed. + Specifically, the directory should contain both toolkit files, epanet2.dll + and epanetmsx.dll (or the appropriate equivalent files for your system + architecture). """ + import os as _os def set_msx_path(path): diff --git a/wntr/epanet/msx/enums.py b/wntr/epanet/msx/enums.py index e2a77fead..73d7134fc 100644 --- a/wntr/epanet/msx/enums.py +++ b/wntr/epanet/msx/enums.py @@ -1,18 +1,22 @@ -"""EPANET-MSX enum types, for use in toolkit API calls.""" +# coding: utf-8 +""" +The wntr.epanet.msx.enums module contains EPANET-MSX enum types, for use in +toolkit API calls. +""" from enum import IntEnum from wntr.utils.enumtools import add_get @add_get(prefix='MSX_') class TkObjectType(IntEnum): - """The enumeration for object type used in EPANET-MSX. - + """Enumeration for object type used in EPANET-MSX. + .. warning:: These enum values start with 0. .. rubric:: Enum Members - The following enum names are defined, and, if using the :meth:`get` method, then - they are case insensitive and can be optionally prefixed with "MSX\_". + The following enum names are defined, and, if using the :meth:`get` method, + then they are case insensitive and can be optionally prefixed with "MSX\_". .. autosummary:: NODE @@ -48,14 +52,14 @@ class TkObjectType(IntEnum): @add_get(prefix='MSX_') class TkSourceType(IntEnum): - """The enumeration for source type used in EPANET-MSX. - + """Enumeration for source type used in EPANET-MSX. + .. warning:: These enum values start with -1. .. rubric:: Enum Members - The following enum names are defined, and, if using the :meth:`get` method, then - they are case insensitive and can be optionally prefixed with "MSX\_". + The following enum names are defined, and, if using the :meth:`get` method, + then they are case insensitive and can be optionally prefixed with "MSX\_". .. autosummary:: NOSOURCE @@ -78,14 +82,14 @@ class TkSourceType(IntEnum): @add_get(prefix='MSX_') class TkUnitSystem(IntEnum): - """The enumeration for the units system used in EPANET-MSX. - + """Enumeration for the units system used in EPANET-MSX. + .. warning:: These enum values start with 0. .. rubric:: Enum Members - The following enum names are defined, and, if using the :meth:`get` method, then - they are case insensitive and can be optionally prefixed with "MSX\_". + The following enum names are defined, and, if using the :meth:`get` method, + then they are case insensitive and can be optionally prefixed with "MSX\_". .. autosummary:: US @@ -99,14 +103,15 @@ class TkUnitSystem(IntEnum): @add_get(prefix='MSX_') class TkFlowUnits(IntEnum): - """The enumeration for the flow units used in EPANET-MSX (determined from EPANET INP file read in with the toolkit). - + """Enumeration for the flow units used in EPANET-MSX (determined from + EPANET INP file read in with the toolkit). + .. warning:: These enum values start with 0. .. rubric:: Enum Members - The following enum names are defined, and, if using the :meth:`get` method, then - they are case insensitive and can be optionally prefixed with "MSX\_". + The following enum names are defined, and, if using the :meth:`get` method, + then they are case insensitive and can be optionally prefixed with "MSX\_". .. autosummary:: CFS @@ -144,14 +149,14 @@ class TkFlowUnits(IntEnum): @add_get(prefix='MSX_') class TkMixType(IntEnum): - """The enumeration for the mixing model used in EPANET-MSX. - + """Enumeration for the mixing model used in EPANET-MSX. + .. warning:: These enum values start with 0. .. rubric:: Enum Members - The following enum names are defined, and, if using the :meth:`get` method, then - they are case insensitive and can be optionally prefixed with "MSX\_". + The following enum names are defined, and, if using the :meth:`get` method, + then they are case insensitive and can be optionally prefixed with "MSX\_". .. autosummary:: MIX1 @@ -171,14 +176,14 @@ class TkMixType(IntEnum): @add_get(prefix='MSX_') class TkSpeciesType(IntEnum): - """The enumeration for species type used in EPANET-MSX. + """Enumeration for species type used in EPANET-MSX. .. warning:: These enum values start with 0. .. rubric:: Enum Members - The following enum names are defined, and, if using the :meth:`get` method, then - they are case insensitive and can be optionally prefixed with "MSX\_". + The following enum names are defined, and, if using the :meth:`get` method, + then they are case insensitive and can be optionally prefixed with "MSX\_". .. autosummary:: BULK @@ -192,14 +197,14 @@ class TkSpeciesType(IntEnum): @add_get(prefix='MSX_') class TkExpressionType(IntEnum): - """The enumeration for the expression type used in EPANET-MSX. - + """Enumeration for the expression type used in EPANET-MSX. + .. warning:: These enum values start with 0. .. rubric:: Enum Members - The following enum names are defined, and, if using the :meth:`get` method, then - they are case insensitive and can be optionally prefixed with "MSX\_". + The following enum names are defined, and, if using the :meth:`get` method, + then they are case insensitive and can be optionally prefixed with "MSX\_". .. autosummary:: NO_EXPR @@ -219,14 +224,14 @@ class TkExpressionType(IntEnum): @add_get(prefix='MSX_') class TkSolverType(IntEnum): - """The enumeration for the solver type used in EPANET-MSX. - + """Enumeration for the solver type used in EPANET-MSX. + .. warning:: These enum values start with 0. .. rubric:: Enum Members - The following enum names are defined, and, if using the :meth:`get` method, then - they are case insensitive and can be optionally prefixed with "MSX\_". + The following enum names are defined, and, if using the :meth:`get` method, + then they are case insensitive and can be optionally prefixed with "MSX\_". .. autosummary:: EUL @@ -243,14 +248,14 @@ class TkSolverType(IntEnum): @add_get(prefix='MSX_') class TkCouplingType(IntEnum): - """The enumeration for the coupling type option used in EPANET-MSX. - + """Enumeration for the coupling type option used in EPANET-MSX. + .. warning:: These enum values start with 0. .. rubric:: Enum Members - The following enum names are defined, and, if using the :meth:`get` method, then - they are case insensitive and can be optionally prefixed with "MSX\_". + The following enum names are defined, and, if using the :meth:`get` method, + then they are case insensitive and can be optionally prefixed with "MSX\_". .. autosummary:: NO_COUPLING @@ -264,14 +269,14 @@ class TkCouplingType(IntEnum): @add_get(prefix='MSX_') class TkMassUnits(IntEnum): - """The enumeration for mass units used in EPANET-MSX. + """Enumeration for mass units used in EPANET-MSX. .. warning:: These enum values start with 0. .. rubric:: Enum Members - The following enum names are defined, and, if using the :meth:`get` method, then - they are case insensitive and can be optionally prefixed with "MSX\_". + The following enum names are defined, and, if using the :meth:`get` method, + then they are case insensitive and can be optionally prefixed with "MSX\_". .. autosummary:: MG @@ -291,14 +296,14 @@ class TkMassUnits(IntEnum): @add_get(prefix='MSX_') class TkAreaUnits(IntEnum): - """The enumeration for area units used in EPANET-MSX. - + """Enumeration for area units used in EPANET-MSX. + .. warning:: These enum values start with 0. .. rubric:: Enum Members - The following enum names are defined, and, if using the :meth:`get` method, then - they are case insensitive and can be optionally prefixed with "MSX\_". + The following enum names are defined, and, if using the :meth:`get` method, + then they are case insensitive and can be optionally prefixed with "MSX\_". .. autosummary:: FT2 @@ -315,14 +320,14 @@ class TkAreaUnits(IntEnum): @add_get(prefix='MSX_') class TkRateUnits(IntEnum): - """The enumeration for rate units used in EPANET-MSX. - + """Enumeration for rate units used in EPANET-MSX. + .. warning:: These enum values start with 0. .. rubric:: Enum Members - The following enum names are defined, and, if using the :meth:`get` method, then - they are case insensitive and can be optionally prefixed with "MSX\_". + The following enum names are defined, and, if using the :meth:`get` method, + then they are case insensitive and can be optionally prefixed with "MSX\_". .. autosummary:: SECONDS @@ -342,14 +347,14 @@ class TkRateUnits(IntEnum): @add_get(prefix='MSX_') class TkUnits(IntEnum): - """The position for units used in EPANET-MSX. - + """Position for units used in EPANET-MSX. + .. warning:: These enum values start with 0. .. rubric:: Enum Members - The following enum names are defined, and, if using the :meth:`get` method, then - they are case insensitive and can be optionally prefixed with "MSX\_". + The following enum names are defined, and, if using the :meth:`get` method, + then they are case insensitive and can be optionally prefixed with "MSX\_". .. autosummary:: LENGTH_UNITS @@ -379,14 +384,14 @@ class TkUnits(IntEnum): @add_get(prefix='MSX_') class TkHydVar(IntEnum): - """The enumeration for hydraulic variable used in EPANET-MSX. + """Enumeration for hydraulic variable used in EPANET-MSX. .. warning:: These enum values start with 0. .. rubric:: Enum Members - The following enum names are defined, and, if using the :meth:`get` method, then - they are case insensitive and can be optionally prefixed with "MSX\_". + The following enum names are defined, and, if using the :meth:`get` method, + then they are case insensitive and can be optionally prefixed with "MSX\_". .. autosummary:: DIAMETER @@ -422,14 +427,14 @@ class TkHydVar(IntEnum): @add_get(prefix='MSX_') class TkTstat(IntEnum): - """The enumeration used for time statistic in EPANET-MSX. - + """Enumeration used for time statistic in EPANET-MSX. + .. warning:: These enum values start with 0. .. rubric:: Enum Members - The following enum names are defined, and, if using the :meth:`get` method, then - they are case insensitive and can be optionally prefixed with "MSX\_". + The following enum names are defined, and, if using the :meth:`get` method, + then they are case insensitive and can be optionally prefixed with "MSX\_". .. autosummary:: SERIES @@ -452,14 +457,14 @@ class TkTstat(IntEnum): @add_get(prefix='MSX_') class TkOption(IntEnum): - """The enumeration used for choosing an option in EPANET-MSX toolkit. + """Enumeration used for choosing an option in EPANET-MSX toolkit. .. warning:: These enum values start with 0. .. rubric:: Enum Members - The following enum names are defined, and, if using the :meth:`get` method, then - they are case insensitive and can be optionally prefixed with "MSX\_". + The following enum names are defined, and, if using the :meth:`get` method, + then they are case insensitive and can be optionally prefixed with "MSX\_". .. autosummary:: AREA_UNITS_OPTION @@ -497,14 +502,14 @@ class TkOption(IntEnum): @add_get(prefix='MSX_') class TkCompiler(IntEnum): - """The enumeration used for specifying compiler options in EPANET-MSX. - + """Enumeration used for specifying compiler options in EPANET-MSX. + .. warning:: These enum values start with 0. .. rubric:: Enum Members - The following enum names are defined, and, if using the :meth:`get` method, then - they are case insensitive and can be optionally prefixed with "MSX\_". + The following enum names are defined, and, if using the :meth:`get` method, + then they are case insensitive and can be optionally prefixed with "MSX\_". .. autosummary:: NO_COMPILER @@ -521,14 +526,14 @@ class TkCompiler(IntEnum): @add_get(prefix='MSX_') class TkFileMode(IntEnum): - """The enumeration for file model used in EPANET-MSX. - + """Enumeration for file model used in EPANET-MSX. + .. warning:: These enum values start with 0. .. rubric:: Enum Members - The following enum names are defined, and, if using the :meth:`get` method, then - they are case insensitive and can be optionally prefixed with "MSX\_". + The following enum names are defined, and, if using the :meth:`get` method, + then they are case insensitive and can be optionally prefixed with "MSX\_". .. autosummary:: SCRATCH_FILE diff --git a/wntr/epanet/msx/exceptions.py b/wntr/epanet/msx/exceptions.py index 2ed33e506..a1dcc6ee4 100644 --- a/wntr/epanet/msx/exceptions.py +++ b/wntr/epanet/msx/exceptions.py @@ -1,12 +1,12 @@ # coding: utf-8 -"""EPANET-MSX error and exception classes.""" +""" +The wntr.epanet.msx.exceptions module contains Exceptions for EPANET-MSX +IO operations. +""" -from enum import IntEnum from typing import List -from wntr.utils.enumtools import add_get - -from ..exceptions import EN_ERROR_CODES, EpanetException +from ..exceptions import EpanetException MSX_ERROR_CODES = { # MSX syntax errors @@ -52,21 +52,25 @@ :meta hide-value: """ + class EpanetMsxException(EpanetException): - def __init__(self, code: int, *args: List[object], line_num=None, line=None) -> None: - """An Exception class for EPANET-MSX Toolkit and IO exceptions. + def __init__(self, code: int, *args: List[object], line_num=None, + line=None) -> None: + """Exception class for EPANET-MSX Toolkit and IO exceptions Parameters ---------- code : int or str or MSXErrors - The EPANET-MSX error code (int) or a string mapping to the MSXErrors enum members + EPANET-MSX error code (int) or a string mapping to the MSXErrors + enum members args : additional non-keyword arguments, optional - If there is a string-format within the error code's text, these will be used to - replace the format, otherwise they will be output at the end of the Exception message. + If there is a string-format within the error code's text, these + will be used to replace the format, otherwise they will be output + at the end of the Exception message. line_num : int, optional - The line number, if reading an INP file, by default None + Line number, if reading an INP file, by default None line : str, optional - The contents of the line, by default None + Contents of the line, by default None """ if not code or int(code) < 400: return super().__init__(code, *args, line_num=line_num, line=line) @@ -87,61 +91,68 @@ def __init__(self, code: int, *args: List[object], line_num=None, line=None) -> class MSXSyntaxError(EpanetMsxException, SyntaxError): def __init__(self, code, *args, line_num=None, line=None) -> None: - """An MSX-specific error that is due to a syntax error in an msx-file. + """MSX-specific error that is due to a syntax error in an msx-file. Parameters ---------- code : int or str or MSXErrors - The EPANET-MSX error code (int) or a string mapping to the MSXErrors enum members + EPANET-MSX error code (int) or a string mapping to the MSXErrors + enum members args : additional non-keyword arguments, optional - If there is a string-format within the error code's text, these will be used to - replace the format, otherwise they will be output at the end of the Exception message. + If there is a string-format within the error code's text, these + will be used to replace the format, otherwise they will be output + at the end of the Exception message. line_num : int, optional - The line number, if reading an INP file, by default None + Line number, if reading an INP file, by default None line : str, optional - The contents of the line, by default None + Contents of the line, by default None """ super().__init__(code, *args, line_num=line_num, line=line) class MSXKeyError(EpanetMsxException, KeyError): def __init__(self, code, name, *args, line_num=None, line=None) -> None: - """An MSX-specific error that is due to a missing or unacceptably named variable/speces/etc. + """MSX-specific error that is due to a missing or unacceptably named + variable/speces/etc. Parameters ---------- code : int or str or MSXErrors - The EPANET-MSX error code (int) or a string mapping to the MSXErrors enum members + EPANET-MSX error code (int) or a string mapping to the MSXErrors + enum members name : str - The key/name/id that is missing + Key/name/id that is missing args : additional non-keyword arguments, optional - If there is a string-format within the error code's text, these will be used to - replace the format, otherwise they will be output at the end of the Exception message. + If there is a string-format within the error code's text, these + will be used to replace the format, otherwise they will be output + at the end of the Exception message. line_num : int, optional - The line number, if reading an INP file, by default None + Line number, if reading an INP file, by default None line : str, optional - The contents of the line, by default None + Contents of the line, by default None """ super().__init__(code, name, *args, line_num=line_num, line=line) class MSXValueError(EpanetMsxException, ValueError): def __init__(self, code, value, *args, line_num=None, line=None) -> None: - """An MSX-specific error that is related to an invalid value. + """MSX-specific error that is related to an invalid value. Parameters ---------- code : int or str or MSXErrors - The EPANET-MSX error code (int) or a string mapping to the MSXErrors enum members + EPANET-MSX error code (int) or a string mapping to the MSXErrors + enum members value : Any - The value that is invalid + Value that is invalid args : additional non-keyword arguments, optional - If there is a string-format within the error code's text, these will be used to - replace the format, otherwise they will be output at the end of the Exception message. + If there is a string-format within the error code's text, these + will be used to replace the format, otherwise they will be output + at the end of the Exception message. line_num : int, optional - The line number, if reading an INP file, by default None + Line number, if reading an INP file, by default None line : str, optional - The contents of the line, by default None + Contents of the line, by default None """ super().__init__(code, value, *args, line_num=line_num, line=line) diff --git a/wntr/epanet/msx/io.py b/wntr/epanet/msx/io.py index e1a87ae31..fc271d30e 100644 --- a/wntr/epanet/msx/io.py +++ b/wntr/epanet/msx/io.py @@ -1,5 +1,8 @@ # coding: utf-8 -"""I/O functions for EPANET-MSX toolkit compatibility""" +""" +The wntr.epanet.msx io module contains methods for reading/writing EPANET +MSX input and output files. +""" import datetime import logging @@ -13,8 +16,7 @@ import wntr.network from wntr.epanet.msx.exceptions import EpanetMsxException, MSXValueError from wntr.epanet.util import ENcomment -from wntr.network.elements import Source -from wntr.msx.base import ReactionType, VariableType, SpeciesType +from wntr.msx.base import VariableType, SpeciesType from wntr.msx.model import MsxModel sys_default_enc = sys.getdefaultencoding() @@ -79,20 +81,22 @@ def __init__(self): @classmethod def read(cls, msx_filename: str, rxn_model: MsxModel = None): """ - Read an EPANET-MSX input file (.msx) and load data into a water quality - reactions model. Only MSX 2.0 files are recognized. + Read an EPANET-MSX input file (.msx) and load data into a MsxModel. + Only MSX 2.0 files are recognized. Parameters ---------- msx_file : str - the filename of the .msx file to read in - rxn_model : WaterQualityReactionsModel, optional - the model to put data into, by default None (new model) + Filename of the .msx file to read in + rxn_model : MsxModel, optional + Multi-species water quality model to put data into, + by default None (new model) Returns ------- - WaterQualityReactionsModel - the model with the new species, reactions and other options added + MsxModel + Multi-species water quality model with the new species, reactions + and other options added """ if rxn_model is None: rxn_model = MsxModel() @@ -180,9 +184,9 @@ def write(cls, filename: str, msx: MsxModel): Parameters ---------- filename : str - the filename to write - rxn : MultispeciesQualityModel - the multispecies reaction model + Filename to write + rxn : MsxModel + Multi-species water quality model """ obj = cls() obj.rxn = msx diff --git a/wntr/epanet/msx/toolkit.py b/wntr/epanet/msx/toolkit.py index 20aea7cd8..e7ffdd78e 100644 --- a/wntr/epanet/msx/toolkit.py +++ b/wntr/epanet/msx/toolkit.py @@ -1,18 +1,18 @@ +# coding: utf-8 """ -The wntr.reaction.toolkit module is a Python extension for the EPANET MSX +The wntr.epanet.msx.toolkit module is a Python extension for the EPANET-MSX Programmers Toolkit DLLs. .. note:: - Code in this section based on code from "EPANET-MSX-Python-wrapper", - licensed under the BSD license. See LICENSE.txt for details. + Code in this section is based on code from "EPANET-MSX-Python-wrapper", + licensed under the BSD license. See LICENSE.md for details. """ import ctypes import os import os.path import platform import sys -from ctypes import byref from typing import Union from pkg_resources import resource_filename @@ -20,7 +20,6 @@ from wntr.epanet.msx.enums import TkObjectType, TkSourceType from ..toolkit import ENepanet -from ..util import SizeLimits from .exceptions import MSX_ERROR_CODES, EpanetMsxException, MSXKeyError, MSXValueError epanet_toolkit = "wntr.epanet.toolkit" @@ -119,14 +118,14 @@ def _error(self, *args): raise EpanetMsxException(self.errcode) return - # ----------running the simulation----------------------------------------------------- + # ----------running the simulation----------------------------------------- def MSXopen(self, msxfile): """Opens the MSX Toolkit to analyze a particular distribution system. Parameters ---------- msxfile : str - name of the MSX input file + Name of the MSX input file """ if msxfile is not None: msxfile = ctypes.c_char_p(msxfile.encode()) @@ -141,7 +140,8 @@ def MSXclose(self): raise EpanetMsxException(ierr) def MSXusehydfile(self, filename): - """Uses the contents of the specified file as the current binary hydraulics file + """Uses the contents of the specified file as the current binary + hydraulics file Parameters ---------- @@ -160,22 +160,25 @@ def MSXsolveH(self): raise EpanetMsxException(ierr) def MSXinit(self, saveFlag=0): - """Initializes the MSX system before solving for water quality results in step-wise fashion - set saveFlag to 1 if water quality results should be saved to a scratch binary file, or to 0 is not saved to file""" + """Initializes the MSX system before solving for water quality results + in step-wise fashion set saveFlag to 1 if water quality results should + be saved to a scratch binary file, or to 0 is not saved to file""" saveFlag = int(saveFlag) ierr = self.ENlib.MSXinit(saveFlag) if ierr != 0: raise EpanetMsxException(ierr) def MSXsolveQ(self): - """solves for water quality over the entire simulation period and saves the results to an internal scratch file""" + """Solves for water quality over the entire simulation period and saves + the results to an internal scratch file""" ierr = self.ENlib.MSXsolveQ() if ierr != 0: raise EpanetMsxException(ierr) def MSXstep(self): """Advances the water quality simulation one water quality time step. - The time remaining in the overall simulation is returned as tleft, the current time as t.""" + The time remaining in the overall simulation is returned as tleft, the + current time as t.""" t = ctypes.c_long() tleft = ctypes.c_long() ierr = self.ENlib.MSXstep(ctypes.byref(t), ctypes.byref(tleft)) @@ -185,8 +188,9 @@ def MSXstep(self): return out def MSXsaveoutfile(self, filename): - """saves water quality results computed for each node, link and reporting time period to a named binary file - + """Saves water quality results computed for each node, link and + reporting time period to a named binary file + Parameters ---------- filename : str @@ -197,45 +201,47 @@ def MSXsaveoutfile(self, filename): raise EpanetMsxException(ierr) def MSXsavemsxfile(self, filename): - """saves the data associated with the current MSX project into a new MSX input file - + """Saves the data associated with the current MSX project into a new + MSX input file + Parameters ---------- filename : str - the name of the MSX input file to create + Name of the MSX input file to create """ ierr = self.ENlib.MSXsavemsxfile(ctypes.c_char_p(filename.encode())) if ierr != 0: raise EpanetMsxException(ierr, filename) def MSXreport(self): - """Writes water quality simulations results as instructed by the MSX input file to a text file""" + """Writes water quality simulations results as instructed by the MSX + input file to a text file""" ierr = self.ENlib.MSXreport() if ierr != 0: raise EpanetMsxException(ierr) - # ---------get parameters--------------------------------------------------------------- + # ---------get parameters-------------------------------------------------- def MSXgetindex(self, _type: Union[int, TkObjectType], name): - """Retrieves the internal index of an MSX object given its name. + """Gets the internal index of an MSX object given its name. Parameters ---------- _type : int, str or ObjectType - The type of object to get an index for + Type of object to get an index for name : str - The name of the object to get an index for + Name of the object to get an index for Returns ------- int - The internal index + Internal index Raises ------ MSXKeyError - if an invalid str is passed for _type + If an invalid str is passed for _type MSXValueError - if _type is not a valid MSX object type + If _type is not a valid MSX object type """ try: _type = TkObjectType.get(_type) @@ -249,19 +255,20 @@ def MSXgetindex(self, _type: Union[int, TkObjectType], name): return ind.value def MSXgetIDlen(self, _type, index): - """Retrieves the number of characters in the ID name of an MSX object given its internal index number. + """Get the number of characters in the ID name of an MSX object + given its internal index number. Parameters ---------- _type : int, str or ObjectType - The type of object to get an index for - index : int - The index of the object to get the ID length for + Type of object to get an index for + index : int + Index of the object to get the ID length for Returns ------- int - the length of the object ID + Length of the object ID """ try: _type = TkObjectType.get(_type) @@ -275,19 +282,19 @@ def MSXgetIDlen(self, _type, index): return len.value def MSXgetID(self, _type, index): - """Retrieves the ID name of an object given its internal index number + """Get the ID name of an object given its internal index number Parameters ---------- _type : int, str or ObjectType - The type of object to get an index for - index : int - The index of the object to get the ID for + Type of object to get an index for + index : int + Index of the object to get the ID for Returns ------- str - the object ID + Object ID """ try: _type = TkObjectType.get(_type) @@ -303,31 +310,31 @@ def MSXgetID(self, _type, index): return id.value.decode() def MSXgetinitqual(self, _type, node_link_index, species_index): - """Retrieves the initial concentration of a particular chemical species assigned to a specific node - or link of the pipe network + """Get the initial concentration of a particular chemical species + assigned to a specific node or link of the pipe network Parameters ---------- _type : str, int or ObjectType - the type of object + Type of object node_link_index : int - the object index + Object index species_index : int - the species index + Species index Returns ------- float - the initial quality value for that node or link + Initial quality value for that node or link Raises ------ MSXKeyError - the type passed in for ``_type`` is not valid + Type passed in for ``_type`` is not valid MSXValueError - the value for ``_type`` is not valid + Value for ``_type`` is not valid EpanetMsxException - any other error from the C-API + Any other error from the C-API """ try: _type = TkObjectType.get(_type) @@ -343,30 +350,31 @@ def MSXgetinitqual(self, _type, node_link_index, species_index): return iniqual.value def MSXgetqual(self, _type, node_link_index, species_index): - """Retrieves a chemical species concentration at a given node or the average concentration along a link at the current simulation time step + """Get a chemical species concentration at a given node or the + average concentration along a link at the current simulation time step Parameters ---------- _type : str, int or ObjectType - the type of object + Type of object node_link_index : int - the object index + Object index species_index : int - the species index + Species index Returns ------- float - the current quality value for that node or link + Current quality value for that node or link Raises ------ MSXKeyError - the type passed in for ``_type`` is not valid + Type passed in for ``_type`` is not valid MSXValueError - the value for ``_type`` is not valid + Value for ``_type`` is not valid EpanetMsxException - any other error from the C-API + Any other error from the C-API """ try: _type = TkObjectType.get(_type) @@ -382,22 +390,22 @@ def MSXgetqual(self, _type, node_link_index, species_index): return qual.value def MSXgetconstant(self, constant_index): - """Retrieves the value of a particular reaction constant + """Get the value of a particular reaction constant Parameters ---------- constant_index : int - index to the constant + Index to the constant Returns ------- float - the value of the constant + Value of the constant Raises ------ EpanetMsxException - a toolkit error occurred + Toolkit error occurred """ const = ctypes.c_double() ierr = self.ENlib.MSXgetconstant(constant_index, ctypes.byref(const)) @@ -406,30 +414,31 @@ def MSXgetconstant(self, constant_index): return const.value def MSXgetparameter(self, _type, node_link_index, param_index): - """Retrieves the value of a particular reaction parameter for a given TANK or PIPE. + """Get the value of a particular reaction parameter for a given + TANK or PIPE. Parameters ---------- _type : int or str or Enum - get the type of the parameter + Get the type of the parameter node_link_index : int - the link index + Link index param_index : int - the parameter variable index + Parameter variable index Returns ------- float - the parameter value + Parameter value Raises ------ MSXKeyError - if there is no such _type + If there is no such _type MSXValueError - if the _type is improper + If the _type is improper EpanetMsxException - any other error + Any other error """ try: _type = TkObjectType.get(_type) @@ -445,10 +454,24 @@ def MSXgetparameter(self, _type, node_link_index, param_index): return param.value def MSXgetsource(self, node_index, species_index): - """Retrieves information on any external source of a particular chemical species assigned to a specific node of the pipe network + """Get information on any external source of a particular + chemical species assigned to a specific node of the pipe network + + Parameters + ---------- + node_index : int + Node index + species_index : int + Species index + + Returns + ------- + list + [source type, level, and pattern] where level is the baseline + concentration (or mass flow rate) of the source and pattern the + index of the time pattern used to add variability to the source's + baseline level (0 if no pattern defined for the source) """ - #level is returned with the baseline concentration (or mass flow rate) of the source - #pat is returned with the index of the time pattern used to add variability to the source's baseline level (0 if no pattern defined for the source)""" level = ctypes.c_double() _type = ctypes.c_int() pat = ctypes.c_int() @@ -459,17 +482,17 @@ def MSXgetsource(self, node_index, species_index): return src_out def MSXgetpatternlen(self, pat): - """Retrieves the number of time periods within a SOURCE time pattern. + """Get the number of time periods within a SOURCE time pattern. Parameters ---------- pat : int - pattern index + Pattern index Returns ------- int - number of time periods in the pattern + Number of time periods in the pattern """ len = ctypes.c_int() ierr = self.ENlib.MSXgetpatternlen(pat, ctypes.byref(len)) @@ -478,19 +501,19 @@ def MSXgetpatternlen(self, pat): return len.value def MSXgetpatternvalue(self, pat, period): - """Retrieves the multiplier at a specific time period for a given SOURCE time pattern + """Get the multiplier at a specific time period for a given + SOURCE time pattern Parameters ---------- pat : int - pattern index + Pattern index period : int 1-indexed period of the pattern to retrieve Returns ------- - float - the multiplier + Multiplier """ val = ctypes.c_double() ierr = self.ENlib.MSXgetpatternvalue(pat, period, ctypes.byref(val)) @@ -499,22 +522,22 @@ def MSXgetpatternvalue(self, pat, period): return val.value def MSXgetcount(self, _type): - """Retrieves the number of objects of a specified type. + """Get the number of objects of a specified type. Parameters ---------- _type : int or str or Enum - the type of object to count + Type of object to count Returns ------- int - the number of objects of specified type + Number of objects of specified type Raises ------ MSXKeyError - if the _type is invalid + If the _type is invalid """ try: _type = TkObjectType.get(_type) @@ -528,18 +551,19 @@ def MSXgetcount(self, _type): return count.value def MSXgetspecies(self, species_index): - """Retrieves the attributes of a chemical species given its internal index number. - species is the sequence number of the species (starting from 1 as listed in the MSX input file + """Get the attributes of a chemical species given its internal + index number. Parameters ---------- species_index : int - the species to query + Species index to query (starting from 1 as listed in the MSX input + file) Returns ------- int, str, float, float - the type, units, aTol, and rTol for the species + Type, units, aTol, and rTol for the species """ type_ind = ctypes.c_int() units = ctypes.create_string_buffer(15) @@ -552,25 +576,25 @@ def MSXgetspecies(self, species_index): return spe_out def MSXgeterror(self, errcode, len=100): - """returns the text for an error message given its error code + """Get the text for an error message given its error code Parameters ---------- errcode : int - the error code + Error code len : int, optional - the length of the error message, by default 100 and minimum 80 + Length of the error message, by default 100 and minimum 80 Returns ------- str - returns a string decoded from the DLL + String decoded from the DLL Warning ------- - Getting string parameters in this way is not recommended, because it requires - setting up string arrays that may or may not be the correct size. Use the - wntr.epanet.msx.enums package to get error information. + Getting string parameters in this way is not recommended, because it + requires setting up string arrays that may or may not be the correct + size. Use the wntr.epanet.msx.enums package to get error information. """ errmsg = ctypes.create_string_buffer(len) self.ENlib.MSXgeterror(errcode, ctypes.byref(errmsg), len) @@ -579,39 +603,40 @@ def MSXgeterror(self, errcode, len=100): # --------------set parameters----------------------------------- def MSXsetconstant(self, ind, value): - """assigns a new value to a specific reaction constant + """Set a new value to a specific reaction constant Parameters ---------- ind : int - the index to the variable + Index to the variable value : float - the value to give the constant + Value to give the constant """ ierr = self.ENlib.MSXsetconstant(ctypes.c_int(ind), ctypes.c_double(value)) if ierr != 0: raise EpanetMsxException(ierr) def MSXsetparameter(self, _type, ind, param, value): - """assigns a value to a particular reaction parameter for a given TANK or PIPE + """Set a value to a particular reaction parameter for a given TANK + or PIPE Parameters ---------- _type : int or str or enum - the type of value to set + Type of value to set ind : int - the tank or pipe index + Tank or pipe index param : int - the parameter variable index + Parameter variable index value : float - the value to be set + Value to be set Raises ------ MSXKeyError - if there is no such _type + If there is no such _type MSXValueError - if the _type is invalid + If the _type is invalid """ try: _type = TkObjectType.get(_type) @@ -625,19 +650,19 @@ def MSXsetparameter(self, _type, ind, param, value): raise EpanetMsxException(ierr) def MSXsetinitqual(self, _type, ind, spe, value): - """Retrieves the initial concentration of a particular chemical species assigned to a specific node - or link of the pipe network. + """Set the initial concentration of a particular chemical species + assigned to a specific node or link of the pipe network. Parameters ---------- _type : int or str or enum - what type of network element is being set + Type of network element to set ind : int - the index of the network element + Index of the network element spe : int - the index of the species + Index of the species value : float - the initial quality value + Initial quality value """ try: _type = TkObjectType.get(_type) @@ -651,20 +676,21 @@ def MSXsetinitqual(self, _type, ind, spe, value): raise EpanetMsxException(ierr) def MSXsetsource(self, node, spe, _type, level, pat): - """sets the attributes of an external source of a particular chemical species in a specific node of the pipe network + """Set the attributes of an external source of a particular chemical + species in a specific node of the pipe network Parameters ---------- node : int - the node index + Node index spe : int - the species index + Species index _type : int or str or enum - the type of source + Type of source level : float - the source quality value + Source quality value pat : int - the pattern index + Pattern index """ try: _type = TkSourceType.get(_type) @@ -676,14 +702,14 @@ def MSXsetsource(self, node, spe, _type, level, pat): raise EpanetMsxException(ierr) def MSXsetpattern(self, pat, mult): - """assigns a new set of multipliers to a given MSX SOURCE time pattern + """Set multipliers to a given MSX SOURCE time pattern Parameters ---------- pat : int - the pattern index + Pattern index mult : list-like - the pattern multipliers + Pattern multipliers """ length = len(mult) cfactors_type = ctypes.c_double * length @@ -695,28 +721,29 @@ def MSXsetpattern(self, pat, mult): raise EpanetMsxException(ierr) def MSXsetpatternvalue(self, pat, period, value): - """Sets the multiplier factor for a specific period within a SOURCE time pattern. + """Set the multiplier factor for a specific period within a SOURCE time + pattern. Parameters ---------- pat : int - the pattern index + Pattern index period : int - the 1-indexed pattern time period index + 1-indexed pattern time period index value : float - the value to set at that time period + Value to set at that time period """ ierr = self.ENlib.MSXsetpatternvalue(ctypes.c_int(pat), ctypes.c_int(period), ctypes.c_double(value)) if ierr != 0: raise EpanetMsxException(ierr) def MSXaddpattern(self, patternid): - """Adds a new, empty MSX source time pattern to an MSX project. + """Add a new, empty MSX source time pattern to an MSX project. Parameters ---------- patternid : str - the name of the new pattern + Name of the new pattern """ ierr = self.ENlib.MSXaddpattern(ctypes.c_char_p(patternid.encode())) if ierr != 0: diff --git a/wntr/msx/__init__.py b/wntr/msx/__init__.py index e44b248fe..d563c9a97 100644 --- a/wntr/msx/__init__.py +++ b/wntr/msx/__init__.py @@ -1,11 +1,13 @@ -# -*- coding: utf-8 -*- -"""Contains definitions for EPANET Multispecies Extension (MSX) water quality modeling. +# coding: utf-8 +""" +The wntr.msx package contains methods to define EPANET Multi-species Extension +(MSX) water quality models. """ from .base import VariableType, SpeciesType, ReactionType, ExpressionType from .elements import Species, Constant, Parameter, Term, Reaction, HydraulicVariable, MathFunction from .model import MsxModel from .options import MsxSolverOptions -from .library import ReactionLibrary, cite_msx +from .library import ReactionLibrary from . import base, elements, library, model, options diff --git a/wntr/msx/_library_data/arsenic_chloramine.json b/wntr/msx/_library_data/arsenic_chloramine.json index c67e1dc13..8661afaa3 100644 --- a/wntr/msx/_library_data/arsenic_chloramine.json +++ b/wntr/msx/_library_data/arsenic_chloramine.json @@ -1,10 +1,10 @@ { - "wntr-version": "1.0.0", + "wntr-version": "", "name": "arsenic_chloramine", "title": "Arsenic Oxidation/Adsorption Example", "description": "This example models monochloramine oxidation of arsenite/arsenate and wall adsoption/desorption, as given in section 3 of the EPANET-MSX user manual", "references": [ - "Shang, F. and Rossman, L.A. and Uber, J.G. (2023) \"EPANET-MSX 2.0 User Manual\". (Cincinnati, OH: Water Infrastructure Division (CESER), U.S. Environmental Protection Agency). EPA/600/R-22/199." + "Shang, F., Rossman, L. A., and Uber, J.G. (2023). EPANET-MSX 2.0 User Manual. U.S. Environmental Protection Agency, Cincinnati, OH. EPA/600/R-22/199." ], "reaction_system": { "species": [ diff --git a/wntr/msx/_library_data/batch_chloramine_decay.json b/wntr/msx/_library_data/batch_chloramine_decay.json index fc4c416db..6563c38e0 100644 --- a/wntr/msx/_library_data/batch_chloramine_decay.json +++ b/wntr/msx/_library_data/batch_chloramine_decay.json @@ -1,5 +1,5 @@ { - "wntr-version": "1.0.0", + "wntr-version": "", "name": "batch_chloramine_decay", "title": "Batch chloramine decay example", "description": null, diff --git a/wntr/msx/_library_data/lead_ppm.json b/wntr/msx/_library_data/lead_ppm.json index 63a69e852..7d483200b 100644 --- a/wntr/msx/_library_data/lead_ppm.json +++ b/wntr/msx/_library_data/lead_ppm.json @@ -1,5 +1,5 @@ { - "wntr-version": "1.0.0", + "wntr-version": "", "name": "lead_ppm", "title": "Lead Plumbosolvency Model (from Burkhardt et al 2020)", "description": "Parameters for EPA HPS Simulator Model", diff --git a/wntr/msx/_library_data/nicotine.json b/wntr/msx/_library_data/nicotine.json index 7603d684d..999f7b888 100644 --- a/wntr/msx/_library_data/nicotine.json +++ b/wntr/msx/_library_data/nicotine.json @@ -1,5 +1,5 @@ { - "wntr-version": "1.0.0", + "wntr-version": "", "name": "nicotine", "title": "Nicotine - Chlorine reaction", "description": null, diff --git a/wntr/msx/_library_data/nicotine_ri.json b/wntr/msx/_library_data/nicotine_ri.json index f73267661..6554f0469 100644 --- a/wntr/msx/_library_data/nicotine_ri.json +++ b/wntr/msx/_library_data/nicotine_ri.json @@ -1,5 +1,5 @@ { - "wntr-version": "1.0.0", + "wntr-version": "", "name": "nicotine_ri", "title": "Nicotine - Chlorine reaction with reactive intermediate", "description": null, diff --git a/wntr/msx/base.py b/wntr/msx/base.py index e795616c7..6bc035ddc 100644 --- a/wntr/msx/base.py +++ b/wntr/msx/base.py @@ -1,7 +1,9 @@ -# -*- coding: utf-8 -*- +# coding: utf-8 +""" +The wntr.msx.base module includes base classes for the multi-species water +quality model -"""The base classes for the the WNTR quality extensions module. -Other than the enum classes, the classes in this module are all abstract +Other than the enum classes, the classes in this module are all abstract and/or mixin classes, and should not be instantiated directly. """ @@ -9,8 +11,8 @@ import os from abc import ABC, abstractclassmethod, abstractmethod, abstractproperty from enum import Enum -from typing import Any, Dict, Iterator, List, Union, Generator -from wntr.epanet.util import ENcomment, NoteType +from typing import Any, Dict, Iterator, Generator +from wntr.epanet.util import NoteType from wntr.utils.disjoint_mapping import DisjointMapping from wntr.utils.enumtools import add_get @@ -59,11 +61,11 @@ def coth(x): {"name": "Av", "note": "Surface area per unit volume (area units/L) "}, {"name": "Len", "note": "Pipe length (feet or meters)"}, ] -"""The hydraulic variables defined in EPANET-MSX. +"""Hydraulic variables defined in EPANET-MSX. For reference, the valid values are provided in :numref:`table-msx-hyd-vars`. .. _table-msx-hyd-vars: -.. table:: Valid hydraulic variables in multispecies quality model expressions. +.. table:: Valid hydraulic variables in multi-species quality model expressions. ============== ================================================ **Name** **Description** @@ -149,7 +151,7 @@ def coth(x): + tuple([k.upper() for k in EXPR_FUNCTIONS.keys()]) + tuple([k.capitalize() for k in EXPR_FUNCTIONS.keys()]) ) -"""The WNTR reserved names. This includes the MSX hydraulic variables +"""WNTR reserved names. This includes the MSX hydraulic variables (see :numref:`table-msx-hyd-vars`) and the MSX defined functions (see :numref:`table-msx-funcs`). @@ -167,7 +169,7 @@ def coth(x): @add_get(abbrev=True) class VariableType(Enum): - """The type of reaction variable. + """Type of reaction variable. The following types are defined, and aliases of just the first character are also defined. @@ -190,15 +192,15 @@ class VariableType(Enum): """ SPECIES = 3 - """A chemical or biological water quality species""" + """Chemical or biological water quality species""" TERM = 4 - """A functional term, or named expression, for use in reaction expressions""" + """Functional term, or named expression, for use in reaction expressions""" PARAMETER = 5 - """A reaction expression coefficient that is parameterized by tank or pipe""" + """Reaction expression coefficient that is parameterized by tank or pipe""" CONSTANT = 6 - """A constant coefficient for use in reaction expressions""" + """Constant coefficient for use in reaction expressions""" RESERVED = 9 - """A variable that is either a hydraulic variable or other reserved word""" + """Variable that is either a hydraulic variable or other reserved word""" S = SPEC = SPECIES T = TERM @@ -209,7 +211,7 @@ class VariableType(Enum): @add_get(abbrev=True) class SpeciesType(Enum): - """The enumeration for species type. + """Enumeration for species type .. warning:: These enum values are not the same as the MSX SpeciesType. @@ -228,9 +230,9 @@ class SpeciesType(Enum): """ BULK = 1 - """bulk species""" + """Bulk species""" WALL = 2 - """wall species""" + """Wall species""" B = BULK W = WALL @@ -238,7 +240,7 @@ class SpeciesType(Enum): @add_get(abbrev=True) class ReactionType(Enum): - """What type of network component does this reaction occur in + """Reaction type which specifies the location where the reaction occurs The following types are defined, and aliases of just the first character are also defined. @@ -256,9 +258,9 @@ class ReactionType(Enum): """ PIPE = 1 - """The expression describes a reaction in pipes""" + """Expression describes a reaction in pipes""" TANK = 2 - """The expression describes a reaction in tanks""" + """Expression describes a reaction in tanks""" P = PIPE T = TANK @@ -266,7 +268,7 @@ class ReactionType(Enum): @add_get(abbrev=True) class ExpressionType(Enum): - """The type of reaction expression. + """Type of reaction expression The following types are defined, and aliases of just the first character are also defined. @@ -287,12 +289,14 @@ class ExpressionType(Enum): """ EQUIL = 1 - """used for equilibrium expressions where it is assumed that the expression supplied is being equated to zero""" + """Equilibrium expressions where equation is being equated to zero""" RATE = 2 - """used to supply the equation that expresses the rate of change of the given species with respect to time as a function - of the other species in the model""" + """Rate expression where the equation expresses the rate of change of + the given species with respect to time as a function of the other species + in the model""" FORMULA = 3 - """used when the concentration of the named species is a simple function of the remaining species""" + """Formula expression where the concentration of the named species is a + simple function of the remaining species""" E = EQUIL R = RATE @@ -300,27 +304,27 @@ class ExpressionType(Enum): class ReactionBase(ABC): - """A water quality reaction class. + """Water quality reaction class This is an abstract class for water quality reactions with partial concrete - attribute and method definitions. All parameters - and methods documented here must be defined by a subclass except for the following: + attribute and method definitions. All parameters and methods documented + here must be defined by a subclass except for the following: - .. rubric:: Concrete attribtues + .. rubric:: Concrete attributes - The :meth:`__init__` method defines the following attributes concretely. Thus, - a subclass should call :code:`super().__init__(species_name, note=note)` at the beginning of its own - initialization. + The :meth:`__init__` method defines the following attributes concretely. + Thus, a subclass should call :code:`super().__init__(species_name, note=note)` + at the beginning of its own initialization. .. autosummary:: ~ReactionBase._species_name ~ReactionBase.note - .. rubric:: Concrete properies + .. rubric:: Concrete properties - The species name is protected, and a reaction cannot be manually assigned a new species. - Therefore, the following property is defined concretely. + The species name is protected, and a reaction cannot be manually assigned + a new species. Therefore, the following property is defined concretely. .. autosummary:: @@ -338,14 +342,15 @@ class ReactionBase(ABC): """ def __init__(self, species_name: str, *, note: NoteType = None) -> None: - """A water quality reaction definition. + """Water quality reaction definition This abstract class must be subclassed. Parameters ---------- species_name : str - The name of the chemical or biological species being modeled using this reaction. + Name of the chemical or biological species being modeled using this + reaction note : (str | dict | ENcomment), optional keyword Supplementary information regarding this reaction, by default None (see-also :class:`~wntr.epanet.util.NoteType`) @@ -353,52 +358,54 @@ def __init__(self, species_name: str, *, note: NoteType = None) -> None: Raises ------ TypeError - if expression_type is invalid + If expression_type is invalid """ if species_name is None: raise TypeError("The species_name cannot be None") self._species_name: str = str(species_name) - """The protected name of the species""" + """Protected name of the species""" self.note: NoteType = note - """An optional note regarding the reaction (see :class:`~wntr.epanet.util.NoteType`) + """Optional note regarding the reaction (see :class:`~wntr.epanet.util.NoteType`) """ @property def species_name(self) -> str: - """The name of the species that has a reaction being defined.""" + """Name of the species that has a reaction being defined.""" return self._species_name @abstractproperty def reaction_type(self) -> Enum: - """The reaction type (reaction location).""" + """Reaction type (reaction location).""" raise NotImplementedError def __str__(self) -> str: - """Return the name of the species and the reaction type, indicated by an arrow. E.g., 'HOCL->PIPE for chlorine reaction in pipes.""" + """Return the name of the species and the reaction type, indicated by + an arrow. E.g., 'HOCL->PIPE for chlorine reaction in pipes.""" return "{}->{}".format(self.species_name, self.reaction_type.name) def __repr__(self) -> str: - """Return a representation of the reaction from the dictionary representation - see :meth:`to_dict`""" + """Return a representation of the reaction from the dictionary + representation - see :meth:`to_dict`""" return "{}(".format(self.__class__.__name__) + ", ".join(["{}={}".format(k, repr(getattr(self, k))) for k, v in self.to_dict().items()]) + ")" @abstractmethod def to_dict(self) -> dict: - """Represent the object as a dictionary.""" + """Represent the object as a dictionary""" raise NotImplementedError class VariableBase(ABC): - """A multi-species water quality model variable. + """Multi-species water quality model variable - This is an abstract class for water quality model variables with partial definition - of concrete attributes and methods. Parameters - and methods documented here must be defined by a subclass except for the following: + This is an abstract class for water quality model variables with partial + definition of concrete attributes and methods. Parameters and methods + documented here must be defined by a subclass except for the following: - .. rubric:: Concrete attribtues + .. rubric:: Concrete attributes - The :meth:`__init__` method defines the following attributes concretely. Thus, - a subclass should call :code:`super().__init__()` at the beginning of its own - initialization. + The :meth:`__init__` method defines the following attributes concretely. + Thus, a subclass should call :code:`super().__init__()` at the beginning + of its own initialization. .. autosummary:: @@ -417,12 +424,12 @@ class VariableBase(ABC): """ def __init__(self, name: str, *, note: NoteType = None) -> None: - """Multi-species variable constructor arguments. + """Multi-species variable constructor arguments Parameters ---------- name : str - The name/symbol for the variable. Must be a valid MSX variable name. + Name/symbol for the variable. Must be a valid MSX variable name note : (str | dict | ENcomment), optional keyword Supplementary information regarding this variable, by default None (see-also :class:`~wntr.epanet.util.NoteType`) @@ -430,21 +437,21 @@ def __init__(self, name: str, *, note: NoteType = None) -> None: Raises ------ KeyExistsError - the name is already taken + Name is already taken ValueError - the name is a reserved word + Name is a reserved word """ if name in RESERVED_NAMES: raise ValueError("Name cannot be a reserved name") self.name: str = name - """The name/ID of this variable, must be a valid EPANET/MSX ID""" + """Name/ID of this variable, must be a valid EPANET/MSX ID""" self.note: NoteType = note - """An optional note regarding the variable (see :class:`~wntr.epanet.util.NoteType`) + """Optional note regarding the variable (see :class:`~wntr.epanet.util.NoteType`) """ @abstractproperty def var_type(self) -> Enum: - """The type of reaction variable""" + """Type of reaction variable""" raise NotImplementedError @abstractmethod @@ -457,24 +464,27 @@ def __str__(self) -> str: return self.name def __repr__(self) -> str: - """Return a representation of the variable from the dictionary representation - see :meth:`to_dict`""" + """Return a representation of the variable from the dictionary + representation - see :meth:`to_dict`""" return "{}(".format(self.__class__.__name__) + ", ".join(["{}={}".format(k, repr(getattr(self, k))) for k, v in self.to_dict().items()]) + ")" class ReactionSystemBase(ABC): - """Abstract class for reaction systems, which contains variables and reaction expressions. + """Abstract class for reaction systems, which contains variables and + reaction expressions. This class contains the functions necessary to perform dictionary-style addressing of *variables* by their name. It does not allow dictionary-style addressing of reactions. - This is an abstract class with some concrete attributes and methods. Parameters - and methods documented here must be defined by a subclass except for the following: + This is an abstract class with some concrete attributes and methods. + Parameters and methods documented here must be defined by a subclass + except for the following: .. rubric:: Concrete attributes - The :meth:`__init__` method defines the following attributes concretely. Thus, - a subclass should call :code:`super().__init__()` or :code:`super().__init__(filename)`. + The :meth:`__init__` method defines the following attributes concretely. + Thus, a subclass should call :code:`super().__init__()` or :code:`super().__init__(filename)`. .. autosummary:: @@ -483,8 +493,8 @@ class ReactionSystemBase(ABC): .. rubric:: Concrete methods - The following special methods are concretely provided to directly access items - in the :attr:`_vars` attribute. + The following special methods are concretely provided to directly access + items in the :attr:`_vars` attribute. .. autosummary:: :nosignatures: @@ -498,11 +508,12 @@ class ReactionSystemBase(ABC): """ def __init__(self) -> None: - """The constructor for the reaction system.""" + """Constructor for the reaction system.""" self._vars: DisjointMapping = DisjointMapping() - """The variables registry, which is mapped to dictionary functions on the reaction system object""" + """Variables registry, which is mapped to dictionary functions on the + reaction system object""" self._rxns: Dict[str, Any] = dict() - """The reactions dictionary""" + """Reactions dictionary""" @abstractmethod def add_variable(self, obj: VariableBase) -> None: @@ -516,12 +527,12 @@ def add_reaction(self, obj: ReactionBase) -> None: @abstractmethod def variables(self) -> Generator[Any, Any, Any]: - """A generator looping through all variables""" + """Generator looping through all variables""" raise NotImplementedError @abstractmethod def reactions(self) -> Generator[Any, Any, Any]: - """A generator looping through all reactions""" + """Generator looping through all reactions""" raise NotImplementedError @abstractmethod @@ -549,11 +560,11 @@ def __len__(self) -> int: class VariableValuesBase(ABC): - """Abstract class for a variable's network-specific values. + """Abstract class for a variable's network-specific values This class should contain values for different pipes, tanks, etc., that correspond to a specific network for the reaction - system. It can be used for intial concentration values, or + system. It can be used for initial concentration values, or for initial settings on parameters, but should be information that is clearly tied to a specific type of variable. @@ -563,23 +574,17 @@ class VariableValuesBase(ABC): @abstractproperty def var_type(self) -> Enum: - """The type of variable this object holds data for.""" + """Type of variable this object holds data for.""" raise NotImplementedError @abstractmethod def to_dict(self) -> dict: - """Represent a specific variable's network-specific values as a dictionary. - - Returns - ------- - dict - the network-specific values for a specific variable - """ + """Represent the object as a dictionary""" raise NotImplementedError class NetworkDataBase(ABC): - """Abstract class containing network specific data. + """Abstract class containing network specific data This class should be populated with things like initial quality, sources, parameterized values, etc. @@ -590,26 +595,21 @@ class NetworkDataBase(ABC): @abstractmethod def to_dict(self) -> dict: - """Represent the quality-relevant network-specific data as a dictionary. - - Returns - ------- - dict - the quality-relevant network data - """ + """Represent the object as a dictionary""" raise NotImplementedError class QualityModelBase(ABC): - """Abstract water quality model. + """Abstract multi-species water quality model - This is an abstract class for a water quality model. All parameters - and methods documented here must be defined by a subclass except for the following: + This is an abstract class for a water quality model. All parameters and + methods documented here must be defined by a subclass except for the + following: .. rubric:: Concrete attributes - The :meth:`__init__` method defines the following attributes concretely. Thus, - a subclass should call :code:`super().__init__()` or :code:`super().__init__(filename)`. + The :meth:`__init__` method defines the following attributes concretely. + Thus, a subclass should call :code:`super().__init__()` or :code:`super().__init__(filename)`. .. autosummary:: @@ -624,34 +624,34 @@ class QualityModelBase(ABC): """ def __init__(self, filename=None): - """Abstract water quality model. + """Abstract water quality model Parameters ---------- filename : str, optional - the file to use to populate the initial data + File to use to populate the initial data """ self.name: str = None if filename is None else os.path.splitext(os.path.split(filename)[1])[0] - """A name for the model, or the MSX model filename (no spaces allowed)""" + """Name for the model, or the MSX model filename (no spaces allowed)""" self.title: str = None - """The title line from the MSX file, must be a single line""" + """Title line from the MSX file, must be a single line""" self.description: str = None - """A longer description; note that multi-line descriptions may not be + """Longer description; note that multi-line descriptions may not be represented well in dictionary form""" self._orig_file: str = filename - """The protected original filename, if provided in the constructor""" + """Protected original filename, if provided in the constructor""" self._options = None - """The protected options data object""" + """Protected options data object""" self._rxn_system: ReactionSystemBase = None - """The protected reaction system object""" + """Protected reaction system object""" self._net_data: NetworkDataBase = None - """The protected network data object""" + """Protected network data object""" self._wn = None - """The protected water network object""" + """Protected water network object""" @abstractproperty def options(self): - """The model options structure. + """Model options structure Concrete classes should implement this with the appropriate typing and also implement a setter method. @@ -660,7 +660,7 @@ def options(self): @abstractproperty def reaction_system(self) -> ReactionSystemBase: - """The reaction variables defined for this model. + """Reaction variables defined for this model Concrete classes should implement this with the appropriate typing. """ @@ -668,7 +668,7 @@ def reaction_system(self) -> ReactionSystemBase: @abstractproperty def network_data(self) -> NetworkDataBase: - """The network-specific values added to this model. + """Network-specific values added to this model Concrete classes should implement this with the appropriate typing. """ @@ -676,27 +676,21 @@ def network_data(self) -> NetworkDataBase: @abstractmethod def to_dict(self) -> dict: - """Represent the model as a dictionary. - - Returns - ------- - dict - A dictionary representation of a water quality model - """ + """Represent the object as a dictionary""" raise NotImplementedError @abstractclassmethod def from_dict(self, data: dict) -> "QualityModelBase": - """Create a new model from a dictionary. + """Create a new model from a dictionary Parameters ---------- data : dict - A dictionary representation of a water quality model + Dictionary representation of the model Returns ------- QualityModelBase - the new concrete water quality model + New concrete model """ raise NotImplementedError diff --git a/wntr/msx/elements.py b/wntr/msx/elements.py index 82fa4236f..3499a59ef 100644 --- a/wntr/msx/elements.py +++ b/wntr/msx/elements.py @@ -1,11 +1,14 @@ -# -*- coding: utf-8 -*- - -"""Concrete implementations of MSX classes. +# coding: utf-8 +""" +The wntr.msx.elements module includes concrete implementations of the +multi-species water quality model elements, including species, constants, +parameters, terms, and reactions. """ + from __future__ import annotations import logging -from typing import Any, Dict, Literal, Tuple, Union +from typing import Any, Dict, Tuple, Union from wntr.epanet.util import ENcomment, NoteType from wntr.utils.disjoint_mapping import KeyExistsError @@ -25,7 +28,7 @@ class Species(VariableBase): - """A biological or chemical species that impacts water quality. + """Biological or chemical species """ def __init__( @@ -41,44 +44,46 @@ def __init__( _vars: ReactionSystemBase = None, _vals: VariableValuesBase = None, ) -> None: - """A biological or chemical species. + """Biological or chemical species Parameters ---------- name - The species name + Species name species_type - The species type + Species type units - The units of mass for this species, see :attr:`units` property. + Units of mass for this species, see :attr:`units` property. atol : float | None - The absolute tolerance when solving this species' equations, by default None + Absolute tolerance when solving this species' equations, by default + None rtol : float | None - The relative tolerance when solving this species' equations, by default None + Relative tolerance when solving this species' equations, by default + None note Supplementary information regarding this variable, by default None (see :class:`~wntr.epanet.util.NoteType`) diffusivity Diffusivity of the species in water, by default None _vars - the reaction system this species is a part of, by default None + Reaction system this species is a part of, by default None _vals - the initial quality values for this species, by default None + Initial quality values for this species, by default None Raises ------ KeyExistsError - if the name has already been used + If the name has already been used TypeError - if `atol` and `rtol` are not the same type + If `atol` and `rtol` are not the same type ValueError - if `atol` or `rtol` ≤ 0 + If `atol` or `rtol` ≤ 0 Notes ----- - EPANET-MSX requires that `atol` and `rtol` either both be omitted, or both be provided. - In order to enforce this, the arguments passed for `atol` and `rtol` must both be None - or both be positive values. + EPANET-MSX requires that `atol` and `rtol` either both be omitted, or + both be provided. In order to enforce this, the arguments passed for + `atol` and `rtol` must both be None or both be positive values. """ super().__init__(name, note=note) if _vars is not None and not isinstance(_vars, ReactionSystemBase): @@ -94,12 +99,12 @@ def __init__( self._tolerances: Tuple[float, float] = None self.set_tolerances(atol, rtol) self.units: str = units - """The units of mass for this species. - For bulk species, concentration is this unit divided by liters, for wall species, concentration is this unit - divided by the model's area-unit (see options). + """Units of mass for this species. For bulk species, concentration is + this unit divided by liters, for wall species, concentration is this + unit divided by the model's area-unit (see options). """ self.diffusivity: float = diffusivity - """The diffusivity of this species in water, if being used, by default None""" + """Diffusivity of this species in water, if being used, by default None""" self._vars: ReactionSystemBase = _vars self._vals: InitialQuality = _vals @@ -112,16 +117,16 @@ def set_tolerances(self, atol: float, rtol: float): Parameters ---------- atol - The absolute tolerance to use + Absolute tolerance to use rtol - The relative tolerance to use + Relative tolerance to use Raises ------ TypeError - if only one of `atol` or `rtol` is a float + If only one of `atol` or `rtol` is a float ValueError - if `atol` or `rtol` ≤ 0 + If `atol` or `rtol` ≤ 0 """ if (atol is None) ^ (rtol is None): raise TypeError("atol and rtol must both be float or both be None") @@ -138,41 +143,43 @@ def get_tolerances(self) -> Union[Tuple[float, float], None]: Returns ------- (atol, rtol) : (float, float) or None - absolute and relative tolerances, respectively, if they are set + Absolute and relative tolerances, respectively, if they are set """ return self._tolerances def clear_tolerances(self): - """Set both tolerances to None, reverting to the global options value.""" + """Set both tolerances to None, reverting to the global options value. + """ self._tolerances = None @property def atol(self) -> float: - """The absolute tolerance. Must be set using :meth:`set_tolerances`""" + """Absolute tolerance. Must be set using :meth:`set_tolerances`""" if self._tolerances is not None: return self._tolerances[0] return None @property def rtol(self) -> float: - """The relative tolerance. Must be set using :meth:`set_tolerances`""" + """Relative tolerance. Must be set using :meth:`set_tolerances`""" if self._tolerances is not None: return self._tolerances[1] return None @property def var_type(self) -> VariableType: - """The type of variable, :attr:`~wntr.msx.base.VariableType.SPECIES`.""" + """Type of variable, :attr:`~wntr.msx.base.VariableType.SPECIES`.""" return VariableType.SPECIES @property def species_type(self) -> SpeciesType: - """The type of species, either :attr:`~wntr.msx.base.SpeciesType.BULK` or :attr:`~wntr.msx.base.SpeciesType.WALL`""" + """Type of species, either :attr:`~wntr.msx.base.SpeciesType.BULK` + or :attr:`~wntr.msx.base.SpeciesType.WALL`""" return self._species_type @property def initial_quality(self) -> 'InitialQuality': - """If a specific network has been linked, then the initial quality values for the network""" + """Initial quality values for the network""" if self._vals is not None: return self._vals else: @@ -180,7 +187,7 @@ def initial_quality(self) -> 'InitialQuality': @property def pipe_reaction(self) -> 'Reaction': - """The pipe reaction definition""" + """Pipe reaction definition""" if self._vars is not None: return self._vars.pipe_reactions[self.name] else: @@ -188,14 +195,14 @@ def pipe_reaction(self) -> 'Reaction': @property def tank_reaction(self) -> 'Reaction': - """The tank reaction definition""" + """Tank reaction definition""" if self._vars is not None: return self._vars.tank_reactions[self.name] else: raise AttributeError("This species is not connected to a ReactionSystem") def to_dict(self) -> Dict[str, Any]: - """Create a dictionary representation of the object + """Dictionary representation of the object The species dictionary has the following format, as described using a json schema. @@ -249,23 +256,23 @@ def to_dict(self) -> Dict[str, Any]: class Constant(VariableBase): - """A constant coefficient for use in reaction expressions.""" + """Constant coefficient for use in expressions""" def __init__(self, name: str, value: float, *, units: str = None, note: Union[str, dict, ENcomment] = None, _vars: ReactionSystemBase = None) -> None: - """A variable representing a constant value. + """Constant coefficient for use in expressions Parameters ---------- name - The name of the variable. + Name of the variable. value - The constant value. + Constant value. units Units for the variable, by default None note Supplementary information regarding this variable, by default None _vars - the reaction system this constant is a part of, by default None + Reaction system this constant is a part of, by default None """ super().__init__(name, note=note) if _vars is not None and not isinstance(_vars, ReactionSystemBase): @@ -273,9 +280,9 @@ def __init__(self, name: str, value: float, *, units: str = None, note: Union[st if _vars is not None and name in _vars: raise KeyExistsError("This variable name is already taken") self.value: float = float(value) - """The value of the constant""" + """Value of the constant""" self.units: str = units - """The units of the constant""" + """Units of the constant""" self._vars: ReactionSystemBase = _vars def __call__(self, *, t=None) -> Any: @@ -283,10 +290,11 @@ def __call__(self, *, t=None) -> Any: @property def var_type(self) -> VariableType: - """The type of variable, :attr:`~wntr.msx.base.VariableType.CONSTANT`.""" + """Type of variable, :attr:`~wntr.msx.base.VariableType.CONSTANT`.""" return VariableType.CONSTANT def to_dict(self) -> Dict[str, Any]: + """Dictionary representation of the object""" ret = dict(name=self.name, value=self.value) if self.units: ret["units"] = self.units @@ -298,27 +306,27 @@ def to_dict(self) -> Dict[str, Any]: class Parameter(VariableBase): - """A coefficient that is parameterized by pipe/tank.""" + """Parameterized variable for use in expressions""" def __init__( self, name: str, global_value: float, *, units: str = None, note: Union[str, dict, ENcomment] = None, _vars: ReactionSystemBase = None, _vals: VariableValuesBase = None ) -> None: - """A parameterized variable for use in expressions. + """Parameterized variable for use in expressions Parameters ---------- name - The name of this parameter. + Name of this parameter. global_value - The global value for the parameter if otherwise unspecified. + Global value for the parameter if otherwise unspecified. units - The units for this parameter, by default None + Units for this parameter, by default None note Supplementary information regarding this variable, by default None _vars - the reaction system this parameter is a part of, by default None + Reaction system this parameter is a part of, by default None _vals - the netork-specific values for this parameter, by default None + Network-specific values for this parameter, by default None """ super().__init__(name, note=note) if _vars is not None and not isinstance(_vars, ReactionSystemBase): @@ -343,21 +351,22 @@ def __call__(self, *, pipe: str = None, tank: str = None) -> float: Parameters ---------- pipe - the name of a pipe to get the parameter value for, by default None + Name of a pipe to get the parameter value for, by default None tank - the name of a pipe to get the parameter value for, by default None + Name of a pipe to get the parameter value for, by default None Returns ------- float - the value at the specified pipe or tank, or the global value + Value at the specified pipe or tank, or the global value Raises ------ TypeError - if both pipe and tank are specified + If both pipe and tank are specified ValueError - if there is no ParameterValues object defined for and linked to this parameter + If there is no ParameterValues object defined for and linked to + this parameter """ if pipe is not None and tank is not None: raise TypeError("Both pipe and tank cannot be specified at the same time") @@ -371,10 +380,11 @@ def __call__(self, *, pipe: str = None, tank: str = None) -> float: @property def var_type(self) -> VariableType: - """The type of variable, :attr:`~wntr.msx.base.VariableType.PARAMETER`.""" + """Type of variable, :attr:`~wntr.msx.base.VariableType.PARAMETER`.""" return VariableType.PARAMETER def to_dict(self) -> Dict[str, Any]: + """Dictionary representation of the object""" ret = dict(name=self.name, global_value=self.global_value) if self.units: ret["units"] = self.units @@ -386,21 +396,23 @@ def to_dict(self) -> Dict[str, Any]: class Term(VariableBase): - """A named expression that can be used as a term in other expressions.""" + """Named expression (term) that can be used in expressions""" - def __init__(self, name: str, expression: str, *, note: Union[str, dict, ENcomment] = None, _vars: ReactionSystemBase = None) -> None: - """A named expression that can be used as a term in other expressions. + def __init__(self, name: str, expression: str, *, + note: Union[str, dict, ENcomment] = None, + _vars: ReactionSystemBase = None) -> None: + """Named expression (term) that can be used in expressions Parameters ---------- name - The variable name. + Variable name. expression - The mathematical expression to be aliased + Mathematical expression to be aliased note Supplementary information regarding this variable, by default None _vars - the reaction system this species is a part of, by default None + Reaction system this species is a part of, by default None """ super().__init__(name, note=note) if _vars is not None and not isinstance(_vars, ReactionSystemBase): @@ -408,15 +420,16 @@ def __init__(self, name: str, expression: str, *, note: Union[str, dict, ENcomme if _vars is not None and name in _vars: raise KeyExistsError("This variable name is already taken") self.expression: str = expression - """The expression that is aliased by this term""" + """Expression that is aliased by this term""" self._vars: ReactionSystemBase = _vars @property def var_type(self) -> VariableType: - """The type of variable, :attr:`~wntr.msx.base.VariableType.TERM`.""" + """Type of variable, :attr:`~wntr.msx.base.VariableType.TERM`.""" return VariableType.TERM def to_dict(self) -> Dict[str, Any]: + """Dictionary representation of the object""" ret = dict(name=self.name, expression=self.expression) if isinstance(self.note, ENcomment): ret["note"] = self.note.to_dict() @@ -426,70 +439,71 @@ def to_dict(self) -> Dict[str, Any]: class ReservedName(VariableBase): - """An object representing a reserved name that should not be used by the user.""" + """Reserved name that should not be used""" def __init__(self, name: str, *, note: Union[str, dict, ENcomment] = None) -> None: - """An object representing a reserved name that should not be used by the user. + """Reserved name that should not be used Parameters ---------- name - The reserved name. + Reserved name. note Supplementary information regarding this variable, by default None Raises ------ KeyExistsError - if the name has already been registered + If the name has already been registered """ self.name: str = name self.note: Union[str, dict, ENcomment] = note @property def var_type(self) -> VariableType: - """The type of variable, :attr:`~wntr.msx.base.VariableType.RESERVED`.""" + """Type of variable, :attr:`~wntr.msx.base.VariableType.RESERVED`.""" return VariableType.RESERVED def to_dict(self) -> Dict[str, Any]: + """Dictionary representation of the object""" return "{}({})".format(self.__class__.__name__, ", ".join(["name={}".format(repr(self.name)), "note={}".format(repr(self.note))])) class HydraulicVariable(ReservedName): - """A variable representing instantaneous hydraulics data.""" + """Reserved name for hydraulic variables""" def __init__(self, name: str, units: str = None, *, note: Union[str, dict, ENcomment] = None) -> None: - """A variable representing instantaneous hydraulics data. + """Reserved name for hydraulic variables The user should not need to create any variables using this class, they - are created automatically by the MultispeciesModel object during initialization. + are created automatically by the MsxModel object during initialization. Parameters ---------- name - The name of the variable (predefined by MSX) + Name of the variable (predefined by MSX) units - The units for hydraulic variable, by default None + Units for hydraulic variable, by default None note Supplementary information regarding this variable, by default None """ super().__init__(name, note=note) self.units: str = units - """The hydraulic variable's units""" + """Hydraulic variable's units""" class MathFunction(ReservedName): - """A variable that is actually a mathematical function defined by MSX.""" + """Reserved name for math functions""" def __init__(self, name: str, func: callable, *, note: Union[str, dict, ENcomment] = None) -> None: - """A variable that is actually a mathematical function defined by MSX. + """Reserved name for math functions Parameters ---------- name - The function name + Function name func - The callable function + Callable function note Supplementary information regarding this variable, by default None """ @@ -503,7 +517,7 @@ def __call__(self, *args: Any, **kwds: Any) -> Any: class Reaction(ReactionBase): - """A water quality biochemical reaction dynamics definition for a specific species.""" + """Water quality reaction dynamics definition for a specific species""" def __init__( self, @@ -515,22 +529,24 @@ def __init__( note: Union[str, dict, ENcomment] = None, _vars: ReactionSystemBase = None, ) -> None: - """A water quality biochemical reaction dynamics definition for a specific species. + """Water quality reaction dynamics definition for a specific species Parameters ---------- species_name - The species (object or name) this reaction is applicable to. + Species (object or name) this reaction is applicable to. reaction_type - The type of reaction, either PIPE or TANK + Reaction type (location), from {PIPE, TANK} expression_type - The type of reaction dynamics being described by the expression: one of RATE, FORMULA, or EQUIL. + Expression type (left-hand-side) of the equation, from + {RATE, EQUIL, FORMULA} expression - The mathematical expression for the right-hand-side of the reaction equation. + Mathematical expression for the right-hand-side of the reaction + equation. note Supplementary information regarding this variable, by default None _vars - the reaction system this species is a part of, by default None + Reaction system this species is a part of, by default None """ super().__init__(species_name=species_name, note=note) if _vars is not None and not isinstance(_vars, ReactionSystemBase): @@ -546,20 +562,26 @@ def __init__( if not expression: raise TypeError("expression cannot be None") self.expression: str = expression - """The mathematical expression (right-hand-side)""" + """Mathematical expression (right-hand-side)""" self._vars: ReactionSystemBase = _vars @property def expression_type(self) -> ExpressionType: - """The expression type (left-hand-side), either :attr:`~wntr.msx.base.ExpressionType.RATE`, :attr:`~wntr.msx.base.ExpressionType.EQUIL`, or :attr:`~wntr.msx.base.ExpressionType.FORMULA`""" + """Expression type (left-hand-side), either + :attr:`~wntr.msx.base.ExpressionType.RATE`, + :attr:`~wntr.msx.base.ExpressionType.EQUIL`, or + :attr:`~wntr.msx.base.ExpressionType.FORMULA`""" return self._expr_type @property def reaction_type(self) -> ReactionType: - """The reaction type (reaction location), either :attr:`~wntr.msx.base.ReactionType.PIPE` or :attr:`~wntr.msx.base.ReactionType.TANK`""" + """Reaction type (location), either + :attr:`~wntr.msx.base.ReactionType.PIPE` or + :attr:`~wntr.msx.base.ReactionType.TANK`""" return self.__rxn_type def to_dict(self) -> dict: + """Dictionary representation of the object""" ret = dict(species_name=str(self.species_name), expression_type=self.expression_type.name.lower(), expression=self.expression) if isinstance(self.note, ENcomment): ret["note"] = self.note.to_dict() @@ -569,22 +591,24 @@ def to_dict(self) -> dict: class InitialQuality(VariableValuesBase): - """A container for initial quality values for a species in a specific network.""" + """Initial quality values for a species in a specific network""" def __init__(self, global_value: float = 0.0, node_values: dict = None, link_values: dict = None): - """The initial quality values for a species. + """Initial quality values for a species in a specific network Parameters ---------- global_value - the global initial quality value, by default 0.0 + Global initial quality value, by default 0.0 node_values - any different initial quality values for specific nodes, by default None + Any different initial quality values for specific nodes, + by default None link_values - any different initial quality values for specific links, by default None + Any different initial quality values for specific links, + by default None """ self.global_value = global_value - """The global initial quality values for this species.""" + """Global initial quality values for this species.""" self._node_values = node_values if node_values is not None else dict() self._link_values = link_values if link_values is not None else dict() @@ -595,35 +619,41 @@ def __repr__(self) -> str: @property def var_type(self) -> VariableType: - """The type of variable, :attr:`~wntr.msx.base.VariableType.SPECIES`, this object holds data for.""" + """Type of variable, :attr:`~wntr.msx.base.VariableType.SPECIES`, + this object holds data for.""" return VariableType.SPECIES @property def node_values(self) -> Dict[str, float]: - """A mapping that overrides the global_value of the initial quality at specific nodes""" + """Mapping that overrides the global_value of the initial quality at + specific nodes""" return self._node_values @property def link_values(self) -> Dict[str, float]: - """A mapping that overrides the global_value of the initial quality in specific links""" + """Mapping that overrides the global_value of the initial quality in + specific links""" return self._link_values def to_dict(self) -> Dict[str, Dict[str, float]]: + """Dictionary representation of the object""" return dict(global_value=self.global_value, node_values=self._node_values.copy(), link_values=self._link_values.copy()) class ParameterValues(VariableValuesBase): - """A container for pipe and tank specific values of a parameter for a specific network.""" + """Pipe and tank specific values of a parameter for a specific network""" def __init__(self, *, pipe_values: dict = None, tank_values: dict = None) -> None: - """The non-global values for a parameter. + """Pipe and tank specific values of a parameter for a specific network Parameters ---------- pipe_values - any different values for this parameter for specific pipes, by default None + Any different values for this parameter for specific pipes, + by default None tank_values - any different values for this parameter for specific tanks, by default None + Any different values for this parameter for specific tanks, + by default None """ self._pipe_values = pipe_values if pipe_values is not None else dict() self._tank_values = tank_values if tank_values is not None else dict() @@ -633,18 +663,22 @@ def __repr__(self) -> str: @property def var_type(self) -> VariableType: - """The type of variable, :attr:`~wntr.msx.base.VariableType.PARAMETER`, this object holds data for.""" + """Type of variable, :attr:`~wntr.msx.base.VariableType.PARAMETER`, + this object holds data for.""" return VariableType.PARAMETER @property def pipe_values(self) -> Dict[str, float]: - """A mapping that overrides the global_value of a parameter for a specific pipe""" + """Mapping that overrides the global_value of a parameter for a + specific pipe""" return self._pipe_values @property def tank_values(self) -> Dict[str, float]: - """A mapping that overrides the global_value of a parameter for a specific tank""" + """Mapping that overrides the global_value of a parameter for a + specific tank""" return self._tank_values def to_dict(self) -> Dict[str, Dict[str, float]]: + """Dictionary representation of the object""" return dict(pipe_values=self._pipe_values.copy(), tank_values=self._tank_values.copy()) diff --git a/wntr/msx/library.py b/wntr/msx/library.py index 76f00a173..62ce4d1ea 100644 --- a/wntr/msx/library.py +++ b/wntr/msx/library.py @@ -1,18 +1,19 @@ -# -*- coding: utf-8 -*- - -r"""A library of common MSX reactions. - +# coding: utf-8 +""" +The wntr.msx.library module includes a library of multi-species water +models .. rubric:: Environment Variable .. envvar:: WNTR_RXN_LIBRARY_PATH This environment variable, if set, will add additional folder(s) to the - path to search for quality model files, (files with an ".msx", ".yaml", - or ".json" file extension). + path to search for multi-species water quality model files, + (files with an ".msx", ".yaml", or ".json" file extension). Multiple folders should be separated using the "``;``" character. See :class:`~wntr.msx.library.ReactionLibrary` for more details. """ + from __future__ import annotations import json @@ -44,67 +45,49 @@ logger = logging.getLogger(__name__) -def cite_msx() -> dict: - """A citation generator for the EPANET-MSX user guide. - - Returns - ------- - str - Shang, F. and Rossman, L.A. and Uber, J.G. (2023) "EPANET-MSX 2.0 User Manual". (Cincinnati, OH: Water Infrastructure Division (CESER), U.S. Environmental Protection Agency). EPA/600/R-22/199. - """ - return 'Shang, F. and Rossman, L.A. and Uber, J.G. (2023) "EPANET-MSX 2.0 User Manual". (Cincinnati, OH: Water Infrastructure Division (CESER), U.S. Environmental Protection Agency). EPA/600/R-22/199.' - # return dict( - # entry_type="report", - # key="SRU23", - # fields=dict( - # title="EPANET-MSX 2.0 User Manual", - # year=2023, - # author="Shang, F. and Rossman, L.A. and Uber, J.G.", - # institution="Water Infrastructure Division (CESER), U.S. Environmental Protection Agency", - # location="Cincinnati, OH", - # number="EPA/600/R-22/199", - # ), - # ) - - class ReactionLibrary: - """A library of multispecies reaction definitions. + """Library of multi-species water quality models - This object can be accessed and treated like a dictionary, where keys are the model - names and the values are the model objects. + This object can be accessed and treated like a dictionary, where keys are + the model names and the values are the model objects. Paths are added/processed in the following order: 1. the builtin directory of reactions, - 2. any paths specified in the environment variable described below, with directories listed - first having the highest priority, - 3. any extra paths specified in the constructor, searched in the order provided. + 2. any paths specified in the environment variable described below, with + directories listed first having the highest priority, + 3. any extra paths specified in the constructor, searched in the order + provided. + + Once created, the library paths cannot be modified. However, a model can + be added to the library using :meth:`add_model_from_file` or + :meth:`add_models_from_dir`. - Once created, the library paths cannot be modified. However, a model can be added - to the library using :meth:`add_model_from_file` or :meth:`add_models_from_dir`. """ - def __init__(self, extra_paths: List[str] = None, include_builtins=True, include_envvar_paths=True, load=True) -> None: - """A library of multispecies reaction definitions. + def __init__(self, extra_paths: List[str] = None, include_builtins=True, + include_envvar_paths=True, load=True) -> None: + """Library of multi-species water quality models Parameters ---------- extra_paths : list of str, optional - user-specified list of reaction library directories, by default None + User-specified list of reaction library directories, by default + None include_builtins : bool, optional - load files built-in with wntr, by default True + Load files built-in with WNTR, by default True include_envvar_paths : bool, optional - load files from the paths specified in :envvar:`WNTR_RXN_LIBRARY_PATH`, by default True + Load files from the paths specified in + :envvar:`WNTR_RXN_LIBRARY_PATH`, by default True load : bool or str, optional - load the files immediately on creation, by default True. - + Load the files immediately on creation, by default True. If a string, then it will be passed as the `duplicates` argument to the load function. See :meth:`reset_and_reload` for details. Raises ------ TypeError - if `extra_paths` is not a list + If `extra_paths` is not a list """ if extra_paths is None: extra_paths = list() @@ -142,20 +125,20 @@ def __repr__(self) -> str: return "{}({})".format(self.__class__.__name__, repr(self.__library_paths)) def path_list(self) -> List[str]: - """Get the original list of paths used for this library. + """List of paths used to populate the library Returns ------- list of str - a copy of the paths used to **initially** populate this library + Copy of the paths used to **initially** populate the library """ return self.__library_paths.copy() def reset_and_reload(self, duplicates: str = "error") -> List[Tuple[str, str, Any]]: - """Load data from the configured directories into a library of models. + """Load data from the configured directories into a library of models - Note, this function is not recursive and does not 'walk' any of the library's - directories to look for subfolders. + Note, this function is not recursive and does not 'walk' any of the + library's directories to look for subfolders. The ``duplicates`` argument specifies how models that have the same name, or that have the same filename if a name isn't specified in the file, @@ -187,13 +170,13 @@ def reset_and_reload(self, duplicates: str = "error") -> List[Tuple[str, str, An Raises ------ TypeError - if `duplicates` is not a string + If `duplicates` is not a string ValueError - if `duplicates` is not a valid value + If `duplicates` is not a valid value IOError - if `path_to_folder` is not a directory + If `path_to_folder` is not a directory KeyError - if `duplicates` is ``"error"`` and two models have the same name + If `duplicates` is ``"error"`` and two models have the same name """ if duplicates and not isinstance(duplicates, str): raise TypeError("The `duplicates` argument must be None or a string") @@ -207,44 +190,43 @@ def reset_and_reload(self, duplicates: str = "error") -> List[Tuple[str, str, An return load_errors def add_models_from_dir(self, path_to_dir: str, duplicates: str = "error") -> List[Tuple[str, str, Union[MsxModel, Exception]]]: - """Load all valid model files in a folder. - - Note, this function is not recursive and does not 'walk' a directory tree. + """Load all valid model files in a folder - The ``duplicates`` argument specifies how models that have the same name, - or that have the same filename if a name isn't specified in the file, - are handled. **Warning**, if two files in the same directory have models - with the same name, there is no guarantee which will be read in first. + Note, this function is not recursive and does not 'walk' a directory + tree. Parameters ---------- path_to_dir : str - the path to the folder to search + Path to the folder to search duplicates : {"error", "skip", "replace"}, optional + Specifies how models that have the same name, or that have the same + filename if a name isn't specified in the file, are handled. + **Warning**, if two files in the same directory have models with + the same name, there is no guarantee which will be read in first, by default ``"error"`` - - - A value of of ``"error"`` raises an exception and stops execution. - - A value of ``"skip"`` will skip models with the same `name` as a model that already - exists in the library. - - A value of ``"replace"`` will replace any existing model with a model that is read - in that has the same `name`. + - A value of of ``"error"`` raises an exception and stops execution + - A value of ``"skip"`` will skip models with the same `name` as a + model that already exists in the library. + - A value of ``"replace"`` will replace any existing model with a + model that is read in that has the same `name`. Returns ------- (filename, reason, obj) : tuple[str, str, Any] - the file not read in, the cause of the problem, and the object that was skipped/overwritten - or the exception raised + File not read in, the cause of the problem, and the object that was + skipped/overwritten or the exception raised Raises ------ TypeError - if `duplicates` is not a string + If `duplicates` is not a string ValueError - if `duplicates` is not a valid value + If `duplicates` is not a valid value IOError - if `path_to_folder` is not a directory + If `path_to_folder` is not a directory KeyError - if `duplicates` is ``"error"`` and two models have the same name + If `duplicates` is ``"error"`` and two models have the same name """ if duplicates and not isinstance(duplicates, str): raise TypeError("The `duplicates` argument must be None or a string") @@ -309,7 +291,7 @@ def add_models_from_dir(self, path_to_dir: str, duplicates: str = "error") -> Li return load_errors def add_model_from_file(self, path_and_filename: str, name: str = None): - """Load a reaction model from a file and add it to the model. + """Load a model from a file and add it to the library Note, this **does not check** to see if a model exists with the same name, and it will automatically overwrite the existing model if one @@ -349,22 +331,22 @@ def add_model_from_file(self, path_and_filename: str, name: str = None): self.__data[new.name] = new def get_model(self, name: str) -> MsxModel: - """Get a reaction model from the library by model name. + """Get a model from the library by model name Parameters ---------- name : str - the name of the model + Name of the model Returns ------- MsxModel - the model object + Model object """ return self.__data[name] def model_name_list(self) -> List[str]: - """Get the names of all models in the library. + """Get the names of all models in the library Returns ------- diff --git a/wntr/msx/model.py b/wntr/msx/model.py index 4d9749c3d..49bf90058 100644 --- a/wntr/msx/model.py +++ b/wntr/msx/model.py @@ -1,13 +1,15 @@ -# -*- coding: utf-8 -*- - -"""The WNTR MSX model. +# coding: utf-8 +""" +The wntr.msx.model module includes methods to build a multi-species water +quality model. """ + from __future__ import annotations import logging import warnings -from typing import Any, Dict, Generator, List, NewType, Union -from wntr.epanet.util import ENcomment, NoteType +from typing import Dict, Generator, List, Union +from wntr.epanet.util import NoteType from wntr.utils.disjoint_mapping import KeyExistsError @@ -18,7 +20,6 @@ ReactionBase, NetworkDataBase, ReactionSystemBase, - VariableBase, ExpressionType, ReactionType, SpeciesType, @@ -34,7 +35,8 @@ class MsxReactionSystem(ReactionSystemBase): - """A registry for all the variables registered in the multispecies reactions model. + """Registry for all the variables registered in the multi-species reactions + model. This object can be used like a mapping. """ @@ -53,32 +55,32 @@ def __init__(self) -> None: @property def species(self) -> Dict[str, Species]: - """The dictionary view onto only species""" + """Dictionary view onto only species""" return self._species @property def constants(self) -> Dict[str, Constant]: - """The dictionary view onto only constants""" + """Dictionary view onto only constants""" return self._const @property def parameters(self) -> Dict[str, Parameter]: - """The dictionary view onto only parameters""" + """Dictionary view onto only parameters""" return self._param @property def terms(self) -> Dict[str, Term]: - """The dictionary view onto only named terms""" + """Dictionary view onto only named terms""" return self._term @property def pipe_reactions(self) -> Dict[str, Reaction]: - """The dictionary view onto pipe reactions""" + """Dictionary view onto pipe reactions""" return self._pipes @property def tank_reactions(self) -> Dict[str, Reaction]: - """The dictionary view onto tank reactions""" + """Dictionary view onto tank reactions""" return self._tanks def add_variable(self, variable: MsxVariable) -> None: @@ -90,14 +92,14 @@ def add_variable(self, variable: MsxVariable) -> None: Parameters ---------- variable - The variable to add. + Variable to add. Raises ------ TypeError - if `variable` is not an MsxVariable + If `variable` is not an MsxVariable KeyExistsError - if `variable` has a name that is already used in the registry + If `variable` has a name that is already used in the registry """ if not isinstance(variable, (Species, Constant, Parameter, Term, MathFunction, HydraulicVariable)): raise TypeError("Expected AVariable object") @@ -112,14 +114,14 @@ def add_reaction(self, reaction: Reaction) -> None: Parameters ---------- reaction : Reaction - a water quality reaction definition + Water quality reaction definition Raises ------ TypeError - if `reaction` is not a Reaction + If `reaction` is not a Reaction KeyError - if the `species_name` in the `reaction` does not exist in the model + If the `species_name` in the `reaction` does not exist in the model """ if not isinstance(reaction, Reaction): raise TypeError("Expected a Reaction object") @@ -129,17 +131,18 @@ def add_reaction(self, reaction: Reaction) -> None: def variables(self) -> Generator[tuple, None, None]: # FIXME: rename without "all_" for this - """A generator looping through all variables""" + """Generator looping through all variables""" for k, v in self._vars.items(): yield k, v.var_type.name.lower(), v def reactions(self) -> Generator[tuple, None, None]: - """A generator looping through all reactions""" + """Generator looping through all reactions""" for k2, v in self._rxns.items(): for k1, v1 in v.items(): yield k1, k2, v1 def to_dict(self) -> dict: + """Dictionary representation of the MsxModel.""" return dict( species=[v.to_dict() for v in self._species.values()], constants=[v.to_dict() for v in self._const.values()], @@ -151,38 +154,46 @@ def to_dict(self) -> dict: class MsxNetworkData(NetworkDataBase): - """A container for network-specific values associated with a multispecies water quality model.""" - def __init__(self, patterns: Dict[str, List[float]] = None, sources: Dict[str, Dict[str, dict]] = None, initial_quality: Dict[str, Union[dict,InitialQuality]] = None, parameter_values: Dict[str, Union[dict, ParameterValues]] = None) -> None: - """A container for network-specific values associated with a multispecies water quality model. + def __init__(self, patterns: Dict[str, List[float]] = None, + sources: Dict[str, Dict[str, dict]] = None, + initial_quality: Dict[str, Union[dict, InitialQuality]] = None, + parameter_values: Dict[str, Union[dict, ParameterValues]] = None) -> None: + """Network-specific values associated with a multi-species water + quality model - Data is copied from dictionaries passed in, so once created, the dictionaries passed are not connected - to this object. + Data is copied from dictionaries passed in, so once created, the + dictionaries passed are not connected to this object. Parameters ---------- patterns : dict, optional - patterns to use for sources + Patterns to use for sources sources : dict, optional - sources defined for the model + Sources defined for the model initial_quality : dict, optional - initial values for different species at different nodes, links, and the global value + Initial values for different species at different nodes, links, and + the global value parameter_values : dict, optional - parameter values for different pipes and tanks + Parameter values for different pipes and tanks Notes ----- ``patterns`` - A dictionary keyed by pattern name (str) with values being the multipliers (list of float) + Dictionary keyed by pattern name (str) with values being the + multipliers (list of float) ``sources`` - A dictionary keyed by species name (str) with values being dictionaries keyed by junction name (str) with values being the + Dictionary keyed by species name (str) with values being + dictionaries keyed by junction name (str) with values being the dictionary of settings for the source ``initial_quality`` - A dictionary keyed by species name (str) with values being either an :class:`~wntr.msx.elements.InitialQuality` object or - the appropriate dictionary representation thereof. + Dictionary keyed by species name (str) with values being either an + :class:`~wntr.msx.elements.InitialQuality` object or the + appropriate dictionary representation thereof. ``parameter_values`` - A dictionary keyed by parameter name (str) with values being either a :class:`~wntr.msx.elements.ParameterValues` object or - the appropriate dictionary representation thereof. + Dictionary keyed by parameter name (str) with values being either + a :class:`~wntr.msx.elements.ParameterValues` object or the + appropriate dictionary representation thereof. """ if sources is None: sources = dict() @@ -206,53 +217,55 @@ def __init__(self, patterns: Dict[str, List[float]] = None, sources: Dict[str, D @property def sources(self): - """A dictionary of sources, keyed by species name""" + """Dictionary of sources, keyed by species name""" return self._source_dict @property def initial_quality(self) -> Dict[str, InitialQuality]: - """A dictionary of initial quality values, keyed by species name""" + """Dictionary of initial quality values, keyed by species name""" return self._initial_quality_dict @property def patterns(self): - """A dictionary of patterns, specific for the water quality model, keyed by pattern name. + """Dictionary of patterns, specific for the water quality model, keyed + by pattern name. - .. note:: the WaterNetworkModel cannot see these patterns, so names can be reused, so be - careful. Likewise, this model cannot see the WaterNetworkModel patterns, so this could be - a source of some confusion. + .. note:: the WaterNetworkModel cannot see these patterns, so names can + be reused, so be careful. Likewise, this model cannot see the + WaterNetworkModel patterns, so this could be a source of some + confusion. """ return self._pattern_dict @property def parameter_values(self) -> Dict[str, ParameterValues]: - """A dictionary of parameter values, keyed by parameter name""" + """Dictionary of parameter values, keyed by parameter name""" return self._parameter_value_dict def add_pattern(self, name: str, multipliers: List[float]): - """Add a water-quality-model-specific pattern. + """Add a water quality model specific pattern. Arguments --------- name : str - The pattern name + Pattern name multipliers : list of float - The pattern multipliers + Pattern multipliers """ self._pattern_dict[name] = multipliers def init_new_species(self, species: Species): - """(Re)set the initial quality values for a species to a new container + """(Re)set the initial quality values for a species Arguments --------- species : Species - The species to (re)initialized. + Species to (re)initialized. Returns ------- InitialQuality - the new initial quality values container + New initial quality values """ self._initial_quality_dict[str(species)] = InitialQuality() if isinstance(species, Species): @@ -260,12 +273,12 @@ def init_new_species(self, species: Species): return self._initial_quality_dict[str(species)] def remove_species(self, species: Union[Species, str]): - """Remove a species from the network specific model. + """Remove a species from the network specific model Arguments --------- species : Species or str - a species to be removed from the network data + Species to be removed from the network data """ if isinstance(species, Species): species._vals = None @@ -275,17 +288,17 @@ def remove_species(self, species: Union[Species, str]): pass def init_new_parameter(self, param: Parameter): - """(Re)initialize parameter values for a parameter. + """(Re)initialize parameter values for a parameter Arguments --------- param : Parameter - a parameter to be (re)initialized with network data + Parameter to be (re)initialized with network data Returns ------- ParameterValues - the new network data for the specific parameter + New network data for the specific parameter """ self._parameter_value_dict[str(param)] = ParameterValues() if isinstance(param, Parameter): @@ -293,14 +306,14 @@ def init_new_parameter(self, param: Parameter): return self._parameter_value_dict[str(param)] def remove_parameter(self, param: Union[Parameter, str]): - """Remove values associated with a specific parameter. + """Remove values associated with a specific parameter Ignores non-parameters. Arguments --------- param : Parameter or str - the parameter or parameter name to be removed from the network data + Parameter or parameter name to be removed from the network data """ if isinstance(param, Parameter): param._vals = None @@ -321,15 +334,15 @@ def to_dict(self) -> dict: class MsxModel(QualityModelBase): - """A multispecies water quality model for use with WNTR EPANET-MSX simulator.""" + """Multi-species water quality model""" def __init__(self, msx_file_name=None) -> None: - """A full, multi-species water quality model. + """Multi-species water quality model Arguments --------- msx_file_name : str, optional - an MSX file to read in, by default None + MSX file to to load into the MsxModel object, by default None """ super().__init__(msx_file_name) self._references: List[Union[str, Dict[str, str]]] = list() @@ -363,47 +376,48 @@ def __repr__(self) -> str: @property def references(self) -> List[Union[str, Dict[str, str]]]: - """A list of strings or mappings that provide references for this model. + """List of strings or mappings that provide references for this model .. note:: - This property is a list, and should be modified using append/insert/remove. - Members of the list should be json seriealizable (i.e., strings or dicts of strings). + This property is a list, and should be modified using + append/insert/remove. Members of the list should be json + serializable (i.e., strings or dicts of strings). """ return self._references @property def reaction_system(self) -> MsxReactionSystem: - """The reaction variables defined for this model.""" + """Reaction variables defined for this model""" return self._rxn_system @property def network_data(self) -> MsxNetworkData: - """The network-specific values added to this model.""" + """Network-specific values added to this model""" return self._net_data @property def options(self) -> MsxSolverOptions: - """The MSX model options""" + """MSX model options""" return self._options @property def species_name_list(self) -> List[str]: - """all defined species names""" + """Get a list of species names""" return list(self.reaction_system.species.keys()) @property def constant_name_list(self) -> List[str]: - """all defined coefficient names""" + """Get a list of coefficient names""" return list(self.reaction_system.constants.keys()) @property def parameter_name_list(self) -> List[str]: - """all defined coefficient names""" + """Get a list of coefficient names""" return list(self.reaction_system.parameters.keys()) @property def term_name_list(self) -> List[str]: - """all defined function (MSX 'terms') names""" + """Get a list of function (MSX 'terms') names""" return list(self.reaction_system.terms.keys()) @options.setter @@ -411,7 +425,7 @@ def options(self, value: Union[dict, MsxSolverOptions]): if isinstance(value, dict): self._options = MsxSolverOptions.factory(value) elif not isinstance(value, MsxSolverOptions): - raise TypeError("Expected a MultispeciesOptions object, got {}".format(type(value))) + raise TypeError("Expected a MsxSolverOptions object, got {}".format(type(value))) else: self._options = value @@ -430,32 +444,32 @@ def add_species( Arguments --------- name : str - the species name + Species name species_type : SpeciesType - the type of species, either BULK or WALL + Type of species, either BULK or WALL units : str - the mass units for this species + Mass units for this species atol : float, optional unless rtol is not None - the absolute solver tolerance for this species, by default None + Absolute solver tolerance for this species, by default None rtol : float, optional unless atol is not None - the relative solver tolerance for this species, by default None + Relative solver tolerance for this species, by default None note : NoteType, optional keyword - supplementary information regarding this variable, by default None + Supplementary information regarding this variable, by default None (see also :class:`~wntr.epanet.util.ENcomment`) diffusivity : float, optional - diffusivity of this species in water + Diffusivity of this species in water Raises ------ KeyExistsError - if a variable with this name already exists + If a variable with this name already exists ValueError - if `atol` or `rtol` ≤ 0 + If `atol` or `rtol` ≤ 0 Returns ------- Species - the new species + New species """ if name in self._rxn_system: raise KeyExistsError("Variable named {} already exists in model as type {}".format(name, self._rxn_system._vars.get_groupname(name))) @@ -476,19 +490,19 @@ def add_species( return new def remove_species(self, variable_or_name): - """Remove a species from the model. + """Remove a species from the model Removes from both the reaction_system and the network_data. Parameters ---------- variable_or_name : Species or str - the species (or name of the species) to be removed + Species (or name of the species) to be removed Raises ------ KeyError - if `variable_or_name` is not a species in the model + If `variable_or_name` is not a species in the model """ name = str(variable_or_name) if name not in self.reaction_system.species: @@ -498,28 +512,28 @@ def remove_species(self, variable_or_name): self.reaction_system.__delitem__(name) def add_constant(self, name: str, value: float, units: str = None, note: NoteType = None) -> Constant: - """Add a constant coefficient to the model. + """Add a constant coefficient to the model Arguments --------- name : str - the name of the coefficient + Name of the coefficient value : float - the constant value of the coefficient + Constant value of the coefficient units : str, optional - the units for this coefficient, by default None + Units for this coefficient, by default None note : NoteType, optional - supplementary information regarding this variable, by default None + Supplementary information regarding this variable, by default None Raises ------ KeyExistsError - a variable with this name already exists + Variable with this name already exists Returns ------- Constant - the new constant coefficient + New constant coefficient """ if name in self._rxn_system: raise KeyExistsError("Variable named {} already exists in model as type {}".format(name, self._rxn_system._vars.get_groupname(name))) @@ -528,17 +542,17 @@ def add_constant(self, name: str, value: float, units: str = None, note: NoteTyp return new def remove_constant(self, variable_or_name): - """Remove a constant coefficient from the model. + """Remove a constant coefficient from the model Parameters ---------- variable_or_name : Constant or str - the constant (or name of the constant) to be removed + Constant (or name of the constant) to be removed Raises ------ KeyError - if `variable_or_name` is not a constant coefficient in the model + If `variable_or_name` is not a constant coefficient in the model """ name = str(variable_or_name) if name not in self.reaction_system.constants: @@ -547,16 +561,17 @@ def remove_constant(self, variable_or_name): self.reaction_system.__delitem__(name) def add_parameter(self, name: str, global_value: float, units: str = None, note: NoteType = None) -> Parameter: - """Add a parameterized coefficient to the model. + """Add a parameterized coefficient to the model Arguments --------- name : str - the name of the parameter + Name of the parameter global_value : float - the global value of the coefficient (can be overridden for specific pipes/tanks) + Global value of the coefficient (can be overridden for specific + pipes/tanks) units : str, optional - the units for the coefficient, by default None + Units for the coefficient, by default None note : NoteType, optional keyword Supplementary information regarding this variable, by default None (see also :class:`~wntr.epanet.util.ENcomment`). @@ -564,12 +579,12 @@ def add_parameter(self, name: str, global_value: float, units: str = None, note: Raises ------ KeyExistsError - if a variable with this name already exists + If a variable with this name already exists Returns ------- Parameter - the new parameterized coefficient + New parameterized coefficient """ if name in self._rxn_system: raise KeyExistsError("Variable named {} already exists in model as type {}".format(name, self._rxn_system._vars.get_groupname(name))) @@ -579,17 +594,17 @@ def add_parameter(self, name: str, global_value: float, units: str = None, note: return new def remove_parameter(self, variable_or_name): - """Remove a parameterized coefficient from the model. + """Remove a parameterized coefficient from the model Parameters ---------- variable_or_name : Parameter or str - the parameter (or name of the parameter) to be removed + Parameter (or name of the parameter) to be removed Raises ------ KeyError - if `variable_or_name` is not a parameter in the model + If `variable_or_name` is not a parameter in the model """ name = str(variable_or_name) if name not in self.reaction_system.parameters: @@ -599,14 +614,14 @@ def remove_parameter(self, variable_or_name): self.reaction_system.__delitem__(name) def add_term(self, name: str, expression: str, note: NoteType = None) -> Term: - """Add a named expression (term) to the model. + """Add a named expression (term) to the model Parameters ---------- name : str - the name of the functional term to be added + Name of the functional term to be added expression : str - the expression that the term defines + Expression that the term defines note : NoteType, optional keyword Supplementary information regarding this variable, by default None (see also :class:`~wntr.epanet.util.ENcomment`) @@ -619,7 +634,7 @@ def add_term(self, name: str, expression: str, note: NoteType = None) -> Term: Returns ------- Term - the new term + New term """ if name in self._rxn_system: raise KeyError("Variable named {} already exists in model as type {}".format(name, self._rxn_system._vars.get_groupname(name))) @@ -628,17 +643,17 @@ def add_term(self, name: str, expression: str, note: NoteType = None) -> Term: return new def remove_term(self, variable_or_name): - """Remove a named expression (term) from the model. + """Remove a named expression (term) from the model Parameters ---------- variable_or_name : Term or str - the term (or name of the term) to be deleted + Term (or name of the term) to be deleted Raises ------ KeyError - if `variable_or_name` is not a term in the model + If `variable_or_name` is not a term in the model """ name = str(variable_or_name) # FIXME: validate deletion @@ -647,25 +662,26 @@ def remove_term(self, variable_or_name): self.reaction_system.__delitem__(name) def add_reaction(self, species_name: Union[Species, str], reaction_type: ReactionType, expression_type: ExpressionType, expression: str, note: NoteType = None) -> ReactionBase: - """Add a reaction to a species in the model. + """Add a reaction to a species in the model - Note that all species need to have both a pipe and tank reaction defined - unless all species are bulk species and - the tank reactions are identical to the pipe reactions. However, it is not - recommended that users take this approach. + Note that all species need to have both a pipe and tank reaction + defined unless all species are bulk species and the tank reactions are + identical to the pipe reactions. However, it is not recommended that + users take this approach. Once added, access the reactions from the species' object. Arguments --------- species_name : Species or str - the species (or name of species) the reaction is being defined for + Species (or name of species) the reaction is being defined for reaction_type: ReactionType - where this reaction takes place, from {PIPE, TANK} + Reaction type (location), from {PIPE, TANK} expression_type : ExpressionType - the type (LHS) of the equation the expression belongs to, from {RATE, EQUIL, FORMULA} + Expression type (left-hand-side) of the equation, from {RATE, + EQUIL, FORMULA} expression : str - the expression defining the reaction + Expression defining the reaction note : NoteType, optional keyword Supplementary information regarding this reaction, by default None (see also :class:`~wntr.epanet.util.ENcomment`) @@ -673,12 +689,12 @@ def add_reaction(self, species_name: Union[Species, str], reaction_type: Reactio Raises ------ TypeError - if a variable that is not species is passed + If a variable that is not species is passed Returns ------- - MultispeciesReaction - the new reaction object + MsxReactionSystem + New reaction object """ species_name = str(species_name) species = self.reaction_system.species[species_name] @@ -697,20 +713,21 @@ def add_reaction(self, species_name: Union[Species, str], reaction_type: Reactio return new def remove_reaction(self, species_name: str, reaction_type: ReactionType) -> None: - """Remove a reaction at a specified location from a species. + """Remove a reaction at a specified location from a species Parameters ---------- species : Species or str - the species (or name of the species) of the reaction to remove + Species (or name of the species) of the reaction to remove reaction_type : ReactionType - the reaction type (location) of the reaction to remove + Reaction type (location) of the reaction to remove """ reaction_type = ReactionType.get(reaction_type, allow_none=False) species_name = str(species_name) del self.reaction_system.reactions[reaction_type.name.lower()][species_name] def to_dict(self) -> dict: + """Dictionary representation of the MsxModel""" from wntr import __version__ return { @@ -726,12 +743,12 @@ def to_dict(self) -> dict: @classmethod def from_dict(cls, data) -> "MsxModel": - """Create a new multispecies reaction model from a dictionary. + """Create a new multi-species water quality model from a dictionary Parameters ---------- data : dict - The model data + Model data """ from wntr import __version__ diff --git a/wntr/msx/options.py b/wntr/msx/options.py index e99645352..70bed47f2 100644 --- a/wntr/msx/options.py +++ b/wntr/msx/options.py @@ -1,5 +1,7 @@ # coding: utf-8 -"""Options for multispecies reaction models. +""" +The wntr.msx.options module includes options for multi-species water quality +models """ import logging @@ -12,7 +14,7 @@ class MsxReportOptions(_OptionsBase): """ - Options related to EPANET-MSX report outputs. + Report options """ def __init__( @@ -25,44 +27,39 @@ def __init__( links: Union[Literal["ALL"], List[str]] = None, ): """ - Options related to EPANET-MSX report outputs. + Report options Parameters ---------- report_filename : str - Provides the filename to use for outputting an EPANET report file, - by default this will be the prefix plus ".rpt". - + Filename for the EPANET-MSX report file, by default this will be + the prefix plus ".rpt". species : dict[str, bool] Output species concentrations - species_precision : dict[str, float] Output species concentrations with the specified precision - nodes : None, "ALL", or list - Output node information in report file. If a list of node names is provided, - EPANET only provides report information for those nodes. - + Output node information. If a list of node names is provided, + EPANET-MSX only provides report information for those nodes. links : None, "ALL", or list - Output link information in report file. If a list of link names is provided, - EPANET only provides report information for those links. - + Output link information. If a list of link names is provided, + EPANET-MSX only provides report information for those links. pagesize : str - Page size for EPANET report output + Page size for EPANET-MSX report output """ self.pagesize = pagesize - """The pagesize for the report""" + """Pagesize for the report""" self.report_filename = report_filename - """The prefix of the report filename (will add .rpt)""" + """Prefix of the report filename (will add .rpt)""" self.species = species if species is not None else dict() """Turn individual species outputs on and off, by default no species are output""" self.species_precision = species_precision if species_precision is not None else dict() - """Set the output precision for the concentration of a specific species""" + """Output precision for the concentration of a specific species""" self.nodes = nodes - """A list of nodes to print output for, or 'ALL' for all nodes, by default None""" + """List of nodes to print output for, or 'ALL' for all nodes, by default None""" self.links = links - """A list of links to print output for, or 'ALL' for all links, by default None""" + """List of links to print output for, or 'ALL' for all links, by default None""" def __setattr__(self, name, value): if name not in ["pagesize", "report_filename", "species", "nodes", "links", "species_precision"]: @@ -71,9 +68,7 @@ def __setattr__(self, name, value): class MsxSolverOptions(_OptionsBase): - """ - Multispecies quality model options. - """ + """Solver options""" def __init__( self, @@ -91,56 +86,73 @@ def __init__( report: MsxReportOptions = None, ): """ - Multispecies quality model options. + Solver options Parameters ---------- timestep : int >= 1 Water quality timestep (seconds), by default 60 (one minute). area_units : str, optional - The units of area to use in surface concentration forms, by default ``M2``. Valid values are ``FT2``, ``M2``, or ``CM2``. + Units of area to use in surface concentration forms, by default + ``M2``. Valid values are ``FT2``, ``M2``, or ``CM2``. rate_units : str, optional - The time units to use in all rate reactions, by default ``MIN``. Valid values are ``SEC``, ``MIN``, ``HR``, or ``DAY``. + Time units to use in all rate reactions, by default ``MIN``. Valid + values are ``SEC``, ``MIN``, ``HR``, or ``DAY``. solver : str, optional - The solver to use, by default ``RK5``. Options are ``RK5`` (5th order Runge-Kutta method), ``ROS2`` (2nd order Rosenbrock method), or ``EUL`` (Euler method). + Solver to use, by default ``RK5``. Options are ``RK5`` (5th order + Runge-Kutta method), ``ROS2`` (2nd order Rosenbrock method), or + ``EUL`` (Euler method). coupling : str, optional - Use coupling method for solution, by default ``NONE``. Valid options are ``FULL`` or ``NONE``. + Use coupling method for solution, by default ``NONE``. Valid + options are ``FULL`` or ``NONE``. atol : float, optional - Absolute concentration tolerance, by default 0.01 (regardless of species concentration units). + Absolute concentration tolerance, by default 0.01 (regardless of + species concentration units). rtol : float, optional Relative concentration tolerance, by default 0.001 (±0.1%). compiler : str, optional - Whether to use a compiler, by default ``NONE``. Valid options are ``VC``, ``GC``, or ``NONE`` + Whether to use a compiler, by default ``NONE``. Valid options are + ``VC``, ``GC``, or ``NONE`` segments : int, optional - Maximum number of segments per pipe (MSX 2.0 or newer only), by default 5000. + Maximum number of segments per pipe (MSX 2.0 or newer only), by + default 5000. peclet : int, optional - Peclet threshold for applying dispersion (MSX 2.0 or newer only), by default 1000. - report : ReportOptions or dict + Peclet threshold for applying dispersion (MSX 2.0 or newer only), + by default 1000. + report : MsxReportOptions or dict Options on how to report out results. """ self.timestep: int = timestep - """The timestep, in seconds, by default 360""" + """Timestep, in seconds, by default 360""" self.area_units: str = area_units - """The units used to express pipe wall surface area where, by default FT2. Valid values are FT2, M2, and CM2.""" + """Units used to express pipe wall surface area where, by default FT2. + Valid values are FT2, M2, and CM2.""" self.rate_units: str = rate_units - """The units in which all reaction rate terms are expressed, by default HR. Valid values are HR, MIN, SEC, and DAY.""" + """Units in which all reaction rate terms are expressed, by default HR. + Valid values are HR, MIN, SEC, and DAY.""" self.solver: str = solver - """The solver to use, by default EUL. Valid values are EUL, RK5, and ROS2.""" + """Solver to use, by default EUL. Valid values are EUL, RK5, and + ROS2.""" self.coupling: str = coupling - """Whether coupling should occur during solving, by default NONE. Valid values are NONE and FULL.""" + """Whether coupling should occur during solving, by default NONE. Valid + values are NONE and FULL.""" self.rtol: float = rtol - """The relative tolerance used during solvers ROS2 and RK5, by default 0.001 for all species. Can be overridden on a per-species basis.""" + """Relative tolerance used during solvers ROS2 and RK5, by default + 0.001 for all species. Can be overridden on a per-species basis.""" self.atol: float = atol - """The absolute tolerance used by the solvers, by default 0.01 for all species regardless of concentration units. Can be overridden on a per-species basis.""" + """Absolute tolerance used by the solvers, by default 0.01 for all + species regardless of concentration units. Can be overridden on a + per-species basis.""" self.compiler: str = compiler - """A compier to use if the equations should be compiled by EPANET-MSX, by default NONE. Valid options are VC, GC and NONE.""" + """Compiler to use if the equations should be compiled by EPANET-MSX, + by default NONE. Valid options are VC, GC and NONE.""" self.segments: int = segments - """The number of segments per-pipe to use, by default 5000.""" + """Number of segments per-pipe to use, by default 5000.""" self.peclet: int = peclet - """The threshold for applying dispersion, by default 1000.""" + """Threshold for applying dispersion, by default 1000.""" self.report: MsxReportOptions = MsxReportOptions.factory(report) - """The reporting output options.""" + """Reporting output options.""" def __setattr__(self, name, value): if name == "report": @@ -163,7 +175,7 @@ def __setattr__(self, name, value): except ValueError: raise ValueError("%s must be a number", name) elif name not in ["area_units", "rate_units", "solver", "coupling", "compiler"]: - raise ValueError("%s is not a valid member of MultispeciesOptions") + raise ValueError("%s is not a valid member of MsxSolverOptions") self.__dict__[name] = value def to_dict(self): diff --git a/wntr/network/base.py b/wntr/network/base.py index 20ddc94eb..7dcf3ae8b 100644 --- a/wntr/network/base.py +++ b/wntr/network/base.py @@ -245,7 +245,8 @@ def tag(self, tag): @property def initial_quality(self): - """float or dict: The initial quality (concentration) at the node, or a dict of species-->quality for multispecies quality""" + """float or dict: Initial quality (concentration) at the node, or + a dict of species-->quality for multi-species quality""" if not self._initial_quality: return 0.0 return self._initial_quality @@ -257,7 +258,7 @@ def initial_quality(self, value): @property def coordinates(self): - """tuple: The node coordinates, (x,y)""" + """tuple: Node coordinates, (x,y)""" return self._coordinates @coordinates.setter def coordinates(self, coordinates): diff --git a/wntr/tests/test_msx_elements.py b/wntr/tests/test_msx_elements.py index 39cc09188..e65f796f3 100644 --- a/wntr/tests/test_msx_elements.py +++ b/wntr/tests/test_msx_elements.py @@ -157,7 +157,7 @@ def test_Reaction(self): self.assertEqual(formula1.expression, "-Ka + Kb * Cl + T0") self.assertEqual(formula1.expression_type, wntr.msx.ExpressionType.FORMULA) - def test_WaterQualityReactionsModel_creation_specific_everything(self): + def test_MsxModel_creation_specific_everything(self): rxn_model1 = wntr.msx.MsxModel() bulk1 = wntr.msx.Species("Cl", 'b', "mg") wall1 = wntr.msx.Species("ClOH", 'w', "mg", 0.01, 0.0001, note="Testing stuff") diff --git a/wntr/utils/disjoint_mapping.py b/wntr/utils/disjoint_mapping.py index 27dc32c34..fd2572bf8 100644 --- a/wntr/utils/disjoint_mapping.py +++ b/wntr/utils/disjoint_mapping.py @@ -1,7 +1,8 @@ # coding: utf-8 -"""A set of utility classes that is similar to the 'registry' objects in the wntr.network -class, but more general, and therefore usable for other extensions, such as multispecies -reaction modeling. +""" +A set of utility classes that is similar to the 'registry' objects in the wntr.network +class, but more general, and therefore usable for other extensions, such as multi-species +water quality models. """ from collections.abc import MutableMapping @@ -10,13 +11,11 @@ class WrongGroupError(KeyError): """The key exists but is in a different disjoint group""" - pass class KeyExistsError(KeyError): - """The name already exists in the reaction model""" - + """The name already exists in the model""" pass From d347ad644511740b950a59a3f2d505f7dc4c2469 Mon Sep 17 00:00:00 2001 From: dbhart Date: Mon, 13 Nov 2023 08:15:11 -0700 Subject: [PATCH 47/75] Docs update --- wntr/epanet/exceptions.py | 2 +- wntr/epanet/msx/exceptions.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/wntr/epanet/exceptions.py b/wntr/epanet/exceptions.py index fdf405dd5..1a4200128 100644 --- a/wntr/epanet/exceptions.py +++ b/wntr/epanet/exceptions.py @@ -85,7 +85,7 @@ 309: "cannot save results to report file %s", } """A dictionary of the error codes and their meanings from the EPANET toolkit. -Please see :doc:`/errors` for a tables of these values. +Please see :doc:`/errors` for tables of these values. :meta hide-value: """ diff --git a/wntr/epanet/msx/exceptions.py b/wntr/epanet/msx/exceptions.py index a1dcc6ee4..d505d33ef 100644 --- a/wntr/epanet/msx/exceptions.py +++ b/wntr/epanet/msx/exceptions.py @@ -46,8 +46,8 @@ 523: "could not load functions from compiled chemistry file", 524: "illegal math operation", } -"""Dictionary of MSX error codes and meanings. -See :class:`MsxErrorEnum` for the list of error codes and their meanings. +"""A dictionary of the error codes and their meanings from the EPANET-MSX toolkit. +Please see :doc:`/errors` for tables of these values. :meta hide-value: """ From e07e292fc900b9a1da0813113d327350e57807fa Mon Sep 17 00:00:00 2001 From: dbhart Date: Fri, 17 Nov 2023 09:59:06 -0700 Subject: [PATCH 48/75] Fix changed name --- wntr/network/model.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/wntr/network/model.py b/wntr/network/model.py index f6c6cb2ae..81c85ce22 100644 --- a/wntr/network/model.py +++ b/wntr/network/model.py @@ -336,9 +336,9 @@ def msx(self): def msx(self, msx): if msx is None: self._msx = None - from wntr.msx.base import AbstractQualityModel - if not isinstance(msx, AbstractQualityModel): - raise TypeError('Expected AbstractQualityModel (or derived), got {}'.format(type(msx))) + from wntr.msx.base import QualityModelBase + if not isinstance(msx, QualityModelBase): + raise TypeError('Expected QualityModelBase (or derived), got {}'.format(type(msx))) def add_msx_model(self, msx_filename=None): """Add an msx model from a MSX input file (.msx extension)""" From 361f1675b5109b64bad4ca62911bc75de4dc98a4 Mon Sep 17 00:00:00 2001 From: dbhart Date: Mon, 23 Oct 2023 11:34:06 -0600 Subject: [PATCH 49/75] Update to correct the exceptions listings --- wntr/epanet/exceptions.py | 128 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 128 insertions(+) diff --git a/wntr/epanet/exceptions.py b/wntr/epanet/exceptions.py index 1a4200128..6ed8555a6 100644 --- a/wntr/epanet/exceptions.py +++ b/wntr/epanet/exceptions.py @@ -85,7 +85,130 @@ 309: "cannot save results to report file %s", } """A dictionary of the error codes and their meanings from the EPANET toolkit. +<<<<<<< HEAD Please see :doc:`/errors` for tables of these values. +======= + +.. rubric:: Runtime warnings +==== ============================================================================================================================================================================== +Err# Description +---- ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ +1 At `time`, system hydraulically unbalanced - convergence to a hydraulic solution was not achieved in the allowed number of trials +2 At `time`, system may be hydraulically unstable - hydraulic convergence was only achieved after the status of all links was held fixed +3 At `time`, system disconnected - one or more nodes with positive demands were disconnected for all supply sources +4 At `time`, pumps cannot deliver enough flow or head - one or more pumps were forced to either shut down (due to insufficient head) or operate beyond the maximum rated flow +5 At `time`, valves cannot deliver enough flow - one or more flow control valves could not deliver the required flow even when fully open +6 At `time`, system has negative pressures - negative pressures occurred at one or more junctions with positive demand +==== ============================================================================================================================================================================== + +.. rubric:: Runtime errors + +==== ================================================================= +Err# Description +---- ----------------------------------------------------------------- +101 insufficient memory available +102 no network data available +103 hydraulics not initialized +104 no hydraulics for water quality analysis +105 water quality not initialized +106 no results saved to report on +107 hydraulics supplied from external file +108 cannot use external file while hydraulics solver is active +109 cannot change time parameter when solver is active +110 cannot solve network hydraulic equations +120 cannot solve water quality transport equations +==== ================================================================= + +.. rubric:: Input file errors, exclusively + +==== ================================================================= +Err# Description +---- ----------------------------------------------------------------- +200 one or more errors in input file +201 syntax error +==== ================================================================= + +.. rubric:: Input file and/or toolkit errors + +==== ================================================================= +Err# Description +---- ----------------------------------------------------------------- +202 illegal numeric value +203 undefined node +204 undefined link +205 undefined time pattern +206 undefined curve +207 attempt to control a CV/GPV link +208 illegal PDA pressure limits +209 illegal node property value +211 illegal link property value +212 undefined trace node +213 invalid option value +214 too many characters in input line +215 duplicate ID label +216 reference to undefined pump +217 pump has no head curve or power defined +218 `note: error number 218 is undefined in the EPANET 2.2 toolkit` +219 illegal valve connection to tank node +220 illegal valve connection to another valve +221 misplaced rule clause in rule-based control +222 link assigned same start and end nodes +==== ================================================================= + +.. rubric:: Network consistency errors (INP-file and/or toolkit) + +==== ================================================================= +Err# Description +---- ----------------------------------------------------------------- +223 not enough nodes in network +224 no tanks or reservoirs in network +225 invalid lower/upper levels for tank +226 no head curve or power rating for pump +227 invalid head curve for pump +230 nonincreasing x-values for curve +233 network has unconnected node +234 network has an unconnected node with ID `id` +==== ================================================================= + +.. rubric:: Toolkit-only errors + +==== ================================================================= +Err# Description +---- ----------------------------------------------------------------- +240 nonexistent water quality source +241 nonexistent control +250 invalid format (e.g. too long an ID name) +251 invalid parameter code +252 invalid ID name +253 nonexistent demand category +254 node with no coordinates +255 invalid link vertex +257 nonexistent rule +258 nonexistent rule clause +259 attempt to delete a node that still has links connected to it +260 attempt to delete node assigned as a Trace Node +261 attempt to delete a node or link contained in a control +262 attempt to modify network structure while a solver is open +263 node is not a tank +==== ================================================================= + +.. rubric:: File I/O errors + +==== ========================================================= +Err# Description +---- --------------------------------------------------------- +301 identical file names used for different types of files +302 cannot open input file +303 cannot open report file +304 cannot open binary output file +305 cannot open hydraulics file +306 hydraulics file does not match network data +307 cannot read hydraulics file +308 cannot save results to binary file +309 cannot save results to report file +==== ========================================================= + +>>>>>>> f2235867 (Update to correct the exceptions listings) :meta hide-value: """ @@ -108,6 +231,11 @@ def __init__(self, code: int, *args: List[object], line_num=None, line=None) -> line : str, optional The contents of the line, by default None """ +<<<<<<< HEAD +======= + if not isinstance(code, int): + return super().__init__('unknown error code: {}'.format(repr(code)), *args) +>>>>>>> f2235867 (Update to correct the exceptions listings) msg = EN_ERROR_CODES.get(code, 'unknown error') if args is not None: args = [*args] From be1144742ddeb24ef6f93acd2f13598e1e8a9b38 Mon Sep 17 00:00:00 2001 From: dbhart Date: Fri, 17 Nov 2023 11:28:18 -0700 Subject: [PATCH 50/75] fix exceptions --- wntr/epanet/exceptions.py | 128 -------------------------------------- 1 file changed, 128 deletions(-) diff --git a/wntr/epanet/exceptions.py b/wntr/epanet/exceptions.py index 6ed8555a6..1a4200128 100644 --- a/wntr/epanet/exceptions.py +++ b/wntr/epanet/exceptions.py @@ -85,130 +85,7 @@ 309: "cannot save results to report file %s", } """A dictionary of the error codes and their meanings from the EPANET toolkit. -<<<<<<< HEAD Please see :doc:`/errors` for tables of these values. -======= - -.. rubric:: Runtime warnings -==== ============================================================================================================================================================================== -Err# Description ----- ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ -1 At `time`, system hydraulically unbalanced - convergence to a hydraulic solution was not achieved in the allowed number of trials -2 At `time`, system may be hydraulically unstable - hydraulic convergence was only achieved after the status of all links was held fixed -3 At `time`, system disconnected - one or more nodes with positive demands were disconnected for all supply sources -4 At `time`, pumps cannot deliver enough flow or head - one or more pumps were forced to either shut down (due to insufficient head) or operate beyond the maximum rated flow -5 At `time`, valves cannot deliver enough flow - one or more flow control valves could not deliver the required flow even when fully open -6 At `time`, system has negative pressures - negative pressures occurred at one or more junctions with positive demand -==== ============================================================================================================================================================================== - -.. rubric:: Runtime errors - -==== ================================================================= -Err# Description ----- ----------------------------------------------------------------- -101 insufficient memory available -102 no network data available -103 hydraulics not initialized -104 no hydraulics for water quality analysis -105 water quality not initialized -106 no results saved to report on -107 hydraulics supplied from external file -108 cannot use external file while hydraulics solver is active -109 cannot change time parameter when solver is active -110 cannot solve network hydraulic equations -120 cannot solve water quality transport equations -==== ================================================================= - -.. rubric:: Input file errors, exclusively - -==== ================================================================= -Err# Description ----- ----------------------------------------------------------------- -200 one or more errors in input file -201 syntax error -==== ================================================================= - -.. rubric:: Input file and/or toolkit errors - -==== ================================================================= -Err# Description ----- ----------------------------------------------------------------- -202 illegal numeric value -203 undefined node -204 undefined link -205 undefined time pattern -206 undefined curve -207 attempt to control a CV/GPV link -208 illegal PDA pressure limits -209 illegal node property value -211 illegal link property value -212 undefined trace node -213 invalid option value -214 too many characters in input line -215 duplicate ID label -216 reference to undefined pump -217 pump has no head curve or power defined -218 `note: error number 218 is undefined in the EPANET 2.2 toolkit` -219 illegal valve connection to tank node -220 illegal valve connection to another valve -221 misplaced rule clause in rule-based control -222 link assigned same start and end nodes -==== ================================================================= - -.. rubric:: Network consistency errors (INP-file and/or toolkit) - -==== ================================================================= -Err# Description ----- ----------------------------------------------------------------- -223 not enough nodes in network -224 no tanks or reservoirs in network -225 invalid lower/upper levels for tank -226 no head curve or power rating for pump -227 invalid head curve for pump -230 nonincreasing x-values for curve -233 network has unconnected node -234 network has an unconnected node with ID `id` -==== ================================================================= - -.. rubric:: Toolkit-only errors - -==== ================================================================= -Err# Description ----- ----------------------------------------------------------------- -240 nonexistent water quality source -241 nonexistent control -250 invalid format (e.g. too long an ID name) -251 invalid parameter code -252 invalid ID name -253 nonexistent demand category -254 node with no coordinates -255 invalid link vertex -257 nonexistent rule -258 nonexistent rule clause -259 attempt to delete a node that still has links connected to it -260 attempt to delete node assigned as a Trace Node -261 attempt to delete a node or link contained in a control -262 attempt to modify network structure while a solver is open -263 node is not a tank -==== ================================================================= - -.. rubric:: File I/O errors - -==== ========================================================= -Err# Description ----- --------------------------------------------------------- -301 identical file names used for different types of files -302 cannot open input file -303 cannot open report file -304 cannot open binary output file -305 cannot open hydraulics file -306 hydraulics file does not match network data -307 cannot read hydraulics file -308 cannot save results to binary file -309 cannot save results to report file -==== ========================================================= - ->>>>>>> f2235867 (Update to correct the exceptions listings) :meta hide-value: """ @@ -231,11 +108,6 @@ def __init__(self, code: int, *args: List[object], line_num=None, line=None) -> line : str, optional The contents of the line, by default None """ -<<<<<<< HEAD -======= - if not isinstance(code, int): - return super().__init__('unknown error code: {}'.format(repr(code)), *args) ->>>>>>> f2235867 (Update to correct the exceptions listings) msg = EN_ERROR_CODES.get(code, 'unknown error') if args is not None: args = [*args] From d4678600f49731c6e9a1cee98edfa4a2018bdea9 Mon Sep 17 00:00:00 2001 From: dbhart Date: Mon, 30 Oct 2023 10:12:27 -0600 Subject: [PATCH 51/75] Updates to address comments in PR. Tests forthcoming --- documentation/errors.rst | 166 +++++++++++++++++++++++++++++++++++++++ documentation/index.rst | 1 + 2 files changed, 167 insertions(+) create mode 100644 documentation/errors.rst diff --git a/documentation/errors.rst b/documentation/errors.rst new file mode 100644 index 000000000..5206caaba --- /dev/null +++ b/documentation/errors.rst @@ -0,0 +1,166 @@ +.. raw:: latex + + \clearpage + + +Errors and debugging +==================== + +WNTR extends several of the standard python exceptions, :class:`KeyError`, :class:`SyntaxError`, +and :class:`ValueError` with EPANET toolkit specific versions, +:class:`~wntr.epanet.exceptions.ENKeyError`, +:class:`~wntr.epanet.exceptions.ENSyntaxError`, +and :class:`~wntr.epanet.exceptions.ENValueError`, +and a base :class:`~wntr.epanet.exceptions.EpanetException`. +These exceptions are raised when errors occur during INP-file reading/writing, +when using the EPANET toolkit functions, and when running the +:class:`~wntr.sim.epanet.EpanetSimulator`. + +In addition to the normal information that a similar python exception would provide, +these exceptions return the EPANET error code number and the error description +from the EPANET source code. WNTR also tries to intuit the specific variable, +line number (of an input file), and timestamp to give the user the most information +possible. Tables :numref:`table-epanet-warnings` through :numref:`table-epanet-errors-filesystem` +provide the description of the various warnings and error codes defined in [Ross00]_. + + +.. _table-epanet-warnings: +.. table:: EPANET warnings + + =========== ============================================================================================================================================================================== + *Err No.* *Description* + ----------- ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ + **1-6** **Simulation warnings** + ----------- ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ + 1 At `{time}`, system hydraulically unbalanced - convergence to a hydraulic solution was not achieved in the allowed number of trials + 2 At `{time}`, system may be hydraulically unstable - hydraulic convergence was only achieved after the status of all links was held fixed + 3 At `{time}`, system disconnected - one or more nodes with positive demands were disconnected for all supply sources + 4 At `{time}`, pumps cannot deliver enough flow or head - one or more pumps were forced to either shut down (due to insufficient head) or operate beyond the maximum rated flow + 5 At `{time}`, valves cannot deliver enough flow - one or more flow control valves could not deliver the required flow even when fully open + 6 At `{time}`, system has negative pressures - negative pressures occurred at one or more junctions with positive demand + =========== ============================================================================================================================================================================== + +.. _table-epanet-errors-runtime: +.. table:: EPANET runtime errors + + =========== ================================================================= + *Err No.* *Description* + ----------- ----------------------------------------------------------------- + **101-120** **Runtime and simulation errors** + ----------- ----------------------------------------------------------------- + 101 insufficient memory available + 102 no network data available + 103 hydraulics not initialized + 104 no hydraulics for water quality analysis + 105 water quality not initialized + 106 no results saved to report on + 107 hydraulics supplied from external file + 108 cannot use external file while hydraulics solver is active + 109 cannot change time parameter when solver is active + 110 cannot solve network hydraulic equations + 120 cannot solve water quality transport equations + =========== ================================================================= + + +.. _table-epanet-errors-network: +.. table:: EPANET network errors + + =========== ================================================================= + *Err No.* *Description* + ----------- ----------------------------------------------------------------- + **200-201** **Input file errors (exclusively for input files)** + ----------- ----------------------------------------------------------------- + 200 one or more errors in input file + 201 syntax error + ----------- ----------------------------------------------------------------- + **202-222** **Input file and toolkit errors** + ----------- ----------------------------------------------------------------- + 202 illegal numeric value + 203 undefined node + 204 undefined link + 205 undefined time pattern + 206 undefined curve + 207 attempt to control a CV/GPV link + 208 illegal PDA pressure limits + 209 illegal node property value + 211 illegal link property value + 212 undefined trace node + 213 invalid option value + 214 too many characters in input line + 215 duplicate ID label + 216 reference to undefined pump + 217 pump has no head curve or power defined + 218 `note: error number 218 is undefined in EPANET 2.2` + 219 illegal valve connection to tank node + 220 illegal valve connection to another valve + 221 misplaced rule clause in rule-based control + 222 link assigned same start and end nodes + ----------- ----------------------------------------------------------------- + **223-234** **Network consistency errors (INP-file and/or toolkit)** + ----------- ----------------------------------------------------------------- + 223 not enough nodes in network + 224 no tanks or reservoirs in network + 225 invalid lower/upper levels for tank + 226 no head curve or power rating for pump + 227 invalid head curve for pump + 230 nonincreasing x-values for curve + 233 network has unconnected node + 234 network has an unconnected node with ID `id` + ----------- ----------------------------------------------------------------- + **240-263** **Toolkit-only errors** + ----------- ----------------------------------------------------------------- + 240 nonexistent water quality source + 241 nonexistent control + 250 invalid format (e.g. too long an ID name) + 251 invalid parameter code + 252 invalid ID name + 253 nonexistent demand category + 254 node with no coordinates + 255 invalid link vertex + 257 nonexistent rule + 258 nonexistent rule clause + 259 attempt to delete a node that still has links connected to it + 260 attempt to delete node assigned as a Trace Node + 261 attempt to delete a node or link contained in a control + 262 attempt to modify network structure while a solver is open + 263 node is not a tank + =========== ================================================================= + + +.. _table-epanet-errors-filesystem: +.. table:: EPANET file/system errors + + =========== ================================================================= + *Err No.* *Description* + ----------- ----------------------------------------------------------------- + **301-305** **Filename errors** + ----------- ----------------------------------------------------------------- + 301 identical file names used for different types of files + 302 cannot open input file + 303 cannot open report file + 304 cannot open binary output file + 305 cannot open hydraulics file + ----------- ----------------------------------------------------------------- + **306-307** **File structure errors** + ----------- ----------------------------------------------------------------- + 306 hydraulics file does not match network data + 307 cannot read hydraulics file + ----------- ----------------------------------------------------------------- + **308-309** **Filesystem errors** + ----------- ----------------------------------------------------------------- + 308 cannot save results to binary file + 309 cannot save results to report file + =========== ================================================================= + + +For developers +-------------- + +The custom exceptions for EPANET that are included in the :class:`wntr.epanet.exceptions` +module subclass both the :class:`~wntr.epanet.exceptions.EpanetException` +and the standard python exception they are named after. This means that when handling +exceptions, a try-catch block that is looking for a :class:`KeyError`, for example, +will still catch an :class:`~wntr.epanet.exceptions.ENKeyError`. The newest versions +of Python, e.g., 3.11, have a new style of multiple inheritence for Exceptions, called +exception groups, but this has not yet been used in WNTR because older versions of +Python are still supported at this time. diff --git a/documentation/index.rst b/documentation/index.rst index 003bde8c1..5c56728c4 100644 --- a/documentation/index.rst +++ b/documentation/index.rst @@ -31,6 +31,7 @@ designed to simulate and analyze resilience of water distribution networks. graphics gis advancedsim + errors license whatsnew developers From 4c9600aff5498d56be395cd234f0c41f8842c527 Mon Sep 17 00:00:00 2001 From: dbhart Date: Fri, 17 Nov 2023 09:37:07 -0700 Subject: [PATCH 52/75] Added the tests for exceptions --- .../apidoc/wntr.epanet.exceptions.rst | 7 --- wntr/tests/test_epanet_exceptions.py | 47 +++++++++++++++++++ 2 files changed, 47 insertions(+), 7 deletions(-) delete mode 100644 documentation/apidoc/wntr.epanet.exceptions.rst create mode 100644 wntr/tests/test_epanet_exceptions.py diff --git a/documentation/apidoc/wntr.epanet.exceptions.rst b/documentation/apidoc/wntr.epanet.exceptions.rst deleted file mode 100644 index 6cb9d9029..000000000 --- a/documentation/apidoc/wntr.epanet.exceptions.rst +++ /dev/null @@ -1,7 +0,0 @@ -wntr.epanet.exceptions module -============================= - -.. automodule:: wntr.epanet.exceptions - :members: - :no-undoc-members: - :show-inheritance: diff --git a/wntr/tests/test_epanet_exceptions.py b/wntr/tests/test_epanet_exceptions.py new file mode 100644 index 000000000..5dd3b20c3 --- /dev/null +++ b/wntr/tests/test_epanet_exceptions.py @@ -0,0 +1,47 @@ +import unittest +from os.path import abspath, dirname, join, exists + +import wntr.epanet.exceptions + +testdir = dirname(abspath(__file__)) +datadir = join(testdir, "..", "..", "examples", "networks") + + +class TestEpanetExceptions(unittest.TestCase): + + def test_epanet_exception(self): + try: + raise wntr.epanet.exceptions.EpanetException(213, '13:00:00 pm', 'Cannot specify am/pm for times greater than 12:00:00') + except Exception as e: + self.assertTupleEqual(e.args, ("(Error 213) invalid option value '13:00:00 pm' ['Cannot specify am/pm for times greater than 12:00:00']",)) + try: + raise wntr.epanet.exceptions.EpanetException(999) + except Exception as e: + self.assertTupleEqual(e.args, ('(Error 999) unknown error',)) + try: + raise wntr.epanet.exceptions.EpanetException(108) + except Exception as e: + self.assertTupleEqual(e.args, ('(Error 108) cannot use external file while hydraulics solver is active',)) + + def test_epanet_syntax_error(self): + try: + raise wntr.epanet.exceptions.ENSyntaxError(223, line_num=38, line='I AM A SYNTAX ERROR') + except SyntaxError as e: + self.assertTupleEqual(e.args, ('(Error 223) not enough nodes in network, at line 38:\n I AM A SYNTAX ERROR',)) + + def test_epanet_key_error(self): + try: + raise wntr.epanet.exceptions.ENKeyError(206, 'NotACurve') + except KeyError as e: + self.assertTupleEqual(e.args, ("(Error 206) undefined curve, 'NotACurve'",)) + + def test_epanet_value_error(self): + try: + raise wntr.epanet.exceptions.ENValueError(213, 423.0e28) + except ValueError as e: + self.assertTupleEqual(e.args, ('(Error 213) invalid option value 4.23e+30',)) + + + +if __name__ == "__main__": + unittest.main() From 54e045eff37e27981b7bb2ab17eb9a58aa7bc6c6 Mon Sep 17 00:00:00 2001 From: dbhart Date: Fri, 17 Nov 2023 11:33:52 -0700 Subject: [PATCH 53/75] Get rid of apidoc to match docs-theme --- documentation/apidoc/wntr.epanet.io.rst | 7 ----- .../apidoc/wntr.epanet.msx.enums.rst | 7 ----- .../apidoc/wntr.epanet.msx.exceptions.rst | 7 ----- documentation/apidoc/wntr.epanet.msx.io.rst | 7 ----- documentation/apidoc/wntr.epanet.msx.rst | 20 -------------- .../apidoc/wntr.epanet.msx.toolkit.rst | 7 ----- documentation/apidoc/wntr.epanet.rst | 21 --------------- documentation/apidoc/wntr.epanet.toolkit.rst | 7 ----- documentation/apidoc/wntr.epanet.util.rst | 7 ----- documentation/apidoc/wntr.gis.geospatial.rst | 7 ----- documentation/apidoc/wntr.gis.network.rst | 7 ----- documentation/apidoc/wntr.gis.rst | 15 ----------- documentation/apidoc/wntr.graphics.color.rst | 7 ----- documentation/apidoc/wntr.graphics.curve.rst | 7 ----- documentation/apidoc/wntr.graphics.layer.rst | 7 ----- .../apidoc/wntr.graphics.network.rst | 7 ----- documentation/apidoc/wntr.graphics.rst | 18 ------------- .../apidoc/wntr.metrics.economic.rst | 7 ----- .../apidoc/wntr.metrics.hydraulic.rst | 7 ----- documentation/apidoc/wntr.metrics.misc.rst | 7 ----- documentation/apidoc/wntr.metrics.rst | 18 ------------- .../apidoc/wntr.metrics.topographic.rst | 7 ----- .../apidoc/wntr.metrics.water_security.rst | 7 ----- documentation/apidoc/wntr.morph.link.rst | 7 ----- documentation/apidoc/wntr.morph.node.rst | 7 ----- documentation/apidoc/wntr.morph.rst | 16 ----------- documentation/apidoc/wntr.morph.skel.rst | 7 ----- documentation/apidoc/wntr.msx.base.rst | 7 ----- documentation/apidoc/wntr.msx.elements.rst | 7 ----- documentation/apidoc/wntr.msx.library.rst | 7 ----- documentation/apidoc/wntr.msx.model.rst | 7 ----- documentation/apidoc/wntr.msx.options.rst | 7 ----- documentation/apidoc/wntr.msx.rst | 20 -------------- documentation/apidoc/wntr.network.base.rst | 8 ------ .../apidoc/wntr.network.controls.rst | 8 ------ .../apidoc/wntr.network.elements.rst | 8 ------ documentation/apidoc/wntr.network.io.rst | 8 ------ documentation/apidoc/wntr.network.layer.rst | 8 ------ documentation/apidoc/wntr.network.model.rst | 8 ------ documentation/apidoc/wntr.network.options.rst | 7 ----- documentation/apidoc/wntr.network.rst | 21 --------------- documentation/apidoc/wntr.rst | 27 ------------------- .../apidoc/wntr.scenario.earthquake.rst | 7 ----- .../apidoc/wntr.scenario.fragility_curve.rst | 7 ----- documentation/apidoc/wntr.scenario.rst | 16 ----------- documentation/apidoc/wntr.sim.aml.rst | 12 --------- documentation/apidoc/wntr.sim.core.rst | 7 ----- documentation/apidoc/wntr.sim.epanet.rst | 7 ----- documentation/apidoc/wntr.sim.hydraulics.rst | 7 ----- documentation/apidoc/wntr.sim.results.rst | 7 ----- documentation/apidoc/wntr.sim.rst | 20 -------------- documentation/apidoc/wntr.sim.solvers.rst | 7 ----- .../apidoc/wntr.utils.disjoint_mapping.rst | 8 ------ documentation/apidoc/wntr.utils.enumtools.rst | 7 ----- documentation/apidoc/wntr.utils.logger.rst | 7 ----- .../apidoc/wntr.utils.ordered_set.rst | 8 ------ documentation/apidoc/wntr.utils.rst | 18 ------------- 57 files changed, 558 deletions(-) delete mode 100644 documentation/apidoc/wntr.epanet.io.rst delete mode 100644 documentation/apidoc/wntr.epanet.msx.enums.rst delete mode 100644 documentation/apidoc/wntr.epanet.msx.exceptions.rst delete mode 100644 documentation/apidoc/wntr.epanet.msx.io.rst delete mode 100644 documentation/apidoc/wntr.epanet.msx.rst delete mode 100644 documentation/apidoc/wntr.epanet.msx.toolkit.rst delete mode 100644 documentation/apidoc/wntr.epanet.rst delete mode 100644 documentation/apidoc/wntr.epanet.toolkit.rst delete mode 100644 documentation/apidoc/wntr.epanet.util.rst delete mode 100644 documentation/apidoc/wntr.gis.geospatial.rst delete mode 100644 documentation/apidoc/wntr.gis.network.rst delete mode 100644 documentation/apidoc/wntr.gis.rst delete mode 100644 documentation/apidoc/wntr.graphics.color.rst delete mode 100644 documentation/apidoc/wntr.graphics.curve.rst delete mode 100644 documentation/apidoc/wntr.graphics.layer.rst delete mode 100644 documentation/apidoc/wntr.graphics.network.rst delete mode 100644 documentation/apidoc/wntr.graphics.rst delete mode 100644 documentation/apidoc/wntr.metrics.economic.rst delete mode 100644 documentation/apidoc/wntr.metrics.hydraulic.rst delete mode 100644 documentation/apidoc/wntr.metrics.misc.rst delete mode 100644 documentation/apidoc/wntr.metrics.rst delete mode 100644 documentation/apidoc/wntr.metrics.topographic.rst delete mode 100644 documentation/apidoc/wntr.metrics.water_security.rst delete mode 100644 documentation/apidoc/wntr.morph.link.rst delete mode 100644 documentation/apidoc/wntr.morph.node.rst delete mode 100644 documentation/apidoc/wntr.morph.rst delete mode 100644 documentation/apidoc/wntr.morph.skel.rst delete mode 100644 documentation/apidoc/wntr.msx.base.rst delete mode 100644 documentation/apidoc/wntr.msx.elements.rst delete mode 100644 documentation/apidoc/wntr.msx.library.rst delete mode 100644 documentation/apidoc/wntr.msx.model.rst delete mode 100644 documentation/apidoc/wntr.msx.options.rst delete mode 100644 documentation/apidoc/wntr.msx.rst delete mode 100644 documentation/apidoc/wntr.network.base.rst delete mode 100644 documentation/apidoc/wntr.network.controls.rst delete mode 100644 documentation/apidoc/wntr.network.elements.rst delete mode 100644 documentation/apidoc/wntr.network.io.rst delete mode 100644 documentation/apidoc/wntr.network.layer.rst delete mode 100644 documentation/apidoc/wntr.network.model.rst delete mode 100644 documentation/apidoc/wntr.network.options.rst delete mode 100644 documentation/apidoc/wntr.network.rst delete mode 100644 documentation/apidoc/wntr.rst delete mode 100644 documentation/apidoc/wntr.scenario.earthquake.rst delete mode 100644 documentation/apidoc/wntr.scenario.fragility_curve.rst delete mode 100644 documentation/apidoc/wntr.scenario.rst delete mode 100644 documentation/apidoc/wntr.sim.aml.rst delete mode 100644 documentation/apidoc/wntr.sim.core.rst delete mode 100644 documentation/apidoc/wntr.sim.epanet.rst delete mode 100644 documentation/apidoc/wntr.sim.hydraulics.rst delete mode 100644 documentation/apidoc/wntr.sim.results.rst delete mode 100644 documentation/apidoc/wntr.sim.rst delete mode 100644 documentation/apidoc/wntr.sim.solvers.rst delete mode 100644 documentation/apidoc/wntr.utils.disjoint_mapping.rst delete mode 100644 documentation/apidoc/wntr.utils.enumtools.rst delete mode 100644 documentation/apidoc/wntr.utils.logger.rst delete mode 100644 documentation/apidoc/wntr.utils.ordered_set.rst delete mode 100644 documentation/apidoc/wntr.utils.rst diff --git a/documentation/apidoc/wntr.epanet.io.rst b/documentation/apidoc/wntr.epanet.io.rst deleted file mode 100644 index 92600f190..000000000 --- a/documentation/apidoc/wntr.epanet.io.rst +++ /dev/null @@ -1,7 +0,0 @@ -wntr.epanet.io module -===================== - -.. automodule:: wntr.epanet.io - :members: - :no-undoc-members: - :show-inheritance: diff --git a/documentation/apidoc/wntr.epanet.msx.enums.rst b/documentation/apidoc/wntr.epanet.msx.enums.rst deleted file mode 100644 index 2f6312275..000000000 --- a/documentation/apidoc/wntr.epanet.msx.enums.rst +++ /dev/null @@ -1,7 +0,0 @@ -wntr.epanet.msx.enums module -============================ - -.. automodule:: wntr.epanet.msx.enums - :members: - :no-undoc-members: - :show-inheritance: diff --git a/documentation/apidoc/wntr.epanet.msx.exceptions.rst b/documentation/apidoc/wntr.epanet.msx.exceptions.rst deleted file mode 100644 index 0f920ebf8..000000000 --- a/documentation/apidoc/wntr.epanet.msx.exceptions.rst +++ /dev/null @@ -1,7 +0,0 @@ -wntr.epanet.msx.exceptions module -================================= - -.. automodule:: wntr.epanet.msx.exceptions - :members: - :no-undoc-members: - :show-inheritance: diff --git a/documentation/apidoc/wntr.epanet.msx.io.rst b/documentation/apidoc/wntr.epanet.msx.io.rst deleted file mode 100644 index eb608d561..000000000 --- a/documentation/apidoc/wntr.epanet.msx.io.rst +++ /dev/null @@ -1,7 +0,0 @@ -wntr.epanet.msx.io module -========================= - -.. automodule:: wntr.epanet.msx.io - :members: - :no-undoc-members: - :show-inheritance: diff --git a/documentation/apidoc/wntr.epanet.msx.rst b/documentation/apidoc/wntr.epanet.msx.rst deleted file mode 100644 index 83be9381a..000000000 --- a/documentation/apidoc/wntr.epanet.msx.rst +++ /dev/null @@ -1,20 +0,0 @@ -wntr.epanet.msx module -====================== - -.. automodule:: wntr.epanet.msx - :members: - :no-undoc-members: - :show-inheritance: - - -Submodules ----------- - -.. toctree:: - :maxdepth: 1 - - wntr.epanet.msx.enums - wntr.epanet.msx.exceptions - wntr.epanet.msx.io - wntr.epanet.msx.toolkit - diff --git a/documentation/apidoc/wntr.epanet.msx.toolkit.rst b/documentation/apidoc/wntr.epanet.msx.toolkit.rst deleted file mode 100644 index 4ae1e206a..000000000 --- a/documentation/apidoc/wntr.epanet.msx.toolkit.rst +++ /dev/null @@ -1,7 +0,0 @@ -wntr.epanet.msx.toolkit module -============================== - -.. automodule:: wntr.epanet.msx.toolkit - :members: - :no-undoc-members: - :show-inheritance: diff --git a/documentation/apidoc/wntr.epanet.rst b/documentation/apidoc/wntr.epanet.rst deleted file mode 100644 index a4fc3f35d..000000000 --- a/documentation/apidoc/wntr.epanet.rst +++ /dev/null @@ -1,21 +0,0 @@ -wntr.epanet package -=================== - -.. automodule:: wntr.epanet - :members: - :no-undoc-members: - :show-inheritance: - - -Submodules ----------- - -.. toctree:: - :maxdepth: 1 - - wntr.epanet.exceptions - wntr.epanet.io - wntr.epanet.msx - wntr.epanet.toolkit - wntr.epanet.util - diff --git a/documentation/apidoc/wntr.epanet.toolkit.rst b/documentation/apidoc/wntr.epanet.toolkit.rst deleted file mode 100644 index 3556c750a..000000000 --- a/documentation/apidoc/wntr.epanet.toolkit.rst +++ /dev/null @@ -1,7 +0,0 @@ -wntr.epanet.toolkit module -=================================== - -.. automodule:: wntr.epanet.toolkit - :members: - :no-undoc-members: - :show-inheritance: diff --git a/documentation/apidoc/wntr.epanet.util.rst b/documentation/apidoc/wntr.epanet.util.rst deleted file mode 100644 index 9e367ec0d..000000000 --- a/documentation/apidoc/wntr.epanet.util.rst +++ /dev/null @@ -1,7 +0,0 @@ -wntr.epanet.util module -======================= - -.. automodule:: wntr.epanet.util - :members: - :no-undoc-members: - :show-inheritance: diff --git a/documentation/apidoc/wntr.gis.geospatial.rst b/documentation/apidoc/wntr.gis.geospatial.rst deleted file mode 100644 index b1ecdef10..000000000 --- a/documentation/apidoc/wntr.gis.geospatial.rst +++ /dev/null @@ -1,7 +0,0 @@ -wntr.gis.geospatial module -===================================== - -.. automodule:: wntr.gis.geospatial - :members: - :no-undoc-members: - :show-inheritance: diff --git a/documentation/apidoc/wntr.gis.network.rst b/documentation/apidoc/wntr.gis.network.rst deleted file mode 100644 index 236c31d19..000000000 --- a/documentation/apidoc/wntr.gis.network.rst +++ /dev/null @@ -1,7 +0,0 @@ -wntr.gis.network module -===================================== - -.. automodule:: wntr.gis.network - :members: - :no-undoc-members: - :show-inheritance: diff --git a/documentation/apidoc/wntr.gis.rst b/documentation/apidoc/wntr.gis.rst deleted file mode 100644 index 69a81375c..000000000 --- a/documentation/apidoc/wntr.gis.rst +++ /dev/null @@ -1,15 +0,0 @@ -wntr.gis package -==================== - -.. automodule:: wntr.gis - :members: - :no-undoc-members: - :show-inheritance: - -Submodules ----------- - -.. toctree:: - - wntr.gis.network - wntr.gis.geospatial diff --git a/documentation/apidoc/wntr.graphics.color.rst b/documentation/apidoc/wntr.graphics.color.rst deleted file mode 100644 index 62faef5e7..000000000 --- a/documentation/apidoc/wntr.graphics.color.rst +++ /dev/null @@ -1,7 +0,0 @@ -wntr.graphics.color module -==================================== - -.. automodule:: wntr.graphics.color - :members: - :no-undoc-members: - :show-inheritance: diff --git a/documentation/apidoc/wntr.graphics.curve.rst b/documentation/apidoc/wntr.graphics.curve.rst deleted file mode 100644 index 61823bf13..000000000 --- a/documentation/apidoc/wntr.graphics.curve.rst +++ /dev/null @@ -1,7 +0,0 @@ -wntr.graphics.curve module -==================================== - -.. automodule:: wntr.graphics.curve - :members: - :no-undoc-members: - :show-inheritance: diff --git a/documentation/apidoc/wntr.graphics.layer.rst b/documentation/apidoc/wntr.graphics.layer.rst deleted file mode 100644 index cb0ce7e24..000000000 --- a/documentation/apidoc/wntr.graphics.layer.rst +++ /dev/null @@ -1,7 +0,0 @@ -wntr.graphics.layer module -==================================== - -.. automodule:: wntr.graphics.layer - :members: - :no-undoc-members: - :show-inheritance: diff --git a/documentation/apidoc/wntr.graphics.network.rst b/documentation/apidoc/wntr.graphics.network.rst deleted file mode 100644 index a87b73ded..000000000 --- a/documentation/apidoc/wntr.graphics.network.rst +++ /dev/null @@ -1,7 +0,0 @@ -wntr.graphics.network module -==================================== - -.. automodule:: wntr.graphics.network - :members: - :no-undoc-members: - :show-inheritance: diff --git a/documentation/apidoc/wntr.graphics.rst b/documentation/apidoc/wntr.graphics.rst deleted file mode 100644 index 6d05f1b27..000000000 --- a/documentation/apidoc/wntr.graphics.rst +++ /dev/null @@ -1,18 +0,0 @@ -wntr.graphics package -===================== - -.. automodule:: wntr.graphics - :members: - :no-undoc-members: - :show-inheritance: - -Submodules ----------- - -.. toctree:: - - wntr.graphics.network - wntr.graphics.layer - wntr.graphics.curve - wntr.graphics.color - diff --git a/documentation/apidoc/wntr.metrics.economic.rst b/documentation/apidoc/wntr.metrics.economic.rst deleted file mode 100644 index 5ca22bda1..000000000 --- a/documentation/apidoc/wntr.metrics.economic.rst +++ /dev/null @@ -1,7 +0,0 @@ -wntr.metrics.economic module -============================= - -.. automodule:: wntr.metrics.economic - :members: - :no-undoc-members: - :show-inheritance: diff --git a/documentation/apidoc/wntr.metrics.hydraulic.rst b/documentation/apidoc/wntr.metrics.hydraulic.rst deleted file mode 100644 index 83432d025..000000000 --- a/documentation/apidoc/wntr.metrics.hydraulic.rst +++ /dev/null @@ -1,7 +0,0 @@ -wntr.metrics.hydraulic module -================================ - -.. automodule:: wntr.metrics.hydraulic - :members: - :no-undoc-members: - :show-inheritance: diff --git a/documentation/apidoc/wntr.metrics.misc.rst b/documentation/apidoc/wntr.metrics.misc.rst deleted file mode 100644 index 99dba99d6..000000000 --- a/documentation/apidoc/wntr.metrics.misc.rst +++ /dev/null @@ -1,7 +0,0 @@ -wntr.metrics.misc module -========================= - -.. automodule:: wntr.metrics.misc - :members: - :no-undoc-members: - :show-inheritance: diff --git a/documentation/apidoc/wntr.metrics.rst b/documentation/apidoc/wntr.metrics.rst deleted file mode 100644 index 9278e295e..000000000 --- a/documentation/apidoc/wntr.metrics.rst +++ /dev/null @@ -1,18 +0,0 @@ -wntr.metrics package -====================== - -.. automodule:: wntr.metrics - :members: - :no-undoc-members: - :show-inheritance: - -Submodules ----------- - -.. toctree:: - - wntr.metrics.topographic - wntr.metrics.hydraulic - wntr.metrics.water_security - wntr.metrics.economic - wntr.metrics.misc diff --git a/documentation/apidoc/wntr.metrics.topographic.rst b/documentation/apidoc/wntr.metrics.topographic.rst deleted file mode 100644 index 992b1ce5e..000000000 --- a/documentation/apidoc/wntr.metrics.topographic.rst +++ /dev/null @@ -1,7 +0,0 @@ -wntr.metrics.topographic module -=============================== - -.. automodule:: wntr.metrics.topographic - :members: - :no-undoc-members: - :show-inheritance: diff --git a/documentation/apidoc/wntr.metrics.water_security.rst b/documentation/apidoc/wntr.metrics.water_security.rst deleted file mode 100644 index a1d0629c3..000000000 --- a/documentation/apidoc/wntr.metrics.water_security.rst +++ /dev/null @@ -1,7 +0,0 @@ -wntr.metrics.water_security module -===================================== - -.. automodule:: wntr.metrics.water_security - :members: - :no-undoc-members: - :show-inheritance: diff --git a/documentation/apidoc/wntr.morph.link.rst b/documentation/apidoc/wntr.morph.link.rst deleted file mode 100644 index 94d3d0a9f..000000000 --- a/documentation/apidoc/wntr.morph.link.rst +++ /dev/null @@ -1,7 +0,0 @@ -wntr.morph.link module -===================================== - -.. automodule:: wntr.morph.link - :members: - :no-undoc-members: - :show-inheritance: diff --git a/documentation/apidoc/wntr.morph.node.rst b/documentation/apidoc/wntr.morph.node.rst deleted file mode 100644 index 70b826f60..000000000 --- a/documentation/apidoc/wntr.morph.node.rst +++ /dev/null @@ -1,7 +0,0 @@ -wntr.morph.node module -===================================== - -.. automodule:: wntr.morph.node - :members: - :no-undoc-members: - :show-inheritance: diff --git a/documentation/apidoc/wntr.morph.rst b/documentation/apidoc/wntr.morph.rst deleted file mode 100644 index 888d0a1ef..000000000 --- a/documentation/apidoc/wntr.morph.rst +++ /dev/null @@ -1,16 +0,0 @@ -wntr.morph package -==================== - -.. automodule:: wntr.morph - :members: - :no-undoc-members: - :show-inheritance: - -Submodules ----------- - -.. toctree:: - - wntr.morph.node - wntr.morph.link - wntr.morph.skel diff --git a/documentation/apidoc/wntr.morph.skel.rst b/documentation/apidoc/wntr.morph.skel.rst deleted file mode 100644 index 2969ece7b..000000000 --- a/documentation/apidoc/wntr.morph.skel.rst +++ /dev/null @@ -1,7 +0,0 @@ -wntr.morph.skel module -===================================== - -.. automodule:: wntr.morph.skel - :members: - :no-undoc-members: - :show-inheritance: diff --git a/documentation/apidoc/wntr.msx.base.rst b/documentation/apidoc/wntr.msx.base.rst deleted file mode 100644 index 9df2031eb..000000000 --- a/documentation/apidoc/wntr.msx.base.rst +++ /dev/null @@ -1,7 +0,0 @@ -wntr.msx.base module -==================== - -.. automodule:: wntr.msx.base - :members: - :undoc-members: - :show-inheritance: diff --git a/documentation/apidoc/wntr.msx.elements.rst b/documentation/apidoc/wntr.msx.elements.rst deleted file mode 100644 index 9bc59e92d..000000000 --- a/documentation/apidoc/wntr.msx.elements.rst +++ /dev/null @@ -1,7 +0,0 @@ -wntr.msx.elements module -======================== - -.. automodule:: wntr.msx.elements - :members: - :undoc-members: - :show-inheritance: diff --git a/documentation/apidoc/wntr.msx.library.rst b/documentation/apidoc/wntr.msx.library.rst deleted file mode 100644 index dc10f1f4e..000000000 --- a/documentation/apidoc/wntr.msx.library.rst +++ /dev/null @@ -1,7 +0,0 @@ -wntr.msx.library module -======================= - -.. automodule:: wntr.msx.library - :members: - :undoc-members: - :show-inheritance: diff --git a/documentation/apidoc/wntr.msx.model.rst b/documentation/apidoc/wntr.msx.model.rst deleted file mode 100644 index ec8a7934e..000000000 --- a/documentation/apidoc/wntr.msx.model.rst +++ /dev/null @@ -1,7 +0,0 @@ -wntr.msx.model module -===================== - -.. automodule:: wntr.msx.model - :members: - :undoc-members: - :show-inheritance: diff --git a/documentation/apidoc/wntr.msx.options.rst b/documentation/apidoc/wntr.msx.options.rst deleted file mode 100644 index 1e1b0c622..000000000 --- a/documentation/apidoc/wntr.msx.options.rst +++ /dev/null @@ -1,7 +0,0 @@ -wntr.msx.options module -======================= - -.. automodule:: wntr.msx.options - :members: - :undoc-members: - :show-inheritance: diff --git a/documentation/apidoc/wntr.msx.rst b/documentation/apidoc/wntr.msx.rst deleted file mode 100644 index 00b1530eb..000000000 --- a/documentation/apidoc/wntr.msx.rst +++ /dev/null @@ -1,20 +0,0 @@ -wntr.msx package -================ - -.. automodule:: wntr.msx - :members: - :undoc-members: - :show-inheritance: - - -Submodules ----------- - -.. toctree:: - :maxdepth: 1 - - wntr.msx.base - wntr.msx.elements - wntr.msx.library - wntr.msx.model - wntr.msx.options diff --git a/documentation/apidoc/wntr.network.base.rst b/documentation/apidoc/wntr.network.base.rst deleted file mode 100644 index cd3152561..000000000 --- a/documentation/apidoc/wntr.network.base.rst +++ /dev/null @@ -1,8 +0,0 @@ -wntr.network.base module -===================================== - -.. automodule:: wntr.network.base - :members: - :inherited-members: - :no-undoc-members: - :show-inheritance: diff --git a/documentation/apidoc/wntr.network.controls.rst b/documentation/apidoc/wntr.network.controls.rst deleted file mode 100644 index 07036c787..000000000 --- a/documentation/apidoc/wntr.network.controls.rst +++ /dev/null @@ -1,8 +0,0 @@ -wntr.network.controls module -=================================== - -.. automodule:: wntr.network.controls - :members: - :inherited-members: - :no-undoc-members: - :show-inheritance: diff --git a/documentation/apidoc/wntr.network.elements.rst b/documentation/apidoc/wntr.network.elements.rst deleted file mode 100644 index 26cef395e..000000000 --- a/documentation/apidoc/wntr.network.elements.rst +++ /dev/null @@ -1,8 +0,0 @@ -wntr.network.elements module -===================================== - -.. automodule:: wntr.network.elements - :members: - :inherited-members: - :no-undoc-members: - :show-inheritance: diff --git a/documentation/apidoc/wntr.network.io.rst b/documentation/apidoc/wntr.network.io.rst deleted file mode 100644 index 190a5e351..000000000 --- a/documentation/apidoc/wntr.network.io.rst +++ /dev/null @@ -1,8 +0,0 @@ -wntr.network.io module -=================================== - -.. automodule:: wntr.network.io - :members: - :inherited-members: - :no-undoc-members: - :show-inheritance: diff --git a/documentation/apidoc/wntr.network.layer.rst b/documentation/apidoc/wntr.network.layer.rst deleted file mode 100644 index ef1a5c171..000000000 --- a/documentation/apidoc/wntr.network.layer.rst +++ /dev/null @@ -1,8 +0,0 @@ -wntr.network.layer module -===================================== - -.. automodule:: wntr.network.layer - :members: - :inherited-members: - :no-undoc-members: - :show-inheritance: diff --git a/documentation/apidoc/wntr.network.model.rst b/documentation/apidoc/wntr.network.model.rst deleted file mode 100644 index c40d391e4..000000000 --- a/documentation/apidoc/wntr.network.model.rst +++ /dev/null @@ -1,8 +0,0 @@ -wntr.network.model module -===================================== - -.. automodule:: wntr.network.model - :members: - :inherited-members: - :no-undoc-members: - :show-inheritance: diff --git a/documentation/apidoc/wntr.network.options.rst b/documentation/apidoc/wntr.network.options.rst deleted file mode 100644 index 69baf0350..000000000 --- a/documentation/apidoc/wntr.network.options.rst +++ /dev/null @@ -1,7 +0,0 @@ -wntr.network.options module -===================================== - -.. automodule:: wntr.network.options - :members: - :no-undoc-members: - :show-inheritance: diff --git a/documentation/apidoc/wntr.network.rst b/documentation/apidoc/wntr.network.rst deleted file mode 100644 index 05dbe11ca..000000000 --- a/documentation/apidoc/wntr.network.rst +++ /dev/null @@ -1,21 +0,0 @@ -wntr.network package -==================== - -.. automodule:: wntr.network - :members: - :no-undoc-members: - :show-inheritance: - -Submodules ----------- - -.. toctree:: - - wntr.network.base - wntr.network.controls - wntr.network.elements - wntr.network.io - wntr.network.model - wntr.network.layer - wntr.network.options - diff --git a/documentation/apidoc/wntr.rst b/documentation/apidoc/wntr.rst deleted file mode 100644 index 7dd9f2ca5..000000000 --- a/documentation/apidoc/wntr.rst +++ /dev/null @@ -1,27 +0,0 @@ -.. _api_documentation: - -API documentation -=================== - -.. automodule:: wntr - :members: - :no-undoc-members: - :show-inheritance: - -Subpackages ------------ - -.. toctree:: - :maxdepth: 1 - - wntr.epanet - wntr.graphics - wntr.gis - wntr.metrics - wntr.morph - wntr.network - wntr.msx - wntr.scenario - wntr.sim - wntr.utils - diff --git a/documentation/apidoc/wntr.scenario.earthquake.rst b/documentation/apidoc/wntr.scenario.earthquake.rst deleted file mode 100644 index 3daaddef7..000000000 --- a/documentation/apidoc/wntr.scenario.earthquake.rst +++ /dev/null @@ -1,7 +0,0 @@ -wntr.scenario.earthquake module -=============================== - -.. automodule:: wntr.scenario.earthquake - :members: - :no-undoc-members: - :show-inheritance: diff --git a/documentation/apidoc/wntr.scenario.fragility_curve.rst b/documentation/apidoc/wntr.scenario.fragility_curve.rst deleted file mode 100644 index 1fcd14d21..000000000 --- a/documentation/apidoc/wntr.scenario.fragility_curve.rst +++ /dev/null @@ -1,7 +0,0 @@ -wntr.scenario.fragility_curve module -===================================== - -.. automodule:: wntr.scenario.fragility_curve - :members: - :no-undoc-members: - :show-inheritance: diff --git a/documentation/apidoc/wntr.scenario.rst b/documentation/apidoc/wntr.scenario.rst deleted file mode 100644 index 88a7aec78..000000000 --- a/documentation/apidoc/wntr.scenario.rst +++ /dev/null @@ -1,16 +0,0 @@ -wntr.scenario package -===================== - -.. automodule:: wntr.scenario - :members: - :no-undoc-members: - :show-inheritance: - -Submodules ----------- - -.. toctree:: - - wntr.scenario.earthquake - wntr.scenario.fragility_curve - diff --git a/documentation/apidoc/wntr.sim.aml.rst b/documentation/apidoc/wntr.sim.aml.rst deleted file mode 100644 index ffdb96180..000000000 --- a/documentation/apidoc/wntr.sim.aml.rst +++ /dev/null @@ -1,12 +0,0 @@ -wntr.sim.aml module -============================ - -.. automodule:: wntr.sim.aml.aml - :members: - :no-undoc-members: - :show-inheritance: - -.. automodule:: wntr.sim.aml.expr - :members: - :no-undoc-members: - :show-inheritance: diff --git a/documentation/apidoc/wntr.sim.core.rst b/documentation/apidoc/wntr.sim.core.rst deleted file mode 100644 index fa5e1eb9c..000000000 --- a/documentation/apidoc/wntr.sim.core.rst +++ /dev/null @@ -1,7 +0,0 @@ -wntr.sim.core module -============================= - -.. automodule:: wntr.sim.core - :members: - :no-undoc-members: - :show-inheritance: diff --git a/documentation/apidoc/wntr.sim.epanet.rst b/documentation/apidoc/wntr.sim.epanet.rst deleted file mode 100644 index 2a6fab645..000000000 --- a/documentation/apidoc/wntr.sim.epanet.rst +++ /dev/null @@ -1,7 +0,0 @@ -wntr.sim.epanet module -====================== - -.. automodule:: wntr.sim.epanet - :members: - :no-undoc-members: - :show-inheritance: diff --git a/documentation/apidoc/wntr.sim.hydraulics.rst b/documentation/apidoc/wntr.sim.hydraulics.rst deleted file mode 100644 index 289b92411..000000000 --- a/documentation/apidoc/wntr.sim.hydraulics.rst +++ /dev/null @@ -1,7 +0,0 @@ -wntr.sim.hydraulics module -============================== - -.. automodule:: wntr.sim.hydraulics - :members: - :no-undoc-members: - :show-inheritance: diff --git a/documentation/apidoc/wntr.sim.results.rst b/documentation/apidoc/wntr.sim.results.rst deleted file mode 100644 index 6e6c78b6f..000000000 --- a/documentation/apidoc/wntr.sim.results.rst +++ /dev/null @@ -1,7 +0,0 @@ -wntr.sim.results module -============================== - -.. automodule:: wntr.sim.results - :members: - :no-undoc-members: - :show-inheritance: diff --git a/documentation/apidoc/wntr.sim.rst b/documentation/apidoc/wntr.sim.rst deleted file mode 100644 index cc230a09d..000000000 --- a/documentation/apidoc/wntr.sim.rst +++ /dev/null @@ -1,20 +0,0 @@ -wntr.sim package -================ - -.. automodule:: wntr.sim - :members: - :no-undoc-members: - :show-inheritance: - -Submodules ----------- - -.. toctree:: - - wntr.sim.core - wntr.sim.epanet - wntr.sim.hydraulics - wntr.sim.results - wntr.sim.solvers - wntr.sim.aml - diff --git a/documentation/apidoc/wntr.sim.solvers.rst b/documentation/apidoc/wntr.sim.solvers.rst deleted file mode 100644 index 4bd3ac9b2..000000000 --- a/documentation/apidoc/wntr.sim.solvers.rst +++ /dev/null @@ -1,7 +0,0 @@ -wntr.sim.solvers module -============================ - -.. automodule:: wntr.sim.solvers - :members: - :no-undoc-members: - :show-inheritance: diff --git a/documentation/apidoc/wntr.utils.disjoint_mapping.rst b/documentation/apidoc/wntr.utils.disjoint_mapping.rst deleted file mode 100644 index de6ab742d..000000000 --- a/documentation/apidoc/wntr.utils.disjoint_mapping.rst +++ /dev/null @@ -1,8 +0,0 @@ -wntr.utils.disjoint_mapping module -================================== - -.. automodule:: wntr.utils.disjoint_mapping - :members: - :inherited-members: - :no-undoc-members: - :show-inheritance: diff --git a/documentation/apidoc/wntr.utils.enumtools.rst b/documentation/apidoc/wntr.utils.enumtools.rst deleted file mode 100644 index c856c713c..000000000 --- a/documentation/apidoc/wntr.utils.enumtools.rst +++ /dev/null @@ -1,7 +0,0 @@ -wntr.utils.enumtools module -=========================== - -.. automodule:: wntr.utils.enumtools - :members: - :no-undoc-members: - :show-inheritance: diff --git a/documentation/apidoc/wntr.utils.logger.rst b/documentation/apidoc/wntr.utils.logger.rst deleted file mode 100644 index a778dc33d..000000000 --- a/documentation/apidoc/wntr.utils.logger.rst +++ /dev/null @@ -1,7 +0,0 @@ -wntr.utils.logger module -======================== - -.. automodule:: wntr.utils.logger - :members: - :no-undoc-members: - :show-inheritance: diff --git a/documentation/apidoc/wntr.utils.ordered_set.rst b/documentation/apidoc/wntr.utils.ordered_set.rst deleted file mode 100644 index 45610dd78..000000000 --- a/documentation/apidoc/wntr.utils.ordered_set.rst +++ /dev/null @@ -1,8 +0,0 @@ -wntr.utils.ordered_set module -=================================== - -.. automodule:: wntr.utils.ordered_set - :members: - :inherited-members: - :no-undoc-members: - :show-inheritance: diff --git a/documentation/apidoc/wntr.utils.rst b/documentation/apidoc/wntr.utils.rst deleted file mode 100644 index f66334b01..000000000 --- a/documentation/apidoc/wntr.utils.rst +++ /dev/null @@ -1,18 +0,0 @@ -wntr.utils package -================== - -.. automodule:: wntr.utils - :members: - :inherited-members: - :no-undoc-members: - :show-inheritance: - -Submodules ----------- - -.. toctree:: - - wntr.utils.disjoint_mapping - wntr.utils.enumtools - wntr.utils.logger - wntr.utils.ordered_set From fd965c742a1c8efe68743edd92b8878d6deffe9c Mon Sep 17 00:00:00 2001 From: dbhart Date: Fri, 17 Nov 2023 11:40:48 -0700 Subject: [PATCH 54/75] Exceptions/docs-theme merges --- documentation/conf.py | 122 +++++++++++++++++++++++++------- documentation/errors.rst | 1 + documentation/hydraulics.rst | 15 ++-- documentation/index.rst | 60 +++++----------- documentation/reference.rst | 132 +++++++++++++++++++++-------------- wntr/epanet/__init__.py | 3 +- wntr/epanet/exceptions.py | 7 +- wntr/network/options.py | 19 ++--- 8 files changed, 211 insertions(+), 148 deletions(-) diff --git a/documentation/conf.py b/documentation/conf.py index d45b8e778..0fc5bf7c2 100644 --- a/documentation/conf.py +++ b/documentation/conf.py @@ -40,16 +40,51 @@ 'sphinx.ext.autosummary', 'sphinx.ext.napoleon', 'sphinx.ext.intersphinx', -] + 'sphinx_design', + 'sphinxcontrib.bibtex' +] + +add_function_parentheses = True +add_module_names = False +python_display_short_literal_types = True + +toc_object_entries = True +toc_object_entries_show_parents = 'hide' + +napoleon_google_docstring = True +napoleon_numpy_docstring = True +napoleon_include_init_with_doc = True +napoleon_include_private_with_doc = False +napoleon_include_special_with_doc = False +napoleon_use_admonition_for_examples = False +napoleon_use_admonition_for_notes = False +napoleon_use_admonition_for_references = True +napoleon_preprocess_types = False +napoleon_use_ivar = True +napoleon_use_param = True +napoleon_use_rtype = True +napoleon_use_keyword = False +napoleon_custom_sections = ['Read-only Simulation Attributes', 'Class Methods', 'Enum Members'] + +# viewcode_import = False + +autodoc_default_options = { + 'undoc-members': True, + 'private-members': False, + 'special-members': False, + 'inherited-members': True, + 'show-inheritance': True, + 'member-order': 'groupwise', +} + +autodoc_class_signature = 'separated' +autodoc_typehints = 'description' +autodoc_typehints_format = 'short' +autodoc_typehints_description_target = 'documented' +autodoc_type_aliases = {'DataFrame': 'pandas DataFrame',} + +autoclass_content = 'class' -autosummary_generate = True -napoleon_use_rtype = False -viewcode_import = True -numpydoc_show_class_members = True -numpydoc_show_inherited_class_members = False -numpydoc_class_members_toctree = False -autodoc_member_order = 'bysource' -autoclass_content = 'both' numfig=True numfig_format = {'figure': 'Figure %s', 'table': 'Table %s', 'code-block': 'Listing %s'} @@ -57,7 +92,8 @@ templates_path = ['_templates'] import glob -autosummary_generate = glob.glob("apidoc/*.rst") +autosummary_generate = ["wntr-api.rst",] + glob.glob("apidoc/*.rst") +autosummary_generate_overwrite = True # The suffix(es) of source filenames. # You can specify multiple suffix as a list of string: @@ -75,6 +111,10 @@ copyright = u'2023 National Technology & Engineering Solutions of Sandia, LLC (NTESS)' author = u'WNTR Developers' +bibtex_bibfiles = ['references.bib', 'citations.bib'] +bibtex_default_style = 'plain' +bibtex_reference_style = 'label' + # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the # built documents. @@ -91,6 +131,13 @@ # Usually you set "language" from the command line for these cases. language = 'en' +intersphinx_mapping = { + "python": ("https://docs.python.org/3", (None, "_local/python-objects.inv")), + "matplotlib": ("https://matplotlib.org/stable/", (None, "_local/matplotlib-objects.inv")), + "numpy": ("https://numpy.org/doc/stable/", (None, "_local/numpy-objects.inv")), + "pandas": ("https://pandas.pydata.org/docs/", (None, "_local/pandas-objects.inv")), +} + # There are two options for replacing |today|: either, you set today to some # non-false value, then it is used: #today = '' @@ -104,11 +151,9 @@ # The reST default role (used for this markup: `text`) to use for all # documents. #default_role = None -napoleon_custom_sections = ['Read-only Simulation Attributes', 'Class Methods', 'Enum Members', 'Model Description'] # If true, '()' will be appended to :func: etc. cross-reference text. #add_function_parentheses = True -#autodoc_type_aliases = {'DataFrame': 'pandas DataFrame', 'MsxVariable': ':class:`~wntr.msx.model.MsxVariable`', 'NoteType': ':class:`~wntr.epanet.util.NoteType`'} # If true, the current module name will be prepended to all description # unit titles (such as .. function::). @@ -129,7 +174,7 @@ # If true, `todo` and `todoList` produce output, else they produce nothing. todo_include_todos = True -html_extra_path = ['extra'] + # -- Options for HTML output ---------------------------------------------- @@ -137,26 +182,53 @@ # a list of builtin themes. #html_theme = 'sphinx_rtd_theme' -def setup(app): - app.add_css_file( "wntr.css") on_rtd = os.environ.get('READTHEDOCS', None) == 'True' if not on_rtd: # only import and set the theme if we're building docs locally - import sphinx_rtd_theme - html_theme = 'sphinx_rtd_theme' - html_theme_path = [sphinx_rtd_theme.get_html_theme_path()] - html_style = 'wntr.css' + html_theme = 'pydata_sphinx_theme' + else: + def setup(app): + app.add_css_file( "wntr.css") html_theme = 'default' # html_context = { # 'css_files': ['_static/wntr.css'], # } - + # Theme options are theme-specific and customize the look and feel of a theme # further. For a list of options available for each theme, see the # documentation. -#html_theme_options = {} - +html_theme_options = { + "icon_links": [ + { + # Label for this link + "name": "GitHub", + # URL where the link will redirect + "url": "https://github.com/USEPA/WNTR", # required + # Icon class (if "type": "fontawesome"), or path to local image (if "type": "local") + "icon": "fa-brands fa-github", + # The type of image to be used (see below for details) + "type": "fontawesome", + }, + { + "name": "Sandia National Laboratories", + "url": "https://sandia.gov", # required + "icon": "_static/snl_logo.png", + "type": "local", + }, + { + "name": "U.S. Environmental Protection Agency", + "url": "https://epa.gov", # required + "icon": "_static/epa_logo.png", + "type": "local", + }, + ], + "use_edit_page_button": False, + "primary_sidebar_end": ["indices.html"], + "show_toc_level": 2, + # "secondary_sidebar_items": ["page-toc"], #["page-toc", "edit-this-page", "sourcelink"], + "navbar_end": [ "theme-switcher.html", "navbar-icon-links.html",], +} # Add any paths that contain custom themes here, relative to this directory. #html_theme_path = [] @@ -169,12 +241,12 @@ def setup(app): # The name of an image file (relative to this directory) to place at the top # of the sidebar. -#html_logo = 'figures/wntr.png' +html_logo = '_static/logo.jpg' # The name of an image file (within the static path) to use as favicon of the # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 # pixels large. -#html_favicon = None +html_favicon = "_static/wntr-favicon.svg" # The style sheet to use for HTML and HTML Help pages. A file of that name # must exist either in Sphinx' static/ path, or in one of the custom paths @@ -189,7 +261,7 @@ def setup(app): # Add any extra paths that contain custom files (such as robots.txt or # .htaccess) here, relative to this directory. These files are copied # directly to the root of the documentation. -#html_extra_path = [] +html_extra_path = ['_data'] # If not '', a 'Last updated on:' timestamp is inserted at every page bottom, # using the given strftime format. diff --git a/documentation/errors.rst b/documentation/errors.rst index 5206caaba..bd945d6f7 100644 --- a/documentation/errors.rst +++ b/documentation/errors.rst @@ -2,6 +2,7 @@ \clearpage +.. _epanet-errors: Errors and debugging ==================== diff --git a/documentation/hydraulics.rst b/documentation/hydraulics.rst index f284024b7..56243a2ad 100644 --- a/documentation/hydraulics.rst +++ b/documentation/hydraulics.rst @@ -9,11 +9,10 @@ Hydraulic simulation WNTR contains two simulators: the EpanetSimulator and the WNTRSimulator. See :ref:`software_framework` for more information on features and limitations of these simulators. -Additional hydraulic simulation options are discussed in :ref:`advanced_simulation`. EpanetSimulator ----------------- -The EpanetSimulator can be used to run a hydraulic simulation using the EPANET 2.00.12 Programmer's Toolkit [Ross00]_ or EPANET 2.2.0 Programmer's Toolkit [RWTS20]_. +The EpanetSimulator can be used to run EPANET 2.00.12 Programmer's Toolkit :cite:p:`ross00` or EPANET 2.2.0 Programmer's Toolkit :cite:p:`rwts20`. EPANET 2.2.0 is used by default and runs demand-driven and pressure dependent hydraulic analysis. EPANET 2.00.12 runs demand-driven hydraulic analysis only. Both versions can also run water quality simulations, as described in :ref:`water_quality_simulation`. @@ -112,7 +111,7 @@ More information on water network options can be found in :ref:`options`. Mass balance at nodes ------------------------- -Both simulators use the mass balance equations from EPANET [Ross00]_: +Both simulators use the mass balance equations from EPANET :cite:p:`ross00`: .. math:: @@ -128,7 +127,7 @@ If water is flowing out of node :math:`n` and into pipe :math:`p`, then Headloss in pipes ------------------------- -Both simulators use conservation of energy formulas from EPANET [Ross00]_. +Both simulators use conservation of energy formulas from EPANET :cite:p:`ross00`. While the EpanetSimulator can use the Hazen-Williams and Chezy-Manning pipe head loss formulas, the WNTRSimulator uses only the Hazen-Williams head loss formula, shown below. @@ -226,7 +225,7 @@ The mass balance and headloss equations described above are solved by simultaneously determining demand along with the network pressures and flow rates. Both simulators can run hydraulics using a pressure dependent demand simulation -according to the following pressure-demand relationship [WaSM88]_: +according to the following pressure-demand relationship :cite:p:`wasm88`: .. math:: @@ -309,7 +308,7 @@ Users interested in using the EpanetSimulator to model leaks can still do so by emitter coefficients. When using the WNTRSimulator, leaks are modeled with a general form of the equation proposed by Crowl and Louvar -[CrLo02]_ where the mass flow rate of fluid through the hole is expressed as: +:cite:p:`crlo02` where the mass flow rate of fluid through the hole is expressed as: .. math:: @@ -329,9 +328,9 @@ where :math:`g` is the acceleration of gravity (m/s²), and :math:`\rho` is the density of the fluid (kg/m³). -The default discharge coefficient is 0.75 (assuming turbulent flow) [Lamb01]_, but +The default discharge coefficient is 0.75 (assuming turbulent flow) :cite:p:`lamb01`, but the user can specify other values if needed. -The value of :math:`\alpha` is set to 0.5 (assuming large leaks out of steel pipes) [Lamb01]_ and currently cannot be changed by the user. +The value of :math:`\alpha` is set to 0.5 (assuming large leaks out of steel pipes) :cite:p:`lamb01` and currently cannot be changed by the user. Leaks can be added to junctions and tanks. A pipe break is modeled using a leak area large enough to drain the pipe. diff --git a/documentation/index.rst b/documentation/index.rst index 5c56728c4..b7ba52ee4 100644 --- a/documentation/index.rst +++ b/documentation/index.rst @@ -1,47 +1,28 @@ -.. figure:: figures/logo.jpg +.. figure:: _static/logo.jpg :scale: 10 % :alt: Logo +======================================== +Water Network Tool for Resilience (WNTR) +======================================== + The Water Network Tool for Resilience (WNTR) is an EPANET compatible Python package designed to simulate and analyze resilience of water distribution networks. +The official WNTR software repository is in the U.S. EPA's GitHub repository +(https://github.com/USEPA/WNTR); releases are also made available via PyPI and conda-forge +(see :ref:`installation`). + .. toctree:: :maxdepth: 1 + :hidden: - overview - installation - framework - units - getting_started - waternetworkmodel - model_io - controls - networkxgraph - layers - options - hydraulics - waterquality - waterquality_msx - resultsobject - disaster_models - criticality - resilience - fragility - morph - graphics - gis - advancedsim - errors - license - whatsnew - developers + userguide + wntr-api users - API documentation - acronyms - reference - + Citing WNTR ------------------ +=========== To cite WNTR, use one of the following references: * Klise, K.A., Hart, D.B., Bynum, M., Hogge, J., Haxton, T., Murray, R., Burkhardt, J. (2020). Water Network Tool for Resilience (WNTR) User Manual: Version 0.2.3. U.S. EPA Office of Research and Development, Washington, DC, EPA/600/R-20/185, 82p. @@ -50,8 +31,9 @@ To cite WNTR, use one of the following references: * Klise, K.A., Bynum, M., Moriarty, D., Murray, R. (2017). A software framework for assessing the resilience of drinking water systems to disasters with an example earthquake case study, Environmental Modelling and Software, 95, 420-431, doi: 10.1016/j.envsoft.2017.06.022 + US EPA Disclaimer ---------------------- +================= The U.S. Environmental Protection Agency through its Office of Research and Development funded and collaborated in the research described here under an Interagency Agreement with the Department of Energy's Sandia National Laboratories. @@ -60,17 +42,9 @@ the contents necessarily reflect the views of the Agency. Mention of trade names EPA approval, endorsement, or recommendation. Sandia Funding Statement --------------------------------- +======================== Sandia National Laboratories is a multimission laboratory managed and operated by National Technology and Engineering Solutions of Sandia, LLC., a wholly owned subsidiary of Honeywell International, Inc., for the U.S. Department of Energy's National Nuclear Security Administration under contract DE-NA-0003525. -Indices and tables -================== - -* :ref:`genindex` -* :ref:`modindex` -* :ref:`search` - - diff --git a/documentation/reference.rst b/documentation/reference.rst index bd638f8cf..d365df535 100644 --- a/documentation/reference.rst +++ b/documentation/reference.rst @@ -2,93 +2,123 @@ \clearpage -References -==================== - .. only:: html - Due to limitations with cross referenced citations in reStructuredText (e.g., commas and spaces are not supported), - citations are cross referenced using a 6 digit notation [*]_. + References + ========== + + +.. raw:: latex + + \begingroup + \def\section#1#2{} + \def\chapter#1#2{} + \begin{thebibliography}{1234} + +.. + [ALA01] American Lifelines Alliance. (2001). Seismic Fragility Formulations for Water Systems, Part 1 and 2. Report for the American Lifelines Alliance, ASCE (Ed.) Reston, VA: American Society of Civil Engineers. April 2001. -.. [ALA01] American Lifelines Alliance. (2001). Seismic Fragility Formulations for Water Systems, Part 1 and 2. Report for the American Lifelines Alliance, ASCE (Ed.) Reston, VA: American Society of Civil Engineers. April 2001. +.. + [AwGB90] Awumah, K., Goulter, I., and Bhatt, S.K. (1990). Assessment of reliability in water distribution networks using entropy based measures. Stochastic Hydrology and Hydraulics, 4(4), 309-320. -.. [AwGB90] Awumah, K., Goulter, I., and Bhatt, S.K. (1990). Assessment of reliability in water distribution networks using entropy based measures. Stochastic Hydrology and Hydraulics, 4(4), 309-320. +.. + [BaRR13] Barker, K., Ramirez-Marquez, J.E., and Rocco, C.M. (2013). Resilience-based network component importance measures. Reliability Engineering and System Safety, 117, 89-97. -.. [BaRR13] Barker, K., Ramirez-Marquez, J.E., and Rocco, C.M. (2013). Resilience-based network component importance measures. Reliability Engineering and System Safety, 117, 89-97. +.. + [Bieni19] Bieniek, T., van Andel, B., and Bø, T.I. (2019). Bidirectional UTM-WGS84 converter for python, Retrieved on February 5, 2019 from https://github.com/Turbo87/utm. -.. [Bieni19] Bieniek, T., van Andel, B., and Bø, T.I. (2019). Bidirectional UTM-WGS84 converter for python, Retrieved on February 5, 2019 from https://github.com/Turbo87/utm. +.. + [CrLo02] Crowl, D.A., and Louvar, J.F. (2011). Chemical Process Safety: Fundamentals with Applications, 3 edition. Upper Saddle River, NJ: Prentice Hall, 720p. -.. [BWMS20] Burkhardt, J. B., Woo, J., Mason, J., Shang, F., Triantafyllidou, S., Schock, M.R., Lytle, D., and Murray, R. (2020). Framework for Modeling Lead in Premise Plumbing Systems Using EPANET. Journal of Water Resources Planning and Management, 146(12). https://doi.org/10.1061/(asce)wr.1943-5452.0001304 PMID:33627937. +.. + [ELLT12] Eto, J.H., LaCommare, K.H., Larsen, P.H., Todd, A., and Fisher, E. (2012). An Examination of Temporal Trends in Electricity Reliability Based on Reports from U.S. Electric Utilities. Lawrence Berkeley National Laboratory Report Number LBNL-5268E. Berkeley, CA: Ernest Orlando Lawrence Berkeley National Laboratory, 68p. -.. [CrLo02] Crowl, D.A., and Louvar, J.F. (2011). Chemical Process Safety: Fundamentals with Applications, 3 edition. Upper Saddle River, NJ: Prentice Hall, 720p. +.. + [JVFM21] Jordahl, K., Van den Bossche, J., Fleischmann, M, McBride, J. and others (2021) geopandas, 10.5281/zenodo.5573592. -.. [ELLT12] Eto, J.H., LaCommare, K.H., Larsen, P.H., Todd, A., and Fisher, E. (2012). An Examination of Temporal Trends in Electricity Reliability Based on Reports from U.S. Electric Utilities. Lawrence Berkeley National Laboratory Report Number LBNL-5268E. Berkeley, CA: Ernest Orlando Lawrence Berkeley National Laboratory, 68p. +.. + [Folium] python-visualization/folium. (n.d.). Retrieved on February 5, 2019 from https://github.com/python-visualization/folium. -.. [GSCL94] Gu, B., Schmitt, J., Chen, Z. Liang, L., and McCarthy, J.F. (1994) Adsorption and desorption of natural organic matter on iron oxide: mechanisms and models. Environmental Science and Technology, 28:38-46. +.. + [GaCl18] Gazoni, E. and Clark, C. (2018) openpyxl - A Python library to read/write Excel 2010 xlsx/xlsm files, Retrieved on May 4, 2018 from https://openpyxl.readthedocs.io. -.. [JVFM21] Jordahl, K., Van den Bossche, J., Fleischmann, M, McBride, J. and others (2021) geopandas, 10.5281/zenodo.5573592. +.. + [HaSS08] Hagberg, A.A., Schult, D.A., and Swart, P.J. (2008). Exploring network structure, dynamics, and function using NetworkX. In Proceedings of the 7th Python in Science Conference (SciPy2008), August 19-24, Pasadena, CA, USA. -.. [Folium] python-visualization/folium. (n.d.). Retrieved on February 5, 2019 from https://github.com/python-visualization/folium. +.. + [Hunt07] Hunter, J.D. (2007). Matplotlib: A 2D graphics environment. Computing in Science and Engineering, 9(3), 90-95. -.. [GaCl18] Gazoni, E. and Clark, C. (2018) openpyxl - A Python library to read/write Excel 2010 xlsx/xlsm files, Retrieved on May 4, 2018 from https://openpyxl.readthedocs.io. +.. + [ICC12] International Code Council. (2011). 2012 International Fire Code, Appendix B - Fire-Flow Requirements for Buildings. Country Club Hills, IL: International Code Council, ISBN: 978-1-60983-046-5. -.. [HaSS08] Hagberg, A.A., Schult, D.A., and Swart, P.J. (2008). Exploring network structure, dynamics, and function using NetworkX. In Proceedings of the 7th Python in Science Conference (SciPy2008), August 19-24, Pasadena, CA, USA. +.. + [JaSr08] Jayaram, N. and Srinivasan, K. (2008). Performance-based optimal design and rehabilitation of water distribution networks using life cycle costing. Water resources research, 44(1). -.. [Hunt07] Hunter, J.D. (2007). Matplotlib: A 2D graphics environment. Computing in Science and Engineering, 9(3), 90-95. +.. + [JCMG11] Joyner, D., Certik, O., Meurer, A., and Granger, B.E. (2012). Open source computer algebra systems, SymPy. ACM Communications in Computer Algebra, 45(4), 225-234. -.. [ICC12] International Code Council. (2011). 2012 International Fire Code, Appendix B - Fire-Flow Requirements for Buildings. Country Club Hills, IL: International Code Council, ISBN: 978-1-60983-046-5. +.. + [Lamb01] Lambert, A. (2001). What do we know about pressure-leakage relationships in distribution systems. Proceedings of the IWA Specialised Conference ‘System Approach to Leakage Control and Water Distribution Systems Management’, Brno, Czech Republic, 2001, May 16-18, 89-96. -.. [JaSr08] Jayaram, N. and Srinivasan, K. (2008). Performance-based optimal design and rehabilitation of water distribution networks using life cycle costing. Water Resources Research, 44(1). +.. + [LWFZ17] Liu, H., Walski, T., Fu, G., Zhang, C. (2017). Failure Impact Analysis of Isolation Valves in a Water Distribution Network. Journal of Water Resources Planning and Management 143(7): 04017019. -.. [JCMG11] Joyner, D., Certik, O., Meurer, A., and Granger, B.E. (2012). Open source computer algebra systems, SymPy. ACM Communications in Computer Algebra, 45(4), 225-234. +.. + [Mcki13] McKinney, W. (2013). Python for Data Analysis: Data Wrangling with Pandas, NumPy, and IPython. Sebastopal, CA: O'Reilly Media, 1 edition, 466p. -.. [Lamb01] Lambert, A. (2001). What do we know about pressure-leakage relationships in distribution systems. Proceedings of the IWA Specialised Conference ‘System Approach to Leakage Control and Water Distribution Systems Management’, Brno, Czech Republic, 2001, May 16-18, 89-96. +.. + [NIAC09] National Infrastructure Advisory Council (NIAC). (2009). Critical Infrastructure Resilience, Final Report and Recommendations, U.S. Department of Homeland Security, Washington, D.C., Accessed September 20, 2014. http://www.dhs.gov/xlibrary/assets/niac/niac_critical_infrastructure_resilience.pdf. -.. [LWFZ17] Liu, H., Walski, T., Fu, G., Zhang, C. (2017). Failure Impact Analysis of Isolation Valves in a Water Distribution Network. Journal of Water Resources Planning and Management 143(7): 04017019. +.. + [OsKS02] Ostfeld, A., Kogan, D., and Shamir, U. (2002). Reliability simulation of water distribution systems - single and multiquality. Urban Water, 4(1), 53-61. -.. [Mcki13] McKinney, W. (2013). Python for Data Analysis: Data Wrangling with Pandas, NumPy, and IPython. Sebastopal, CA: O'Reilly Media, 1 edition, 466p. +.. + [Ross00] Rossman, L.A. (2000). EPANET 2 Users Manual. Cincinnati, OH: U.S. Environmental Protection Agency. U.S. Environmental Protection Agency Technical Report, EPA/600/R--00/057, 200p. -.. [NIAC09] National Infrastructure Advisory Council (NIAC). (2009). Critical Infrastructure Resilience, Final Report and Recommendations, U.S. Department of Homeland Security, Washington, D.C., Accessed September 20, 2014. http://www.dhs.gov/xlibrary/assets/niac/niac_critical_infrastructure_resilience.pdf. +.. + [rtree] Toblerity/rtree. (n.d.). Retrieved on March 17, 2022 from https://github.com/Toblerity/rtree. -.. [OsKS02] Ostfeld, A., Kogan, D., and Shamir, U. (2002). Reliability simulation of water distribution systems - single and multiquality. Urban Water, 4(1), 53-61. +.. + [RWTS20] Rossman, L., Woo, H., Tryby M., Shang, F., Janke, R., and Haxton, T. (2020) EPANET 2.2 User Manual. U.S. Environmental Protection Agency, Washington, DC, EPA/600/R-20/133. -.. [Ross00] Rossman, L.A. (2000). EPANET 2 Users Manual. Cincinnati, OH: U.S. Environmental Protection Agency. U.S. Environmental Protection Agency Technical Report, EPA/600/R--00/057, 200p. +.. + [SOKZ12] Salomons, E., Ostfeld, A., Kapelan, Z., Zecchin, A., Marchi, A., and Simpson, A. (2012). The battle of the water networks II - Problem description. Water Distribution Systems Analysis Conference 2012, September 24-27, Adelaide, South Australia, Australia. Retrieved on May 23, 2017 from https://emps.exeter.ac.uk/media/universityofexeter/emps/research/cws/downloads/WDSA2012-BWNII-ProblemDescription.pdf. -.. [rtree] Toblerity/rtree. (n.d.). Retrieved on March 17, 2022 from https://github.com/Toblerity/rtree. +.. + [SPHC16] Sievert, C., Parmer, C., Hocking, T., Chamberlain, S., Ram, K., Corvellec, M., and Despouy, P. (2016). plotly: Create interactive web graphics via Plotly’s JavaScript graphing library [Software]. -.. [RWTS20] Rossman, L., Woo, H., Tryby M., Shang, F., Janke, R., and Haxton, T. (2020) EPANET 2.2 User Manual. U.S. Environmental Protection Agency, Washington, DC, EPA/600/R-20/133. +.. + [Todi00] Todini, E. (2000). Looped water distribution networks design using a resilience index based heuristic approach. Urban Water, 2(2), 115-122. -.. [SOKZ12] Salomons, E., Ostfeld, A., Kapelan, Z., Zecchin, A., Marchi, A., and Simpson, A. (2012). The battle of the water networks II - Problem description. Water Distribution Systems Analysis Conference 2012, September 24-27, Adelaide, South Australia, Australia. Retrieved on May 23, 2017 from https://emps.exeter.ac.uk/media/universityofexeter/emps/research/cws/downloads/WDSA2012-BWNII-ProblemDescription.pdf. +.. + [USEPA14] United States Environmental Protection Agency. (2014). Systems Measures of Water Distribution System Resilience. Washington DC: U.S. Environmental Protection Agency. U.S. Environmental Protection Agency Technical Report, EPA 600/R--14/383, 58p. -.. [SPHC16] Sievert, C., Parmer, C., Hocking, T., Chamberlain, S., Ram, K., Corvellec, M., and Despouy, P. (2016). plotly: Create interactive web graphics via Plotly’s JavaScript graphing library [Software]. +.. + [USEPA15] United States Environmental Protection Agency. (2015). Water Security Toolkit User Manual. Washington DC: U.S. Environmental Protection Agency. U.S. Environmental Protection Agency Technical Report, EPA/600/R-14/338, 187p. -.. [SRU23] Shang, F., Rossman, L. A., and Uber, J.G. (2023). EPANET-MSX 2.0 User Manual. U.S. Environmental Protection Agency, Cincinnati, OH. EPA/600/R-22/199. +.. + [VaCV11] van der Walt, S., Colbert, S.C., and Varoquaux, G. (2011). The NumPy array: A structure for efficient numerical computation. Computing in Science and Engineering, 13, 22-30. -.. [Todi00] Todini, E. (2000). Looped water distribution networks design using a resilience index based heuristic approach. Urban Water, 2(2), 115-122. +.. + [WaSM88] Wagner, J.M., Shamir, U., and Marks, D.H. (1988). Water distribution reliability: Simulation methods. Journal of Water Resources Planning and Management, 114(3), 276-294. -.. [USEPA14] United States Environmental Protection Agency. (2014). Systems Measures of Water Distribution System Resilience. Washington DC: U.S. Environmental Protection Agency. U.S. Environmental Protection Agency Technical Report, EPA 600/R--14/383, 58p. +.. + [WaWC06] Walski, T., Weiler, J. Culver, T. (2006). Using Criticality Analysis to Identify Impact of Valve Location. Water Distribution Systems Analysis Symposium. Cincinnati, OH, American Society of Civil Engineers: 1-9. -.. [USEPA15] United States Environmental Protection Agency. (2015). Water Security Toolkit User Manual. Washington DC: U.S. Environmental Protection Agency. U.S. Environmental Protection Agency Technical Report, EPA/600/R-14/338, 187p. +.. + [WWQP06] Wald, D.J., Worden, B.C., Quitoriano, V., and Pankow, K.L. (2006). ShakeMap manual: Technical manual, user's guide, and software guide. United States Geologic Survey, Retrieved on April 25, 2017 from http://pubs.usgs.gov/tm/2005/12A01/. -.. [VaCV11] van der Walt, S., Colbert, S.C., and Varoquaux, G. (2011). The NumPy array: A structure for efficient numerical computation. Computing in Science and Engineering, 13, 22-30. +.. + [WCSG03] Walski, T.M., Chase, D.V., Savic, D.A., Grayman, W., Beckwith, S. (2003). Advanced Water Distribution Modeling and Management. HAESTAD Press, Waterbury, CT, 800. -.. [WaSM88] Wagner, J.M., Shamir, U., and Marks, D.H. (1988). Water distribution reliability: Simulation methods. Journal of Water Resources Planning and Management, 114(3), 276-294. +.. raw:: html -.. [WaWC06] Walski, T., Weiler, J. Culver, T. (2006). Using Criticality Analysis to Identify Impact of Valve Location. Water Distribution Systems Analysis Symposium. Cincinnati, OH, American Society of Civil Engineers: 1-9. +
-.. [WWQP06] Wald, D.J., Worden, B.C., Quitoriano, V., and Pankow, K.L. (2006). ShakeMap manual: Technical manual, user's guide, and software guide. United States Geologic Survey, Retrieved on April 25, 2017 from http://pubs.usgs.gov/tm/2005/12A01/. +.. bibliography:: -.. [WCSG03] Walski, T.M., Chase, D.V., Savic, D.A., Grayman, W., Beckwith, S. (2003). Advanced Water Distribution Modeling and Management. HAESTAD Press, Waterbury, CT, 693p. -.. [*] Cross reference labels begins with 4 letters: +.. raw:: latex - * If the citation has one author, the first 4 letters of name are used - * If the citation has two authors, the first 2 letters of author 1 and first 2 letters of author 2 are used - * If the citation has three authors, the first 2 letters of author 1, first letter of author 2, and first letter of author 3 are used - * If the citation has four authors, the first letter of each author is used - * If the citation has more than four authors, the first letter of first four authors is used - * Exceptions are made for American Lifelines Alliance (ALA) and United States Environmental Protection Agency (USEPA) - - The next two digits are the year (century ignored). - If the 6 digits match another citation, a lower case letter (a, b, ...) is added. - Cross reference notation will be updated to a standard format when better options come available. + \end{thebibliography} + \endgroup diff --git a/wntr/epanet/__init__.py b/wntr/epanet/__init__.py index daea1f9c1..2024a4aae 100644 --- a/wntr/epanet/__init__.py +++ b/wntr/epanet/__init__.py @@ -3,6 +3,5 @@ """ from .io import InpFile #, BinFile, HydFile, RptFile from .util import FlowUnits, MassUnits, HydParam, QualParam, EN -import wntr.epanet.toolkit as toolkit -import wntr.epanet.exceptions as exceptions +from . import toolkit, io, util, exceptions import wntr.epanet.msx as msx \ No newline at end of file diff --git a/wntr/epanet/exceptions.py b/wntr/epanet/exceptions.py index 1a4200128..6442a0706 100644 --- a/wntr/epanet/exceptions.py +++ b/wntr/epanet/exceptions.py @@ -1,8 +1,5 @@ # coding: utf-8 -""" -The wntr.epanet.expections module contains Exceptions for EPANET toolkit -and IO operations. -""" +"""Exceptions for EPANET toolkit and IO operations.""" from typing import List @@ -85,7 +82,7 @@ 309: "cannot save results to report file %s", } """A dictionary of the error codes and their meanings from the EPANET toolkit. -Please see :doc:`/errors` for tables of these values. +Please see :doc:`/errors` for descriptions of these values. :meta hide-value: """ diff --git a/wntr/network/options.py b/wntr/network/options.py index 8daa855f2..3d1d086a5 100644 --- a/wntr/network/options.py +++ b/wntr/network/options.py @@ -1,21 +1,12 @@ """ The wntr.network.options module includes simulation options. -.. rubric:: Classes - -.. autosummary:: - :nosignatures: - - Options - TimeOptions - GraphicsOptions - HydraulicOptions - ReportOptions - ReactionOptions - QualityOptions - EnergyOptions - UserOptions +.. note:: + This module has been changed in version 0.2.3 to incorporate the new options + that EPANET 2.2 requires. It also reorganizes certain options to better align + with EPANET nomenclature. This change is not backwards compatible, particularly + when trying to use pickle files with older options. """ import re import logging From 853536e87fbae1d56ad3db2f29771498e8fd41d9 Mon Sep 17 00:00:00 2001 From: dbhart Date: Fri, 17 Nov 2023 11:42:08 -0700 Subject: [PATCH 55/75] Final conflict --- wntr/epanet/__init__.py | 1 - 1 file changed, 1 deletion(-) diff --git a/wntr/epanet/__init__.py b/wntr/epanet/__init__.py index 2024a4aae..38953580e 100644 --- a/wntr/epanet/__init__.py +++ b/wntr/epanet/__init__.py @@ -4,4 +4,3 @@ from .io import InpFile #, BinFile, HydFile, RptFile from .util import FlowUnits, MassUnits, HydParam, QualParam, EN from . import toolkit, io, util, exceptions -import wntr.epanet.msx as msx \ No newline at end of file From 7ea6a6ede32b4a97b4985367d5f196b6bd8b5558 Mon Sep 17 00:00:00 2001 From: Katherine Klise Date: Tue, 12 Dec 2023 16:06:34 -0800 Subject: [PATCH 56/75] Updates to msx docs --- documentation/advancedsim.rst | 2 +- documentation/waterquality_msx.rst | 37 ++++++++++++------- .../example.msx => data/Net3_arsenic.msx} | 4 +- examples/msx/example.inp | 36 ------------------ 4 files changed, 27 insertions(+), 52 deletions(-) rename examples/{msx/example.msx => data/Net3_arsenic.msx} (97%) delete mode 100644 examples/msx/example.inp diff --git a/documentation/advancedsim.rst b/documentation/advancedsim.rst index 1944c9c70..cb295bdd3 100644 --- a/documentation/advancedsim.rst +++ b/documentation/advancedsim.rst @@ -281,7 +281,7 @@ reference. ... """J. B. Burkhardt, et al. (2020) https://doi.org/10.1061/(asce)wr.1943-5452.0001304""" ... ) >>> msx - MultispeciesQualityModel(name='lead_ppm') + MsxModel(name='lead_ppm') Model options are added as follows: diff --git a/documentation/waterquality_msx.rst b/documentation/waterquality_msx.rst index d6314097c..3ffcf6145 100644 --- a/documentation/waterquality_msx.rst +++ b/documentation/waterquality_msx.rst @@ -8,10 +8,10 @@ >>> import wntr >>> try: ... wn = wntr.network.model.WaterNetworkModel('../examples/networks/Net3.inp') - ... msx_filename = '../examples/data/something.msx' + ... wn.msx = wntr.msx.MsxModel('../examples/data/Net3_arsenic.msx') ... except: ... wn = wntr.network.model.WaterNetworkModel('examples/networks/Net3.inp') - ... msx_filename = 'examples/data/something.msx' + ... wn.msx = wntr.msx.MsxModel('examples/data/Net3_arsenic.msx') .. _msx_water_quality: @@ -28,11 +28,13 @@ In this example, the MsxModel is created from a MSX file (see [SRU23]_ for more .. doctest:: - >>> msx_filename = 'data/something.msx') # doctest: +SKIP - >>> wn.msx = wntr.msx.MsxModel(msx_filename) + >>> import wntr # doctest: +SKIP + + >>> wn = wntr.network.WaterNetworkModel('networks/Net3.inp') # doctest: +SKIP + >>> wn.msx = wntr.msx.MsxModel('data/Net3_arsenic.msx') # doctest: +SKIP + >>> sim = wntr.sim.EpanetSimulator(wn) >>> results = sim.run_sim() -[TODO add an msx file that uses Net3 to the examples folder for documentation examples] The results include a quality value for each node, link, and species (see :ref:`simulation_results` for more details). @@ -74,20 +76,29 @@ Examples that illustrate how to build MSX models in WNTR are included in :ref:`a Reaction library ----------------- -WNTR also contains a library of MSX models that are accessed through the :class:`~wntr.msx.library.ReactionLibrary`. +WNTR also contains a library of MSX models that are accessed through the +:class:`~wntr.msx.library.ReactionLibrary`. This includes the following models: -* `Arsenic Chloramine model `_ [SRU23]_ -* `Lead Plumbosolvency model `_ [BWMS20]_ -[TODO change the 2 links to usepa, add other models if they are referenced] +* `Arsenic oxidation/adsorption `_ [SRU23]_ +* `Batch chloramine decay `_ +* `Lead plumbosolvency `_ [BWMS20]_ +* `Nicotine/chlorine reaction `_ +* `Nicotine/chlorine reaction with reactive intermediate `_ The models are stored in JSON format. Additional models can be loaded into the library by setting a user specified path. -Additional models could also be added to the WNTR Reactions library. +Additional models could also be added directly to the WNTR Reactions library. -The following example loads a MsxModel from the ReactionLibrary. +The following example loads the Lead plumbosolvency model (lead_ppm) from the ReactionLibrary. .. doctest:: - >>> msx_model = ... -[TODO finish this example] + >>> reaction_library = wntr.msx.library.ReactionLibrary() + + >>> print(reaction_library.model_name_list()) + ['arsenic_chloramine', 'batch_chloramine_decay', 'lead_ppm', 'nicotine', 'nicotine_ri'] + + >>> lead_ppm = reaction_library.get_model("lead_ppm") + >>> print(lead_ppm) + MsxModel(name='lead_ppm') diff --git a/examples/msx/example.msx b/examples/data/Net3_arsenic.msx similarity index 97% rename from examples/msx/example.msx rename to examples/data/Net3_arsenic.msx index b20e0854b..2b7cb2a81 100644 --- a/examples/msx/example.msx +++ b/examples/data/Net3_arsenic.msx @@ -46,8 +46,8 @@ Arsenic Oxidation/Adsorption Example [QUALITY] ;Initial conditions (= 0 if not specified here) - NODE Source AS3 10.0 - NODE Source NH2CL 2.5 + NODE River AS3 10.0 + NODE River NH2CL 2.5 [REPORT] NODES C D ;Report results for nodes C and D diff --git a/examples/msx/example.inp b/examples/msx/example.inp deleted file mode 100644 index 0887e00db..000000000 --- a/examples/msx/example.inp +++ /dev/null @@ -1,36 +0,0 @@ -[TITLE] -EPANET-MSX Example Network - -[JUNCTIONS] -;ID Elev Demand Pattern - A 0 4.1 - B 0 3.4 - C 0 5.5 - D 0 2.3 - -[RESERVOIRS] -;ID Head Pattern - Source 100 - -[PIPES] -;ID Node1 Node2 Length Diameter Roughness - 1 Source A 1000 200 100 - 2 A B 800 150 100 - 3 A C 1200 200 100 - 4 B C 1000 150 100 - 5 C D 2000 150 100 - -[TIMES] - Duration 48 - Hydraulic Timestep 1:00 - Quality Timestep 0:05 - Report Timestep 2 - Report Start 0 - Statistic NONE - -[OPTIONS] - Units CMH - Headloss H-W - Quality NONE - -[END] From 48a6faf07b025caef1d03f9dc7e6ec79f4c9bc75 Mon Sep 17 00:00:00 2001 From: dbhart Date: Thu, 14 Dec 2023 10:50:24 -0700 Subject: [PATCH 57/75] Fixing typos --- documentation/citations.bib | 4 ++-- documentation/references.bib | 15 +++++++++++++-- documentation/userguide.rst | 1 + documentation/wntr-api.rst | 1 + 4 files changed, 17 insertions(+), 4 deletions(-) diff --git a/documentation/citations.bib b/documentation/citations.bib index 6e5b3eef6..d0a2c6b4c 100644 --- a/documentation/citations.bib +++ b/documentation/citations.bib @@ -198,7 +198,7 @@ @article{mazumder2022 number = "5", pages = "728--743", year = "2022", - publisher = "Taylor \\& Francis", + publisher = "Taylor \& Francis", doi = "10.1080/15732479.2020.1864415" } @@ -259,7 +259,7 @@ @article{nikolopoulos2020b number = "3", pages = "256--270", year = "2022", - publisher = "Taylor \\& Francis", + publisher = "Taylor \& Francis", doi = "10.1080/1573062X.2021.1995446" } diff --git a/documentation/references.bib b/documentation/references.bib index 40f09982c..e07d3450c 100644 --- a/documentation/references.bib +++ b/documentation/references.bib @@ -23,7 +23,7 @@ @article{barr13 author = "Barker, Kash and Ramirez-Marquez, Jose Emmanuel and Rocco, Claudio M.", doi = "10.1016/j.ress.2013.03.012", issn = "0951-8320", - journal = "Reliability Engineering \\& System Safety", + journal = "Reliability Engineering \& System Safety", pages = "89--97", title = "Resilience-based network component importance measures", volume = "117", @@ -92,7 +92,7 @@ @inproceedings{hass08 @article{hunt07, author = "Hunter, John D. and others", doi = "10.1109/MCSE.2007.55", - journal = "Computing in Science \\& Engineering", + journal = "Computing in Science \& Engineering", number = "3", pages = "90--95", title = "Matplotlib: A {2D} Graphics Environment", @@ -250,6 +250,17 @@ @misc{sphc16 optcomment = "modified from below preferred citation, per Plotly" } +@techreport{shang2023, + author = "Shang, F. and Rossman, L. and Uber, J.", + institution = "U.S. Environmental Protection Agency", + title = "{EPANET}-{MSX} 2.0 User Manual", + year = "2023", + address = "Cincinnati, OH", + number = "EPA/600/R--22/199", + url = "https://cfpub.epa.gov/si/si_public_record_Report.cfm?dirEntryId=358205&Lab=CESER", + urldate = "2023-11-17", +} + @article{todi00, author = "Todini, Ezio", doi = "10.1016/S1462-0758(00)00049-2", diff --git a/documentation/userguide.rst b/documentation/userguide.rst index fa4c7d302..023e35285 100644 --- a/documentation/userguide.rst +++ b/documentation/userguide.rst @@ -55,6 +55,7 @@ U.S. Department of Energy's National Nuclear Security Administration under contr hydraulics waterquality + waterquality_msx resultsobject .. toctree:: diff --git a/documentation/wntr-api.rst b/documentation/wntr-api.rst index f3fc7c4c1..27a6b7d71 100644 --- a/documentation/wntr-api.rst +++ b/documentation/wntr-api.rst @@ -21,6 +21,7 @@ API documentation wntr.graphics wntr.metrics wntr.morph + wntr.msx wntr.network wntr.scenario wntr.sim From 08b60b7e3705d1f1864071ecb461200e54a7fdc8 Mon Sep 17 00:00:00 2001 From: dbhart Date: Mon, 18 Dec 2023 10:04:52 -0700 Subject: [PATCH 58/75] Adding MSX binary files and updating .gitignore --- .gitignore | 84 ++++++++++++++++++++++++-- wntr/epanet/Darwin/libepanet2.dylib | Bin 0 -> 309136 bytes wntr/epanet/Darwin/libepanetmsx.dylib | Bin 0 -> 249696 bytes wntr/epanet/Linux/libepanet2.so | Bin 0 -> 400624 bytes wntr/epanet/Linux/libepanetmsx.so | Bin 0 -> 225256 bytes wntr/epanet/Windows/epanet2.lib | Bin 22614 -> 50330 bytes wntr/epanet/Windows/epanetmsx.lib | Bin 0 -> 7182 bytes 7 files changed, 78 insertions(+), 6 deletions(-) create mode 100755 wntr/epanet/Darwin/libepanet2.dylib create mode 100755 wntr/epanet/Darwin/libepanetmsx.dylib create mode 100644 wntr/epanet/Linux/libepanet2.so create mode 100644 wntr/epanet/Linux/libepanetmsx.so create mode 100644 wntr/epanet/Windows/epanetmsx.lib diff --git a/.gitignore b/.gitignore index 01ebf9a57..8a88191db 100644 --- a/.gitignore +++ b/.gitignore @@ -1,24 +1,96 @@ +# Developer IDE directories /.project -/.spyproject -_build/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# VS Code project settings +*.code-workspace +/.vscode + +# IPython +profile_default/ +ipython_config.py + +# pyenv +.python-version + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Distribution / packaging +.Python build/ -wntr.egg-info/ +develop-eggs/ dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg docker/ +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +.hypothesis/ +.pytest_cache/ + +# Mac cleanup +**/.DS_Store + +# Other items / test output +temp* *.pyd *.pyc *.egg -*.coverage *.ipynb *.html *.pickle *.xlsx -temp* - examples/*.inp wntr/tests/*.png +# Documentation build files +documentation/_build documentation/_local documentation/apidoc + +# WNTR specific +wntr/sim/aml/*.so +wntr/sim/aml/*.dll +wntr/sim/aml/*.dylib +wntr/sim/network_isolation/*.so +wntr/sim/network_isolation/*.dll +wntr/sim/network_isolation/*.dylib diff --git a/wntr/epanet/Darwin/libepanet2.dylib b/wntr/epanet/Darwin/libepanet2.dylib new file mode 100755 index 0000000000000000000000000000000000000000..5a458ddf3bb25fed4d8d0e6da917a9ad6673b6b9 GIT binary patch literal 309136 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 z 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 literal 0 HcmV?d00001 diff --git a/wntr/epanet/Darwin/libepanetmsx.dylib b/wntr/epanet/Darwin/libepanetmsx.dylib new file mode 100755 index 0000000000000000000000000000000000000000..e691a671c88609d5faf0897b1e81b87e0a9c059b GIT binary patch literal 249696 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

f0FG#k_P+qDml{NesN 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%0AJOn34e!(NZVm6y@GBbLq~UcM&eia8 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

%WKW`@A1i`7IrT2stV|5q;kgliOxbF7-mvW)yPd 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

  • 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 OWAFbp2lyAC{{H}04QKKI literal 0 HcmV?d00001 diff --git a/wntr/epanet/Linux/libepanetmsx.so b/wntr/epanet/Linux/libepanetmsx.so new file mode 100644 index 0000000000000000000000000000000000000000..bb761b5457352741efdcd64879b80187391fbb78 GIT binary patch literal 225256 zcmeFadt6ji_dkA6C-FLXq3}r)OAE^sElW!a%h9pKFs0B`L`6Zl34@nXLy=;dFf1** zV_Dh7!pfqH38q4J!>&|TbbFc!>mj>QS^nN@?{&`X+05wl`9A;sp5Zlf&U){))?RDv zwfEV3pEJYtj)~*iL_`?otF3X7;in8EfeYd?+L|oDMi`y(+1EHl@V2u`f}C8ABLMSgC~~5{YFTb*$2TsQdd#CLcLEi4Wf1<&sz~?n~*QejLP%=FzlsGUP-%u-@YxxY>;>xxP^C zC!L2juE@+`B1s43+W1My2CS_n%nUD`_hg#NSG8aJh&_2r+(TX7Uj6t(i@lE(omq`y zqZsc=c$2PRA+3JFeY|sF*e#``e65 zjK)iPb)FL&b@7!`q883c8sB+S$1f(H`qP@&l6Fxu+a;X4X0!2eWahYbMX@lwO}ol3 zE8>j1I(6-i3EH-n;SMgZDnX>+s%>_v?7SiTB%hzk~O?c)y4D`*?qZ z_a}JM>odF?>4aZj;P@qOg!d14pS-aBJ9F-SzxOYDJ65MpyYsYxe_XX< z;L~Y!*H3(O-q4cEp4vM6?e6P8`gL{hYGdX@FSJc4d}`^Cd&l;;GUob%4?H`r`fA4b z^yfajV0_Mi6AtHG)sWot>!fX)-@fXq+V}T*Hl1}zn&Z-oZf$qY{tuq-)$P=$_P##) z+~+So=c~al&5HU@!=srek2vYHe(i^SnzF2X^S`qn{^YM-r}b@$&rE)!N6gD5Gy3MP zn^<-4+?hvqcVAG~?bzKKcy zx%8x;nm@l~>h<4wx(#}C)T2An#!P75I3Rm*`gPSWFQ2;nuYo0Hug_W>ov>WVb8GHlke-F-MPc&H4`qmV};Kd+kL}6ci%f#j5+A; z_d^d4zi-B|`RTu6eBV9uYx}ZaPW<+o?cY4G>+OgCJaOS0*Xf-?M)9 z{7Xk1*>QH|kS;goo|ilDy^QNS_o__a`{btkHq5*Hw)U6(F?wt9#x6U{J7vw9w#fGB zHA_0(Jo!++jaU5kO_$#epVEKDXWzT0-TT$-_9cgYI^*>>Pki!|L7R%t>)kf}LPyi; zgF`;e**0SPk3D{BnYpsI`SSNVfBbmmh{@}^`y$(W#xHvRsy@P@{JG++_;0gUmEF?u;y0f=spN)*$rt5zc`@~1eBN)pp962dCn|1hcU#BxD{Q5m zUjIG8vCDDJ?aOZH^;5~VQ+KTJem3*B=l4^3hkUi5qlVz6N|V0x(FBQV0z}^q7n>$01ATPqin(Pg(39c z5Q3k^>R|edLd3Z&1b%6VIQ%Ds{@o$kcSi_4blr``TYtRTTO0I9?Yb{#!%fbZrc#|Gg0W z--N)Q4-x0-A^Pt{A@X5ah0^b+{-x4C8zl7i)8=`-W3(|YWh&T~W5dqaqND?{KpA@pwvflm#AXNIu

    8(R8N!}hLh$bi!9P7j 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

    PfT@BTn3aGwVc;64S!{~*P`%T>;`I{lfm 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 z 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

      b&7`ouatL?(rw>I@nhw(^T`I29pkkRMJy=** z&Ul>*&zHe?#ch_4uJ=NvLPCn|c1zW!H>I((VA^ttC2@PM!K^NA5&GfzlCVyYS#eHQ6sHPUHD~B$)2cK_wCp{m83o(@1E>@@RJV-;n-4U!9ElAp_lV2{IL&Z-dAP(QO5US{r{2v&9V6YJ6=9K zr`gwx<-n)w^K)w~zW?675Ahm))#mHb!`rbV`7fn%ANLr}KFmv67*GHEvG{&|l@I6o z3a6TQ`ah1vU-gQm@5AU&Mr06E=Y9z;Y=T$pzdQDU2^xdbry09!e;z!AohkTl(%6Z` zkEiF4efT`0;FY*ieE*%ay_vq3gNSba*oS`v72Ege`*~th8NY_rK{r-vKfWHWMO>*r zAAjD#wl{Bzg^$U}ip{6%!@uHOW&F~7x2YCizI#x)`FK8jFBad=f4lDhi!bvbE4P}; z1MJKDZlcSiF~5lO>NXx?WcKmZ5o)RroxIm4`JWf#KK`5-7g^aVLl&`};NQEMelPvt sM;XaqxA%W?c|Pxz3ToPnzU~Ei(x>ZX@mk2Z@u&7!eE%MwmygH)U+kCTDgXcg literal 0 HcmV?d00001 diff --git a/wntr/epanet/Windows/epanet2.lib b/wntr/epanet/Windows/epanet2.lib index 7c60cb2ddd85397d3681ad8110114dcb392b6778..9ea26811c303b95ebda9d86ca8c95a8be0a8f6c6 100644 GIT binary patch literal 50330 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 b#%rH4JRxMBn1mv3+1{@iE*~^csM`JmjA_UI diff --git a/wntr/epanet/Windows/epanetmsx.lib b/wntr/epanet/Windows/epanetmsx.lib new file mode 100644 index 0000000000000000000000000000000000000000..930059413fd6f84eba5c1d78864cbd9ac4e8ad4b GIT binary patch literal 7182 zcmcIoTWnNS6y1G5=}`Kb>9nOS3>Bk%P)a+4RvRr+2<1&F#t_1En7P1^X=j{Aqdy9M z^n(!mA;fP&LVSdn%7?EHG?)+*K@Fy8Ff=r%K@*UGF@n^+?|IyF?p*3jhu&n*nZ3_G zXPw91>z;F$bcd4R124E%`1EJ_N?jLPJO8t?qw87rchCg@F9NvE08~r>R5k#3A24Zb z1t6&!VbXXEb(DqJgrs2|m$O)+)L&sza~FWbGs>j)0sx7}!^C|GfW&i~iF+05C^gMY z>UIN=)Er?_y#c_KF)UGP_b{otj^je{9%oX25b;r(x|!4=CdtCfOqx!j9c5vRiMI{g zwFQHHo40N49|-oY-La;>Z`;7u{-BWv4IAm9)N2q7ZrQnMQ??7dDSep7!1|qAHU@iF z53GjGJ6=hJMhtAeFB&tji|9}yXfu*(q!XcZ+DHy7E|v{FLXk+8hho$E7zxEPDwgbs zRWRRFJd+ITUfjg$qr=hktC>(t8;~>#ykuy|z+r1niIA`|uW)=gl@1N3H799ApZ(ND zGOqL@Ev!}_2UeN}Rwsuf*B0xgk@@hIv#ksIX%(7p%uu$%@+33!v#%feSnFpt5UZdL zOj{fDlFOhvNh3!}7~!aqvX+maxQ%&);~8~%&3?(kYWsS%rl<*8HNw5rbl$ z2Q2oH*xVJg~_Mk1b6wwdc#Lpc!7q_cBC7|ADXBrH5rLo4m1Wi>VOjmJie z?UtSESd&Q^2VRfpK#EPYU2ki9*)xr&x)tCKxv$WQmdi@Ei3l{K1CjI?7d(#@YRHqSp!=tsc z-VP1~PW6-xW&~S#Ao53v{TaU9Bn2p2C~Y<>VB0BcP1Q~^lHF9dYzE7IBRDaV{T+pf z*2b#<%Jw^$v)>F^uN)`7w-d8YRyv*7$?=iL0zrv#m}=;#Mj1e=(P8#h_$Z`jd-thb z*k{Va%W|=kuSVQTz)f>5k|(CNNGygV`+uj@K)X1`4!R%!||#jK$c=pTg2F# z*}rrLS78nQIVu!h_CWPZZP7?59a`EUs*qmc63QeulwjEd?dP~3oM3wnm!b7rvkp(w@Fa8{s@)t7C*!I3zO?V@{$;*ReOos2dab}W z2GCGQ0EwCYA>$)4(?1OddcyIc1dg}sP*Ks;l-dTJk-AC5w0i)|As-MHbAk+s`}oNR z8-er*SQfIk(hq;AcYx=)Mny5ajK4FanrQ;YrA<1Ai0KG)@EZsyD(JJXzSJ~(mwA>kA= z9Cj`!6lYcTe2yL7{v~~XC{b|ez@bBFS}rTsm5ub=KOg^1iB>9+0_#wkmdm^xkd}vrz9*!)5{aF>w7zxR86tJQ+ilLNOd_!pU4cjrdlhyc zyhwXBPeI}*MI9{fy$T3&RC20)>h1fB5UpIIS%)wkPSbK&#eg{UC}{70SNtQ9l1o7| zzZ_+Ueg3m^U<}_o{Ws_)JKv7S&dl1BW)S;<>`eRp@c3VJJ+6?5=3%^0q-U~`CU;%? z7ca_q3pUvhS&E;13&nC^`305Hi^TGk78bug=wOttzD{SgOBE}oD2wYAH1^$IpPHuSki`K9=Kb@=6O+We4R)-@!@LfB zc<0m8zY-rdO2o&+hYoo?(DKnAl-Km#(fWp^ty}&q<$zN@|EC`ar%A!tuJ^2KIqa4b l=iV%RYm(Tond8t$kpgGq@D^#k_~CtuzZQm~d~DIN{sRGkOX~mt literal 0 HcmV?d00001 From 263b9d6d7bbf5023223ca00effda4bb09a7cc2bf Mon Sep 17 00:00:00 2001 From: dbhart Date: Mon, 18 Dec 2023 11:17:37 -0700 Subject: [PATCH 59/75] Update dll paths --- wntr/epanet/msx/toolkit.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/wntr/epanet/msx/toolkit.py b/wntr/epanet/msx/toolkit.py index e7ffdd78e..aad3a4745 100644 --- a/wntr/epanet/msx/toolkit.py +++ b/wntr/epanet/msx/toolkit.py @@ -25,10 +25,10 @@ epanet_toolkit = "wntr.epanet.toolkit" if os.name in ["nt", "dos"]: - libepanet = resource_filename(__name__, "../Windows/epanet2.dll") - libmsx = resource_filename(__name__, "../Windows/epanetmsx.dll") + libepanet = resource_filename(__name__, "../Windows/epanet2.lib") + libmsx = resource_filename(__name__, "../Windows/epanetmsx.lib") elif sys.platform in ["darwin"]: - libepanet = resource_filename(__name__, "../Darwin/libepanet.dylib") + libepanet = resource_filename(__name__, "../Darwin/libepanet2.dylib") libmsx = resource_filename(__name__, "../Darwin/libepanetmsx.dylib") else: libepanet = resource_filename(__name__, "../Linux/libepanet2.so") From 1709f1f39957171cc8fa40c9206d079e044287f2 Mon Sep 17 00:00:00 2001 From: dbhart Date: Tue, 19 Dec 2023 09:04:45 -0700 Subject: [PATCH 60/75] Updating tests...ish --- wntr/epanet/msx/toolkit.py | 9 +++++++-- wntr/tests/test_epanet_msx_io.py | 7 ++++--- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/wntr/epanet/msx/toolkit.py b/wntr/epanet/msx/toolkit.py index aad3a4745..31574c6fb 100644 --- a/wntr/epanet/msx/toolkit.py +++ b/wntr/epanet/msx/toolkit.py @@ -34,6 +34,11 @@ libepanet = resource_filename(__name__, "../Linux/libepanet2.so") libmsx = resource_filename(__name__, "../Linux/libepanetmsx.so") +dylib_dir = os.environ.get('DYLD_FALLBACK_LIBRARY_PATH','') +if dylib_dir != '': + dylib_dir = dylib_dir + ':' + resource_filename(__name__, "../Darwin") + os.environ['DYLD_FALLBACK_LIBRARY_PATH'] = dylib_dir + import logging logger = logging.getLogger(__name__) @@ -61,9 +66,9 @@ def __init__(self, inpfile="", rptfile="", binfile="", msxfile=""): self.binfile = binfile self.msxfile = msxfile - libnames = ["epanetmsx", "epanetmsx_win32"] + libnames = ["epanetmsx"] if "64" in platform.machine(): - libnames.insert(0, "epanetmsx_amd64") + libnames.insert(0, "epanetmsx") if msx_toolkit: for lib in libnames: try: diff --git a/wntr/tests/test_epanet_msx_io.py b/wntr/tests/test_epanet_msx_io.py index 74d222798..793e2d381 100644 --- a/wntr/tests/test_epanet_msx_io.py +++ b/wntr/tests/test_epanet_msx_io.py @@ -29,10 +29,11 @@ def test_msx_io(self): wntr.epanet.InpFile().write("test.inp", wn_model) wntr.epanet.msx.MsxFile().write("test.msx", msx_model) msx_model2 = wntr.msx.MsxModel(msx_file_name="test.msx") - true_vars = ["AS3", "AS5", "AS5s", "AStot", "Av", "D", "Ff", "K1", "K2", "Ka", "Kb", "Kc", "Ks", "Len", "NH2CL", "Q", "Re", "Smax", "U", "Us"] - in_vars = msx_model.variable_name_list + true_vars = ["AS3", "AS5", "AS5s", "AStot", "NH2CL", "Ka", "Kb", "K1", "K2", "Smax", "Ks"] + true_vars.sort() + in_vars = msx_model.species_name_list + msx_model.constant_name_list + msx_model.parameter_name_list + msx_model.term_name_list in_vars.sort() - io_vars = msx_model2.variable_name_list + io_vars = msx_model2.species_name_list + msx_model2.constant_name_list + msx_model2.parameter_name_list + msx_model2.term_name_list io_vars.sort() self.assertListEqual(true_vars, in_vars) self.assertListEqual(true_vars, io_vars) From 6b146c5f3fc0b01600825c8d67f2ddbe60bf9cff Mon Sep 17 00:00:00 2001 From: David Hart Date: Mon, 12 Feb 2024 08:01:29 -0700 Subject: [PATCH 61/75] MSX binaries update --- wntr/epanet/Windows/EN2setup.exe | Bin 1584021 -> 0 bytes wntr/epanet/Windows/epanet2.bas | 194 ---------------------- wntr/epanet/Windows/epanet2.def | 58 ------- wntr/epanet/Windows/epanet2.dll | Bin 217088 -> 262656 bytes wntr/epanet/Windows/epanet2.lib | Bin 50330 -> 0 bytes wntr/epanet/Windows/epanet2.pas | 264 ------------------------------ wntr/epanet/Windows/epanetmsx.dll | Bin 0 -> 147456 bytes wntr/epanet/Windows/epanetmsx.lib | Bin 7182 -> 0 bytes 8 files changed, 516 deletions(-) delete mode 100644 wntr/epanet/Windows/EN2setup.exe delete mode 100644 wntr/epanet/Windows/epanet2.bas delete mode 100644 wntr/epanet/Windows/epanet2.def delete mode 100644 wntr/epanet/Windows/epanet2.lib delete mode 100644 wntr/epanet/Windows/epanet2.pas create mode 100644 wntr/epanet/Windows/epanetmsx.dll delete mode 100644 wntr/epanet/Windows/epanetmsx.lib diff --git a/wntr/epanet/Windows/EN2setup.exe b/wntr/epanet/Windows/EN2setup.exe deleted file mode 100644 index c2672af1e80fcba0120f2d3a7008759cbfa1a4b6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1584021 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

      ?Ez2u(TZ12 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

      KTp>8g)HzwdTP_nL?W!SdiM>j@#S{BU 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

      &{wQUwSaF6XsIB2@_7-GL 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

      WZ=RB8V;-( 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�(A8%`FbSb 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

      9dRML{_O(l0d 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%0A7$6A`2S-JV!wFS^`}}~ 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⪼$Y4|3OX#T@%}&OVEN+#Q>hD(iiiV)( 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%0DR3j4htYP-509G+2>*Q_|P6vb~x(f0DHMe zC!y$DTkcs!$m}2)LTvMmN31uT`OVjunG2hP4`rV*b~XbV33*q~A(GSMR*VR#vfZo>Gg0@^1V8SIHj-Ppzfz`?_@K zcUhIly}or>BKf*-$OdQKPL+Tkyad$Df_FeSDW*b!KbBdM!D?Zi4{Sg@>hM{3ULvQQ z1GWOwjjJ@?YTz1)1YR*p5mI_*&k{wMu zEvJk<%*cFbt*c@)Z(eBvEQ+iBxt(#r%h+}{*>zQ z=@JnuILx)spPMaUACS%56MGPEBmFa4F5hc}OyW?6w_OT71`e(+Qj(gg?@LqaGy6js z*nORijeuhwXI#qe1-Z8-&=EJ{`jlMKJA+_fX9vWWKSRTnn_*(V8ja1w9CY!CF`bLX zF8$av!d@ouH;6lT&V0F05#%@L5$WdmaN8|CEqD8-jPD9t|kG4=ec<0$JWo|_NiFE zQ1v=_mMqTs^{yc*mQI3yK8$k2PS+Jxi^aTAKAx%FJvBiTPj4+0+oTCIrESVs-|m+^U-e$WUjb|L5Ou-+XP4 z;)l!zCrPTET=!pzOMXnnEDOP8= z%MI}9Agx~vrfHL_!S_ngHrF?gS@Mk7tdvLF_cAs*)$6^xT}6T3Z`_Xu%ImI!{@HOC z8}j?7@1|N^d!dFfL{Hxv<#q~O6aw+w2--`I53uuqTUUZW=+R$Ak7$KtPe)l z@xJzgN~BKds*34}vbrnd=ZpcAVCg_ zoex0pFK9r$&Xc`HL?La=z3bKpY?QxTTi_m$fl_C7fUff-EaPKhuE+8&!Z&$;lA3i% zJSTYSi2ea@lDDp|P5FkfSwgxm4aZaM*;wp^%VgpFTNEEQGdkxaeKMnT-&EZNKH)KM zrf&Tqrkz1Y{WE`MxZ;G^a7~8JK1^4aZn5=5d~ANCAmsr$z_1V`XeIoG2g9ZpM}BXnFO1XfY?#kotF zE`$(mX;ux&j_f#I_rsR5%W$Cb+DndGNkNv(nM0PxoEI10CBp~=C}*gs^GL*6Bd}bMsGgzK3v=>|;-q6_uEHtP zAJuE1m3p#$cyz;;fB9Pyp>C~TJfDrZ%M~%`5Q}2l-0cz%Ew)wC~^favo z$muiUPg{0!B2QSMcwRs{$V3VesZhZeG*2?fuSTpOgbKVqX-|J--ek@%BI!)D;Z|)X zSXQh`#lF0zJ11CCxfKZL?gACER=B}EploB=I^0g=#f8PB&S-fCjyu3Qt5nL=>h5Ar zu!Cz9=rImRDI~hq?PS=b=E%uDa+Bd%g+o>eaTp9qT$&PLe}Q5vLQe4HmXnXrV6cpk z6S@uc3UZdo=KtD>43+>gSoR1(*umH8M%?&NKR)!enWBs;L-0^QgmdZMr?6==^kOh@ z>uX0BjF15c=Z)+Dhz_h}9W%NlDP2Pgj(|2kyNW^%M3BXujp@4%kjPZ`e3q9TbReI> znf;-%JXB1=v>B(ekYIz*qphO-%^pHi&N3CKdG)J~bM2MOHK-VieW4w-$ZDE{X5zg{WVFW8nvK_;WcCSX_3&3|(!qBY^K2HI9WEpX76$6p6klSJAbi|N zND4(!U+@MZ3jJs&!63|Hh|&LP#GVDHs;V7S0)F5j0taMPh}h-Vuo_UP9oJ~wlQueR zlFh{I7Zag~j1S@h)bty5+Q3h`4fkuoE(Ia5O~&llx-4BSGq*=VIXW7JFCwfyjpqSG z{JmnS1lTvkDW5U#7w}nc?3zu(Nevkaq*(<#_Sz9Zf?0|(fp1hn7gFwclOH$y7rmEj zU>tx>S2r;sw*>MW<&t8Xq@JUrbx~49+@K#L8>0&l;)*0Y8S#Dg! zEt<=?<~9$!U3I`{k6sef_{UU~Q}y%IbpU@m4!f@*lDUmP?(8wN>MY41yoxdUQ>8Bo zT(2h#o-cAAjo-%R*w?yBol#G=T%8;ucI3U?Zi9s+mT}~?ihCB!#l?C4Sz63O)McUI z1qi>Q9W(&eAGQeIeDd7@BkRI)CUKy3{`|c!Z0?B1r|SuL9kWMx(WrGPt~~ITZdvfp zp!x)r-}?%Wqm>GOG$D}#DFWH_tWGe3d8w2Lx{2x+OlopoGfXog2h-;N6`j4|2h5+b z#ePt9;l}~s+f21fuGznl^#f=L>cnIpeK~o_G5!fdo@L~$tn#_oXJUl7swzSC>BK$DLUOD%rfFqu0@8@RQxTh@T`5O@wP}#j&$Wyv}KpT+V3*U#xi5MT4 zF|G0<69IF}pdNDzqomLeWc7p}xpV^{r<)eLSG$6w%)kH3C+goL>D-|D<_2x!mHjG&EVB6Okj4w)3 z5bFik+yTEkwb(VoXUI!l6V1`vdex_HeP%Zwl^Y3mBY_ysMKb{uI%G4i*0A0R?Rgmq zMLj{>`2;fcG?x0|W=CA-LOsHX_q&^l^H%&8D*xNx_^_V@?v~#YzkFms9{0ID!e4(f zdGYl8j}UCQG&Z@`t{hiEFN6)>LIJsR*C?NY@36NFmI`T7>pN53zQl8^sdjk(kq?Ru zfzqlV0s9>A!av3YGaU*Wl>N zCGZ)2$z<2V3`zQ+(%#{~P#@yjo^19JblMJww}Q8Xzp(0#j=naMiz4cRZN^z?kJ3zO zsj5Kl@Pz)r5f(3Bs`|UWHMN+1m7BJ#X|9U!AT&I7}dMg4*JOFnzc>d?+25 z`fO3M?hPa*z~AGA39JKc+-LtBgZG!(dP);ozLY-^y*JLX-%2y!ANuHdaIdjk_OHS> zG zhvi>hCdp?+ipw^?-j{##U*+Riv!tuxlj;aLSTE{fI%QS^geTd7S=C2l3K)~+dwy=- zwKFNZhu(^^aP0lVniE?JrNeqZI-E9n%dd0I$%J~buDb1?_;lWgB)8$+7r8?R7dcdToV^vcsxB5FkL_5jO z#vIqLPz~YFY+FANwN}hE#a_I9z|^*lNByjZz%!!NdXm#ug|6PBaau&- zY4NS?;lb9gN_p!IW!GQ4*Ef#>;K{;%4roqBThbu{Rpe#mO{yNJPpyyG{hv!NtA0Hk z==xiz%znK+tCZL+F{>^6XkklH(@*1rs`@{^ly^`bZE!7ykopGT5#<>B6$uiL=o~Jv z;iM!+ngh*%r0FP}&{EN2@s&Q*tg(}Kr@D%oDfY>|>sqm!sAn@hMhsF|%0EoDl9GAd zO%_k@OM`M_;CBSsp!h6&B*fKCo9BYPQVnL2Mmv}MD zYBxA0932SpBt;uEmMKP!V(nspKvGheE5y{L>hQAc!_LN$)NJ-a)y3TQE|qhHA?9X1 zTMPHAF@cz%Vbirg>)Og--{yHQ_0ZE&n2Yuezw>H>7j<`g1l^$Win5cwqp7?Om9>UFLg4U(kd%80+sLjm9VPt04_1>eJ$BWVhQsnLl zKA>6UWjx^6sVNHJOxvdsX^FyV0+;ik#+x@Ol=I~=4}Y#!+doi|)NZ3|>D@b`rl8EV z(!C*>16FEU_Cc>Oz&q6VAMqaJkNUjGT*D$QcO>eUUsCRg)kkH6ESz+Xm!{F$@7ZRh zldO+QebqkRbLyI1<9diWhieea!R)Obd$HXiY>9}Rd6IkM3fuP{%d-pY{jIzSgZGItw7{1(&93ChQX zxD;ZR)lfmqtwC4BNce+wf~)jL+gwM0n|&o?ymoe-)=-w4lKR)>8p)We;zo=55do{X z*mAx>8J{@|gm)5*S@rd52dYN<+jK-hf)T=Os0e_EtPZN+Ujh>>#BKNvU+e~pSSERJ z$%v%QD}@3dvs-Z21#V zs;I^hSFiH?-X?TMY*j;e8!j$4G@pfZF78bWt5m(5)gZot7qJdS(ysUP2#?Fc5P^1~ zRvhJUzACnsAHc0v2HLDeb{sYSp7>6)v)~AQEEo?<)I*>s4miXQmA$tQia-%nYL=gq zc(oGBEFV0B5w}V?PlM7LU$>zOH1@0{20I35zKhVrG!Sr-Pi1g`TT*>jQcJV8!lCFv zQcc+p%rh1YHpAnO;)F*M7VvVFsFM)2?M6xA`@}4Zu)?4~`L5VX5qGQKl|sQ4-4q-nxNSNz)<8k(X>@6V&dgK8ReXWM7E0 zjp$!X+I1kc94vs^U+8E-3t$};osrL%1m;BZ6AJ%#SXRnNhdm05GccLiQ=mmzvYp#F z!8Gp?)$C}nP}LZ$woF3L)x3q6lCF63sT3>XvyNDF73rbev<}Qo$!x(K{aZDVtj*$u z@%To37goNP@C%%BH*!p&;%}T)7lTv`t7NnNFn=pd*+{fs7`QvkPoga02_78hmb%An zI~hLOJ6}31bkSom8$O{N#K#ap9!7_39Hq9@I8E#aSIOX@N0UvHIvhyzfRBeCe?W=h zKX%o?ir`#{ZJ3+FxDkN26#1>iKia82$`1Wz6GfN_cW$SJ zM;q)@JEI|L&GPvXA$4lP=h*sT@4Faza}Ypm8-@rD>}Cy@pAlAXcTq)5Do~fAr6O)3 zBSchrB6lgd2>O+OMW@aP8{B{w=xU&;C^<`%#T$9F<(*N#{OXnjv_-3;ypvzI66A)r zgpD=og18cqEYg(+TDj_oo-Z)4+v}Sv*YNf2%Pup&!M`Cia};HrhXZ>hhlwuD=(nnU zOJ%?3LLx@0DGA#JAcUkI{uOwQb9!q|z9--o6gPA0H+WCXXwEcU%3JZ_R>jU#RLzc) z<66f!vb1r8J}PhF%UneMYN=<4;ab`HoN~)x4^RtIG62FlQzb;^mmy6@kab50n%?UC zV9{6!&kqtW9!IK8g(O>r`7V#$U^*9% z59JV!>j7)sS#TvcTrQW#g>Cv^8~*tIwW|g50Om&Ml(fLGnE2nBt-`${2 z&L7^APA8TqR^ikl<=gki0MzVu9b+Dn8=xO!p@zU-27MM96S%ryj|u>e+1WP-rLjVS znK+KEJuwxpU~Y`sdO7L#aImf0z_`1L09Lr+THjj(XbH?`*W?;=wg#s~o?b{a@S!pf z)XolXwS=5QnsVpP)VuDHe~L83q?hZ!?l5@ac-qs5;QfPf@xrG^-fY0hlr`{Nf`n}wz z&9{8d>hb#g1zc0)^*VV)&{GiBFxAkQHQ!b$^<%bJbjLG)k&cnQaY<`Av^T(`}0kgj@$;d!M9)c;H-TCrQBxd>WR`DgN3X{J(mcH|H*Pi0#V4Uu- ziP&vwY-&_z83h;ZtjJTvWG7GlykLC(;MMP+)#-@d5d&g}%n7}4;@exx1&nAOE%#S<^ zm>4iOE(fpY1>Z*ui4EIb6bat`CYQz}uzC{hqJ~Vj_c4(O4@rRsG>EBLCEN zRL z#!e#AO2yDQ!AvX^Dz1&S{O%~kdKtd6D)7R6DB_D*vM1Z&Xkn-njxrp6%Mo)%E? z-dt>e_DzpvIuzh29Fo`f+^onS=QE8Lkouxe7eEv5k%$Ju!jy2Ov`d1i325^RXwr&~ zmd2M~R?3#2tU}-m%((@o2ZIS(tG?x6ty}YiPsE`>pU4&Gkz>f$r6A4`H90M!=ABek zeGEsKfj^+z)GqpeB>WcL7oPs`RFv)QigY%USvVhhR;~6vIzkWn7gs3txo$$ zQe<^m?z*jzGTE>FnKb_{jVH(GdO%WgcbYk1i<~jt$bu!qOgf&KsH%4Btlk6ITP7p+ zR}QtoK2P;xDLB&T2agZkVlTQc^XI$0-~H~p*L&SwtE#T`Qbek#L=LDR5~BviRl<^` zK>_3enTBnKA6sl0nT*++XVwO0#@U8_Fk!Q1`?t~n%pdnZX2*HiN6D1J~_fX6l$?`t97z+Ts)e;@Vvy+BrbTZu|-j_HZRuM3tix_gl+1= zNyG|FIn%TK+Z)T?u4o2A9ya-)EO1@lC==|;5;?I?Z zaJ9wbM7I|*K_Y&;GW)7lMZw>jNyjD~d7TtC2oX08*KS_xxvgfq-@i-e<(1%M+TGtZ zgvu6a@?4Sqr7pY}S7%@_%sC-`*LzLzO7i1S`XC=Rmu(|i+7<`yqOM38V|x{o2#DGn z$=fF2%Vau1gobywc{*oiMuEwmY9-F~4%t-&|irQAPkAp*7kVF&U z-eUeXRL~i;`rPzqaH?t|r+xs)eyBlJ9*bS0K+<0T`{s(wp9k`DqCV~anQR|;!3ox6 zbG^iIZRJ4z8o?DqQHrN`>cCq#avU3!J=%S%1O9Mj6H`^nhqBKm%88PF??&J3o?eZx zi<_K%ck%g4nm*k4U)I%Oy|(r2351z&M2s!7ZqSCvtyZy>5{OQ8 z`$%B4&Jz6}N&o-PEY=Iwh@i}_S!{f<8I}(@h*n)~xafq%gCC<3SFCv!e2Eju*R07E zYy69z1Y5~Se+2Xb_w!N(s904;Rs?V$LcN255rjx7%M-YfIne71do!wnKX_yt6AlXU zME4M~M20ybP6y+I zcxNCZFl0UDess2kM^&gNvg!?U?EZtBpbf3VLEt5QikAsftsZmwbBA!qC)ik0sahNq z7cjzsw?s?vbtlD)BV_M3lBdJKMG^HRc)8_OOcK|7X+%(5C}^uHc+~j%*LW1-Zsos~ zlm}s3tdu0^tvVy2`oY2Z6v=30MKgblm)H6$D_Bf+K8CH`ARx;65f@3$v7OE)%-nn$ zR2otnKXsb6Nq?Z+jwFS?WW?3oSYaJG9?p%`u%Za38@*O0w7v_6+t;( z0;A)tN;;{XO-(*vjw=|3oU2l&OmWBhs-4D1j09#&Ub-WIOJs51#Ij#s9!}WbAsoig zO@Ur_NTG}-YytY$z15Woe5n+fJ!StBd&u85z=y|((6)lPBK-rek8PQu()`h~4hv|u z3z;*{N+Xpi5&4`TsuWGuI6-e|>>U;Q%*f5Fm=s*Qu6gU$i1PMc*2The(Z)rICStHzep-3P)&V-AKze zQZdSE;cqDr_%w)(DpFdxu`~=^;roZ_!`t<3(}}pZNh9(B6wZaM%J2!W{M$1_fu{3s zU={!T>Icnx0H*U}nW%Gv0H_EE_#6!r9BnWgA5f5d_k(0TN1C@$)T5{R^`Xm!I%SIs zyBpK|1H1%sK4q=~k|Ow&h&cyW{#YaZK-Io+Z}(~{ps#4zI_Zw;Bp zwLF@#GNzuhKnY64E^;G?1ucT1X?1Kc)O9%8Dq4jvc52U*{4T)sKZ8CDJTnfzi1QF$ zbEL89AMPP+dqFlG!;gycYz63#%!xDOiEHlfMJ8-$zo1g}*AZKq(|%0Nn*}^|sht;+ z=qO{AVM(L9Es%FgNg=gojlDa_)BbGnlesojx#o5ucb%`c&Oc6aScXn8ih4rKyvunKIQ+pxl1!cH8llCDktui&pBPwVQ&q{eTV1!jMocxy zYJW(G&Ad)-K62f+itXL_&+{K}NTRDo^rh9LC!X1Yk;Pdn+>OEN$VPy4#)=O+y_5eM zjxd!8Og_DU{F7m$80(u27_1BWfqM5BvH5%qY7BzzG+LIstJ{HY%0}H(ixX~F%zI*- zO#=d2*9)b&ZLXuffi)07Mjou*VJ5+P2(WK)sb*bIuNr=EP>bO9<)B+%UZkMD0l(-T zZuF5@b)=3j6%N}y$$yq)EGo+<@(z>@otsAnp z`S$HPR&&x5v}K{$ILCq4@8$n48X~@?OdFF!JE5#|T|Q=o)68SsCSLbJVL`5ppy;N` zf=KzuU_Ns^rgKJvmCO*h@XdI7`VlNu)pY=^Q~iMZm~Z5;5gBkV2L5LJmtMonAkfhB z#@IKDT2+wjA?vDCI#;{BOIW}B3KdanS-gtui z*kO^`+;?I76=9C`%fj>kydcsad=9VX(H$j3qsp0#F1_8vdsD?7U&rhp$Mxa({UmhY zr$+c@4Qte|a&&$NfW%%IQ&mDJuP%-Tf&to9C0O8jB55I)=fu##5`6w7Pv#w~( zW0*RlbBUXDOUBu9X4qEs`#L_)U)Y4cK~mH^r{346opXD7x`udzN49zcpo2sWQwY!3 zwW{Pqu+>(5j8W3x%v)9QiLBCkeua&tD91mn?R{O1XR_lGf6?pV?o&o9YW9(=maAyq zPK`4d4^ze3@q0F#PiIOA$!q}}@95(l3x=#FK8ik$rlPi`o<6R!4JfQ_4Ko^=zk(|~ zoQ4Su}5V*<5#*eT(OQSo+^R5wIt; zqK!nW)~Q#t&F7Fd8OE}S(fBd3lJ#vh>w<8?&o!yG8U%@(bJsGC%4$EW^Hglz=y`u6 zD~7dCr}TtQjJVPiz?~_4=K|1UiZD{|;_5#1A-CaM`^X^Q=8A33W%IP`f-Up(FlqG^ zZM`1Fc+Oy(ww5L%1eTy5&wanPxc!f!(&G^7=%K;Or>LthjVuT0Y&5L)TS$8jeGI%K zj(k1vbfW{TXB0}&9QdZyFC%2T>9KhnX%}7eT1tgkpG;30`(MR<|Bbm1Eu$Lr)~PU> zMeU+zF=V#l>@z*gUN;xEJJ7|CU6v%LHILlVI(TJP%{D*Q@?QZC`}oP>Bs)dIUN<4@ z?1^y$`5vm2AA6BY4ElaFaJG-GK*>SjA6nfLWuEZ0<+N}gVZpA3C@G?roNKC%A^6Zw z1PXo^o`um*cOLr`PCH_MZi1T&Lkz0kn6WCsv6KEV<+?#zY(!)@L4xxo;I1T=ilAv~ zPlsPOnuDqAT~*5BrW~OUL|a?Xufq^&dF?CE6WojbG}3MY&Fd!Yew;lp{u1FoY_aBf zdzW^$mEmcjP>hn=_I9#?KNOD)-q-?~wma#~jb7xxMAK_W+P+u}CLS{rC%mtRLncPi zwyravLC8ZfzD6Oag9(07*C_NqUOQ~tfO3>DvV);SNZMKvBVvN;Sah9Be^qB0yNf)>w7fjA;;mM7`G zMv~Scd|u$TE$KXiUXw_8+c$60mz7Ia`o8`#uWOqBNpN6f$@{hZGChqwHC{U;B;oX6 z;DfivIkFIf>Ga%TL#EhSvhzLH-TN@4WR{+7V5g&Bx_Rpgyji*vO zw={V(RYIa;V!=L06M1j{WuBz(zV$DK zHubxeIPcKqjeC*JiOGQ*-pp=3<-1_zcxyUGm^7QuP2eYE_N{%dd$I3nWWC{dxhBcs z8)ldmcol|n3T`!No_Z;yej)z3azBdga0L|?A^M24ZcH*`y?L&0C#N1F^06|H<-4<;!(uUMp5 z=0sq88Dwp-&IR4ohILr|{Y8mT^P6+3Tq#@DGCZA8XVDw)4<8y*}fA&>lJ;Ck}B^@Rwbrc9mqJ9 z4nGKYle)y0k_twF1x0J!9SuDxD22L1AXGsZFDMki0p1=Nb;BAqfuC%o?3%Gev|EZx zCz?%;BRA{`V)IJO05w3$zwjPJh31^e88?()F&mq|5eAEk8Z3dkK#eWy+}n0tY)Eu& z#GAlvxdNp&7N}2Pzux7eH{+M|yZar>Q&?q=UvkDC!K`v~H}4}Pf23T6HH9>klX9aH zf3|aOF+)b!S2x(GSSKc7WQN!|tddRe7vc<>K`JL74=1Ht5S+Rjf(F1*dGa@eB=5zn zD{bw8+JCs|sf+ap7Pcsmsc&Kwe*3{4eSywCRw0SWr$FY*Zic|5s^BlTP8jt=dXpjC zLWIdC-snWvp6GsLjf*PhZ#{;^I$N+idN$rr#7`+f+HShG=22kQNe!igYCgeNOJ%Nc zHB*Znos^ptF!)Ci$3|4REOy~sTlTM}!<5nZF8Vuiexvomt=!Sn@0UZk%pol4Csr1b zXye}dW+;oKY(v$!17OiaF>uL-bp@sr)PXG+>SlcVm}=dn|@QBJ4DqvL^sx25H*@ix6ZgTnG*%tr9TMt zR7SA*OApY(31G)N>R0WKe}lN)ywk0BoGbDfyo5>eOGGv$5Gn78cUwP%U-I4i5XQ>e zHLOn~+i#cJ{m+|vulFc?w}rS*G}u$`{Jz!YJZ#pF-$RdHqVPP?E672j<~UD#Kl;D; z3ogyf=LpA&AEpC_z)t~YaWijv;?bhs>FvSd>>-)>TuiKbY63A4$Q}K2FD%u2Wbf%Y6&x5-`DcDMEV0t?Smf z-$SbyddX?5w%q6p-1k?d-s-}1q|{!`4FsZK|ha``}bZs?I) z^4z{OpLe(2wZMeuj(_iAt?h$}fWUUGe311z0e=1%&W}5I0Jay@2~~w18rOAoo&aKB z_2eFh?ynh$F|s(s8(%rYdlNKFf5@0;361L~$Uj9svHTr84Km^oHVpX|;k<>J;D@y5 zyV>hJnJd9`&%D>QxDTa!aB-ZX+oERtbNS3x3|4!nBvUAl!JoC6_k^q?i^nGS5wr&NJVaLj+g{=$~`aXY9BuWSM(5 z=gqVz@Oa4?o#Y?|$w;_qHd$X^7DQdw{+H%UDHEsr|0UERON zpGn6f23hI0{3uNcs2P8_>UK_olG-uMO(sv%0nQjX?U| z)?j|d1dd-_acg?q3x5MpUs4$Tn_zMLf1GD=UD zz^*j`HISjJbxT7;D-hsO)ZXnV`Y7k}2&u!g!un(hksr2vFhaQZkIzNN&%29o-~Dw_ zKiqW$zhY+MjM#vl*x*Vf;x3(Sgbse=aQ{%VpQk1V6J~LsyT^3Wp4Q{*k*b{4{JZ}g zB~+(}3g*zRF8951q&Pa2#-ooB=%E(*RO9!7TdqKLBXY4ny7_PPC)j0N$1m)p7Kw$T zeb^$_15C1>=&G?4N{Dal(WbzUzi9RxZ2@aPpmT0|i<0&o+!$%UvXPm%^Tq@S}r3mZK{m3I{Q|_UdwJH zdJ+Y1x#rw#JZ0Lp$1Z8n{x#2^`-cgeUi!w!Ydn+%@9S`X_gQq%!=QG;jjuoy_?ZJ0 z8fFqhaxV^OF!tpuy~s@)Yu3r~R}74rXmTxObqQtIj1Sx}Yj5{hiGxGr`Wh}h^K&#e zILNL$&ct(?l5XXE9uv7-Nn4L<>kp_@{N9UP`bj3*HHBPWEG3qQjb+?cmzPbkj8_MureQc8k;j`_FL(EhwdcSZmcZj=k)WlQHmL}iu2 z61CTQ6?6q)7g(rqwm*>fOgeMF&f+Ovz7A>!&-a+W9}pq5z!JxvBWci_E<)|e3Bj;S zVSAYsqA)wVj7Rd;H+hJWWQ-1b?~!Q@HkM#pi|fM>NTyE-tERL(e37pD2GXxpZ{)bS ztt!j67pd*s7K{6#%Y4mdgw^e=9N0*Y{rz7fXc7x?tG5{F&Bmc&7Sl4u647pBEZGhF zlE15lp`)XBPVKE-4>iSWDO^=u3#^4LZE#{mr^I4cwA%8>*XF{lo#As>CeA zA&8Q~gNY7SK`X@Lf?{i=kod)q+R-upyQNqAC^55DoM1Nf;X$BqQj%r4NExOM0lmh` z0|{Pg`Li7M&RXGUS4_tYcq{T#8^mv0Q)H?Z3`F=`V4t?VUfk1hsh_hq0lo&%_NZR&OjUEp zwtD~djd6?30~x3<#I``1oLgPTV1mlOh zBiQkqWk}huY=Md&tdd&OKfuFGmz=9p3taML!Nn*aJj_$of&|P7Ci718j{TUyCERr z@AY&6KV8Z>@ek9XKR%+0OzfWkoe**NhlM&akvw#2N2KPo{%f-Ge-d1hQcBB`Y9bB) zXE})@HOuQ`eCY2{CLc+Dbn-8Gnl>TUoHW?;P-9_MLxQcMOT|OvZOXji6Gq$FDxEKQ zQa*+SGvc{2h5gf0J|I6%D2#)80zmWIz+vJM$70if1Q~d^IPY;gEvuUP`W7|*Kd1WJ z7LsFBKZg9?t!d9ST=BO{YR6|OCN!&La~1P?b&>en=C%|G&3x&Qz5zpKrlTORf?!f* zWf2kir@Zb&A?W!NwWp&w*ML$+KC@_+-SRcQbvlon?*JE3z=?_3Ns0*Bj7&!1xoR89 zz1LsRH>Q}^qTy}s7yJuuFqS>Rnt_5mV2=cS@CG1F3*QO0tgOEcX!cktwV<&vS*PMp zIC3b`SNRo@!(C}>I7Fy+N;4w`mve$I-b!(O8kZAF{vkeLmHUnvena~}i~u;Gn9;Bo z)!cV9%oI8UD8r%;pG1L$5LnOYmISqTc@{R$onpI5u$HH!x3xkixh6 z$bL8pRz?+v0vL&kB~=LQeMI>k=RY*RdA1^xt>);$Ee~5P#XhF)AxxnK;uJ4{S2^%U zpG3tVf5|_SY|J8saEE7A!z8=Vfx$-mzhiK!shuq9QW$vx{fvC}9jN9b%^C24#TVy5 z?sXgd#fVN9m)@zQTJs7l+GnzUCY+W$jQXdsCQT$5lK1}0RZl{7cM1Kdx+8UZouczI zntK~3g{N3o(_M<~{zs-4;=Z7FemHxGM=uCM>ezzh`M0j=xYVXd$%!uO?6b{Ux1BXN z#6LR|y=JiX!6g4ZKDKN2wqVZQmG#Enn55|g_0Hx%Y(!QS$bmUB3WsmiHF5Gk*rrW^ z>4wvE@sfF}NwyZ)25<(w7e^vweSdQy#s&}yu9&U$GPZqE`MJB))|SJZl9`avdr8XY z!9GsNco1SDp0F^w?eiVUFUCs`IQ|Z9 zSn9i$0?1rnb0cwZG>b8bQOVbHuGojBWi@+RLHZbRD)8@1XZg0y9mU^b&zxr>hP$4~ zvx2d2k&q#W1u*CF(rvjtvN~~zUgImhjs{-Y{K1b!c7Hgw99ssFEV<1a>=_cv0P9AC zMy%JsBrg`g9GUk6b&P7sFoYjbhMuo}=C&V;VXoW6Rlyw(C{BclxKU`j5(7f?8IDgi z=B!IqpXM~NQKAhJGLM@(QXkt@LrC~mvAXg7f;?UL$5$Hr5<{Tr<=3(&L(IqaFFl*j zWI9tl3+HFedg%AUY#WmuI9d!l-U&3^9*k1f|RK2zaP1SjdYaEW6Jh~)>6s+$v`9NW- z5042}t6(!$jWBlQA-5<>(bUy2*uUQG_VMI9aBfVEaaTSLC^7HV-BYcKm9+EnLFT&3 z-ZNj%#QwB0YQAfrY$B{MO$3k!;G|~mlEiF&m^yA_rkd2%esB;X!qI4m4mw~=lOTUm zg95{kZ9&Ar&y~$Bh+L+S=!OnNYn#AM{N$-+K~24LM1wn}p<~GmloGBvuv8jKuyN3E zvX}WpqTFvdO%u!Pnkjx^ZIaUwD(^Kk-210vYnQ zf{IJZx+vC986PBWxvpQ&viM|>mq`ztXiRBU7$cA)CYbAYI`c%%S?Tc)FkUFyy`9+N z`Db$aeK)VxApJS0jP5Vl2IA7X-Q)woG z7QZz6c#LWE;YEnfsJBy^Ycuk-^NFLiDt_oAAGN2JH{FFKmi6_>8 zkd}(3wm^;Mn&Z(TXc@sCHt@p3N2=12_DlHs*E#{O^Ja;|NLJ@nZLB=bTrcUt+Y%M5 zm--|V6x+4-!`jbFiiV}Q##^4Q6l+QO_3wJWum5+eQun=6P&e(Eu_o3b9J1;NL>mbW zXp`@&!Y=_bjOI_jWjpxtR*dqhlK7_i%apLyy?JNNX(&8rl6{SkNvH{4ZlT`n!6j)2{G?>YQxEl7`|F8pDM7 z+23JrpI_gFljo-6cbJDpXDz*ly#gB;hsY!RZ^!zNw+eT7r)yMF3677P`yW`NGv`Cq zjcm(Mn&c3x4V`f|ul#d;OLun@4(8e9k8{D9&|9j6_CXVph=PeKGWvd#?Z!p7iJVky zyVDiUHW@MDZ1+&rzviKrcp%=nWs)8^lVVR!D7NTxGnC}st@*u4F?fS@BTJp{x*Ceg zsDI@Nn;68sa=6vQP-3gwdfl&DYuSC)O)sasnVStCSqhsK_?YMG7 z1iwTJ)}$M;c-d9;twra#dGz^c-Bje|U%ddAoxU&8jo5yAhNS35lWsPEI1id0XK3<2 zVDp!UZKdcf=r;&dbv#Jx<(v1k*=+pQxi<~iyknv>x%;-x50teYXS{YIeYRNy&wIl8kqg(z&d%Sp`@qKuI>@0@4eW&+NJK?190UXNM zophN|^?$+nToGcQ^h_J6VNd&k1JhNj7|rAxqPdrmwmoRK+BN9aN4qQ3fAdAPZ&6n@ z18_HJsdNsc4MXV<(R-IJ>ExxbR*`N864Ujo?ryn{rTu1XK8j_Dpv_$KU#uTK5Aa6* zNQTfYnTo6!WPtz339|$&z({C0kEp5ajtF0Ing@K}bMDMAprn>@!61J!;Y0LeCXp2S zflNq4Gc2lI@Ns!v_p-UpSL1jFE+&>Sly$Q*gmDlHc_;`tUAtLSlZocq_n9yLQDr?=l+0Q zs1w2n;KPmxo#VC)n{iHM+7rA9_~mL{Rf&bD-P(&1=mbPcbTCD`i~>cgG$2{HwJM~P zidQnooD5uYG9|r9 z>k<#sc&e;!mPr1kai!^Cfk;f?iODk}m3ua{oeT^ngr~{3>?dx06E`vcm%V+ z75*dABa4@;OWi89b#%C@9+IMf%P?_9CfX}J$SWSIpYUMrLojnt)q(Y23DFf2Wq_V9 zxU2`BkVFMQ!+sf*1q7kSXr`@}Z;j%XX8L zCb=^Flf}Ii9?tX>s|{-%VsK?JP^MV=pZ||3WS09KWq5fkur1%Pk{IA8FhX)l` z)c&rqP;W_#Ni*cwUg@#yYAF6R$F}4xS8o7`iTHbtr;`$V$5znQ;+@u(^qyJjgeK5n z>04aBgei{CdPf%Z_c-wZf9NFx7I)xWG1nWZ&|sv`heRivsAWGB$5b#tr5@-`$g*n& z>=BHWO6SS7Nq7^~MB>~13E3zAoSGed%UxdUXJP&jQnh}bN7s#5ew{nJ6Fr%^vQPNh z>c-t{d!3wNYMku^JU;0&N&B-ut%%>SY=`pX^ zD5I~4aF`bU|G90AV0z!kIBW&K$;3*MeLa@SE1f{clSF%kyFi{YI?zbuofqWMZ_B=p7E4-Xfn}d#>;G^~7 z?uYqA^0b&@(J%QwUIz|thKa8?g`mX_o!-a88f4)6=c%uq<U+9|VwRM(ojQS3=dR2pW`#K&le)UvMLETP=s^ zgBajbO`NR<|8BCt3-{+`kGc~JmQu?Zn-_k>vBqaEWS60W@?;+4KiGZbkDFpe(YP^H zH&1*ft0X42zk9mzS`A|R7h3*NG#vz$_d&8M?_f0m$1e%kJeF62_Ff)s>?Cq`m!a&7 z+rZxPUoT8a);63e*gU$|@Q4RDq*g(0V<@f9$V3RXfSbpj}9A>W!ZMovv;lECKwVW3cC}p zTWw6IPgMYh``Sst%=;lVLsvyhTD4sbU2r38^#$*QF#9_@i}p$ZNDU_zBV49$W)oFz z+SNPkvf47chM*NcZVGjH(Or<^?RJNkm-~ctRG0KAA8kPlkEnx=^sZIJ!cHv~#JP|P zP3eV7q(0n&NKX3d-XCoDq`oH(FU-OT2)rXJI!Ts{g~#jvs2gW!57kU1@?m30;8X_P zf|XZnGammz3OX9Bqdb-Jmm75~K~THqBT!}U(zD%%@Ce^Pf~2Jwf|nH*?z0$q|0-}+ zQwt9^I2Q;orOkA_gl&H6`M=670l{;NE7r{~ke zm$)AOpbxzN%g0po_Ij8kzi@Hpdv=s+K~gES2G(*RsUU5ENk`&Z5*2H@_R=XT923Kw zDXkxhVNT91I4Wjy)KYBY@iBC@zYFneXxrUFN@|X#os=gHg#apsU>rH^WPj*Ixb$#n zA$#=DKc$?tq1Nmmq2a>D0^D#fND=wv65gkPVhQj5R)4EFy0?Cb)VT}dW@0)jo|d8^ zj3q9rub76e;L_yyg(u{LIH!3i$MIePM7aRttgB2oA2ZyrP81K2=eMIB9Msj&<8Fkk zE^Wn>Lo`0Hy}dbK>Ho(ou6x13s2cm|#?OR({4)c?=6m748<)Cft7&oo92jpM>j1=> z1mEx#Ud{xXJqM{Qd#^(ABA@%KgG==X53v@SfLiib$YpFAC(GzG(nL#Ie#T+Ey0utE z0X2JS*+$_%p>3#XDQSg|2-+Ktqp%xHQh(9Z^fKsYadw4Y(w`Nc{Y!qK2Q0L&){;2Z zB=|9szv{f}VpAM}~jwJf` z_^ssUgZ6Ms-X@->BOg^mlcPbsFPQmSUOQUdA_UX~ROH0f+Uu!y(dqarr55_7(b|-_g%sTJx!) zETdBKo0WZgs_%HdUS+axbzRCdRG+_y;Ef`=gBtbkd@_W8AwPrn9ZtZb1z&0Z)@K-? zL!%)a#UCd~A)AMKW5 zmAC9*wj@!WW6$NjKzRD-TUp}21S)a#MZ++~2RVpMU9ykN_pkMw`&JPxMFNni_h+No z$T5|OC!nX{50^@FzzD|hp`)~ixS7CnpKV}$EpjihVU@-*Q|is4jz@sqO0{jkh0u_7 z%-U1jSuElj${-pYlR1BT5ICjs^JSEK5Do7lqo{9K(E~g&0)6jWNB-Cb{!m3Ur(UQ z>G;Ut^6Mu_T_n;U>qQgWTR^-2r$GA^iQ>NE!|IjG5e-}J370kn06rY2sT9m1FIf7? z%Ft5{(udVxl`r8|gcT#E5Aj#o2)2*$FcFY7HBR-1Uqg0U$keGxrzhS;C*ONe<{0$z?rgA`uI}+L4?rE0FO&hj#Q@>_YJeNFbYzRz17Rc=!ye38oOnc1ZaN$Itv zs^3WKsBv!SX(^<3dUVR6eS;iezRt(D3$;g`CXFI?xP7xfUr?bm4qB-b~6}|MVUgySf}(b|p}gworl#W2$*VwDIJGSC(SH8;A#>Pz_v?uF5^8H)xe1 z0?v6$Y8`#@N3bV7!%tk!IXJ+FtiV8mN8kk{gxS+I#DoNLfSxRY${FlhVgY{dfKF3% z{Lz-!g3Wu`Ox`8zOxuEvi~n*NaP=)y&8hW2=dmjDYD-|})sAS$4Siu=#ddi@uu##{ zDuMqV;Z^)OuA=}yrR7wh!{A+gfQgPAn`^-Zw(==(0+CPHRcP#$?-)9*TmF zrko5*PzU9`qj`X(Z*+P$x-}c_74!SmBI#-sk2Oh;_#2rls-80Zwhz3vPJt}Ipy$=C zLfvi)VNLYSKMTxJgX$bGX=#8NHt|N|%&`e+S+iPlff&|Fc*qCu!w|qQM7+`CsVS(Z zDjSp+DZAS15e9R31r2Gau^+z#yAwT0MoM~$YMJVa3Oc-gNp!IDOXJI~IQvXt76%~L z`|*r{ryM}ytI96b0FwpDT`;<^&X6&?;Z3?-llXdO;!^RM;WDC|X+b?vqJ8ac7h)$L zf4uNqru~_Do-cp)c&mAy3t*1)M#%zE7|UZWgAEJ3@i@C~y7M{oqSJ#4r!pcRlxN(! z_eSd2*{ehNpbyp z;MEAA@<(vC@_Y+MQSrDK&${}V+zVe2`Vd0hr#`gZhhX>C@PXm>T4`tvtCaPPqY+hU z&xxnf8T&&Y6W)C3w9b(^uRIa0h+id2c1_EwF@O&*7`;PiYVP+D#m{BPh00oN)5eQ= zgfskTwq@f*w8NM=B+ZXXYJomE0S{8(Hh-kH%uC9mmGIvoG_SGfU`f+IvU$GuT=n0f z=UCchrDUa{NuQXYrl+X3US;U*j2vI;YBh&d8g4bfiTD?8c#FN_1b?72Wx14o{n{rS z_?CMHYnVdJ9MQ3jBB?{8!CuPAzj!Ot(*k_6Xn#m%sS@{2>mN+(A2}^iSb7;i@MM~3 zra?U=#1OiEtITUun~gc%Z~j~}K{)U)4u(xCGCc^By6#ERQ?r=tc9MsLdYA8AdU*}H z@(c^KRWvmdlQeFrI)@`An19QsRAw|FeRPb-g?^wDhn9cm-%{eFW$FIiW_qa$qekZ* zbsKzd`q?6qhHh|mZsIl$CU}1YD*w~fR?~9Tycl{Shqk2&mQnIex5f98^&Dgv%?@w-n^vrSd)2y3b$-7TV1 zV547RjSJ%8FNGL3&SbANRJ4@YHQ9ELW=-c%!(fPpIks|3%F4ge)`nLpYBC8V^MKQY z*`mK7hl&XA{e>6gg|x(H)PL`2Yo<4IA_Qk!k-3Kws8wmH3YSnBE+k5!}t9-4h%Q&`E7F8$Gh*Y zbC(_V9&w_+(IrCn1Gc)<98=Eu`C>hL*5Dno_oJe60k{)oP@-6gC33uN5Z zj}bmFc0DWcYP3%3osUcMpA{YZ2g@fSLqoE&7fg42{8iAqFz5PQ*W|IpVRmp|Ooa1j z?NKwf5`7FN((b488usOw>DWL>TN*2)1s?&X*4Z6a&FF@57?RiXK*LSBd$$JnkqcJ5 z;HbpC^g%tiMn`-}`qb}uZc7H6d(2}0jhvioKYz<7{>U&6e4!WDFp5b@Z@*ZIVmZTD zEG}d}Ftk^K4ZYNN>rD2(aj%r2xe1$h-Z*afUK*D(ax_GCExUX!WnWY5jVSd$0g#AY zm*t?udY!vP*zb6LNJ-L`YbfQ$iOhzq_ zItY(eJP1Bdtr_^2TCpRC{~ZmU!i+TJuWt;m!N0kisWnV&E_6BIhF?P4;|$6^pGBkO+;u+m(laM)ZUj6zZM8~8irP3Wf>pt}8qR!X!!8pFsJKvo>&@aXk5i%K{ z1nUMk?d^U61p-R5sc5HS5wrA}XXo?vk6icTPyK7LTL!B} zaSYnx_fIAd+`FT$Sk@iG3@7K`-}NMXc!t^D#0TMhU1MqO;>d?A&}j7mI|lVf3H=F~ zR-N<*+QscpWt1U^Y4~s0LL(R1T+(OaY_ALx5c$4`2jqhQkD8Hp93j(YaD;Bw)3hg&#r-xaF{QkK< zz8%UU&F%9)Jr;B7bWm=dd5yPXMq~@nL{ztu*=a1c|OUs)d!?EG-2 zAvj59to(eOVJs_w+A&nbS0|hFTTXU%bnelwpsFKR#DkXwRg( z5@tN5)GYyNaPB`#XVJ)fHO*c{{>S!hF&TeulCuqLqpvN|?Z?v~i=N;MnSW1ZpK+(O zhw17z`Tm9J>CP6D9rwTGz|X+UvtJ@lx+ykW^SVnU>Fh`UagpQGx8zgJatHIRC;xwA z^s8Ro>g4FqOT49{8e2R{u5g2xOT+UEHpu2NpPeEr20=bbuF1)SF(qJM8`YJb4AHg6 zv?s_2+X5H_=mJrf8i?v3iE+bakB!2te{iUJW9{Iu07K&y+fG+CYdK4dZ)nCi6a3Gm zC1m?}DO#F=p53K%dMyMdD^Mwm1bb`68^>NCNg_*FG~fgXlGOhN9q*B2L`%)pvGxR2jl=1C7;8R!x&jK9*jzk1P ziB*~KfYaX(#e5qB~NLiB%-vX4;?3BY|#-&d&wApT= zBoMslZY)Qc^6Nq9WMPQq+70k!)fYf3pwg%b;be_6OsM!!GWIgal%8A;Xkd z5^~}JtM&?{j#@3oO1Z$xOB$$xeHd!;F2oxjZ<~(-Hpvm+2Np=ba77rh3Sn2S7o{w9 z$cK?uCU?>-0^`<)KbbSNYOmcSH=c0Hw4E?ZM`ulGyA20`jQ8kp%5RSF#w0ShjLX-R zjp+u(>jK?jE;1zl1>aaKVaKci-Syuoo9!i+k5tiIoh904Jd?zCftJD?QTDvNt@77o z`~Angcu+1q_3m08YI2Rzv><)DVhteRLafWHu)6X|Qib1wk7T0he*9~L5>2fzpbjTrdnQo6hCpa+W`(w)P zL*d6D&7*e9K;~B6HyfEdHfl>|OzLOu^|N6Wyxd!Wk-kRM)`O~V^ z-W;IIiwtmNXvnrIS=I$yl4FML3#;iJgUolmKJPMd9oMHkg`~uHKCA92=RiuUCce(q zZ@8a7?%4NU`g-qGaqw~+r1k;V^&#;tA_-?1EXNFv_)iW{pqsVln+Z)Gvu>J?y7Cu@ zJV%YX@f-fR%RpK_A$TZ12l2(uT06Qvd3I^C)gyY8SBUS7nl;fkT_1NxrAN=vuB9z) zBGw}HWNb2p?f#8-+S*`jd=_UT=hb&Y<_NFT_>#5 z{vzaGbBeXQ_$0_s%>K@~*~RldU*x-wi(Y;62)#|`uzF@3XBQUKraBdif}l8&s_~tv zHbDuo*?!y}cCy>DwMO8))TpOvD0l5)@{|lG>M|JT1jhnrZw=!_f|l@2eS>RHHNjX` zSfdtP=iVYA7(L=4JUL4rLnrRX#?3dOoSt=0RM*@Y#vFi6q1^xj;v3?VO> zj}NW&NHEM{lwcnZ@Kzra?C z^^#qNuPi>LgZam;6AeBEy7FD$JeGA)+L8Tkz1seBPlCO93n|v6<>Z`!x?IZGh4KUo zw{_PqG{WsX)8M;zZqi7SL}vkM@PRs2pntM!Brh+$u&?GY4yE<;q5H4wTb3Vuvh}Q{ zixgbZbKiIvbyP`_wRGr8-Y=!DmM_596DP=aFk(VLrezoriS*l^uMW(}1~J56zQ(Ys z7Vbg4gAW)@anb}|KLL4mJ5N3R<9%q|AHHE1aH#*z#@4}XU3VXQ9D%UTe8t7s zF{&nO^RaRHk;g8n|6&ne$_M%hZ>mgV5LsXrxs?m=kFLfiaI6ojHzCHbjNCwYzAsGN z=HZ2t5=AGKlm4H!JQuD8*5MWC-k^w4s3M+DUR7B>(fG8F>1b~Q??^>P#7lW6PFXe_ zm9xt7eVw+*VaV=Z^{$g@@?GlB*k(s-_IB<6WUkWV7U~)dkYNV;5L7e<4~R=f?U4X|2*WIEOWKs-Q~DQ`b_L?sD220L$D#B6SjrfR@># zOU0(h%P@kava->9QElwAkVN=53L~SEu4SVczY*XeG@ilsY?M*)Pc@!wQ_p`pmw9qN zs+D&|>LxN^yo4=jSC~JZ%m8y(<{|dlJ$!}K9`(?sZsldzwEaO%Y4(q(&0H^#M<=o8 zZ=>_Pdk*XVA2&kqeA3t#{RDOz`r6Q5l5q;DD?FO9ntyBJ^1a>#s*2FXLZGLI;bgDf z%2>81ByaGm#WzNLc1fl3giZX{r*cDT7|$(a!EVO*KB z<4dP$Y7rKi)jIO-QKLh`il3CNEve%PxP`-O{)c)|1@yAH+)aH>?HAuXm!QFxlRb<$i+bsJ$nQ%KgUi?t5tH%;hrXjc+WrVx=#mb0q#> z^pi9+6ZaPo@pRm})G;hn{IXI0OsrMX*hINl$}Zf0lPDEs>({&m8_WNJMy+@dAFeh} zn4GtHL2j587uHt2-t$|Y;&3+a>9=(r1{T*j;G+}YJK`*N?@udC$dx&dTe`bN&R|825K#qrP&v~N$7DxFfgWTzp&iOs~iH| zZEI)VcLGcR``RGX&3!L8cV+)Tl38*~R!sQ(Vfn)XP5uo3#0>2$=Gap8GwB^rEo#A9 z-_e%AcJK67_WUE(;fm5Nl>y%RZ2M*+#r3(q#pvmGqxe{*Ps@Jv8cdJv6o0q4VrQx8 zFR@5Y8t!?wCLVGf*s@`YX(3Q0Pv0yB)~9yUY#}e2gufL@o_yxfmssBgwyREUOm#)V2TMK(vmBhaXj^ow&W|a zefWE@G~A0tmZRN+ez+e6kIlJ+j84WMae9lBuKMx5Ehi4};>sS?6o(E&AzE3luDE47 zER|%BpM=A0*!dPkR+4L)?VpFr?H=ZCG$Z)Y7QCwM>b%!`|9@wG=tS>0a=!iO_@9;t z{m04-;y6uj$|2vn62LB{l{`<{KZ0Z1*e4qMJi+XWe%O!iEtN)2tF=L-r0s)i$!dxy z2K2R7&U3XqAKuRmrLoeu=D_cPn*{Le*gcto2sE1mPjlvhExBnriiul$BGw%88CG2_ zAJpIpb}srrmdaFyo1F2mx_|h54Jk+9=MI2Zje~MWCybo!H&=Ngz}hf#3S^w;b&6>2j&>lHGXI4Bc5WqPywWq4r{9M4mmVuh!Ke&~ z*=nSj-?_J|6gm(Y7&G3gG?BQg%pZ~Gg;JBu`kk?WFBre#-9dZ3ydNy83Btl$QmUKS z*ei!!wfMGtdW(wqP5ujIH!TWLF3IT8Z>Hq3RSsl-+6ntmZP;`})lIm|xNk31fElgqvio^(ch&@y5`qCf zBo>d;WJK@NP7sQ_8g;dwAqHsbS%bV=I5<$c{zT@%J7`A%8-f-Apaz0WOHe;D36qFu zN27rblA$`=d1~@I&kbAcOs&I5#mtI{zEo-54YJFztj6>gr6+vljVAHAuZ%X zuYWN$PX3}CJ}0Ea{~!JLQ!U1eDZ!XP_|fp4UXjt--7Hc%`sNmi+K@YabW~Q z<)(;9y}?}85iyHzuXC%Jwi#KVainoPW0j)h-%}9tQ^=Dv0>Si2<+B(7nWwv8#F2ke za4)geZoyg;Pk>UlLr-?vt=0h}UaIjVU%HUhmb2(1wTU_d@g7!?U(D9NLguU0N-0rM z#PNv67@jsHHW>pEY7lT@KM!vhX_Ni*vtZ|#AHXA@{YjjvYGyDHgJ2%=SFNUm-_p=S z_-Gh`Gi(6N;30<*OTSIQrW3{u&-{T2iG-WM8x6z$@hIXFE?vKO!~PwPRMHijg&aX_ zHAuMfSKC%U>rs2{-t=9#Yk@v(8ui(;SSA?bXOhHzHmWRy|#WAV5 zG0=4&iHI}F%9X?vUZj1AE35Gxv{x*|vdV~6DJ%!#DP~nSR%fNTuuk7;&Nt1}%6cBIL}gY=ht@@P>~)oPsYLZ$nLe#@}0CP6A$Zg|seIWN?3lRn#48xH#p`=S>+u|=N5cm{`jRH}46Y0=pn7Bj*6y=p27Htp*==GkN6`o08X*MjrbZsA+J35r>EkNu~hv3_J@oV_Hjv8 zK%F8?BJff!T!%E7azhF}+{ll(`b{$Ykiq05?y>_q3@prhSoLD%-<%0&ph%G4@-t6N zXufjg^Ozn^kq{jM@CoX~x4bpi)3d9wDc%s9Xt(sMA>1)MH5=K+}#Al@Ja{7%B=nifT#ywM_SAFWmj};uu@<=P>fK zw3Rg;T3HC7GXDD4pU4zp4Csen`#Y}=IV_pv4|hD}mxjrP7R|#Wn1@-_cT`BE7jrFE zSypwIdP+Kkon>k*n(|Z7R4|~)y3r?*11g3jP1wg`pHf#C|1ls4;(llUB#b%Y?P_mF z*~dXRXZsxnrQu7Zuu8EU9N=sFC9(97v!Sy*BmY3IUFg6~MQ9L3fD-TJd6hGj6cmJ` zrwiT^j-HT|IXTJN7fq0@z5$K8%n`nH-_?Wxo)JD*pmfSW{l#F@ci3QqThHVXYq1#T zp)eehQ?ryalylCiwkKEyTn`M}({`VrnN_2DPX_!Q>1Os28fsGpWiFP*c=UPXc$LIoJ32kj4S(AFn3H)})=8>x*dqOpIPI zeC7Y+2mM8YM;g7cbi2?@@*{)|lFf#+7OGX{Q?cb$xHHaw8OX^Ls-B#eS|ZJNeJAM1 z^@H~P^=t4)Z7V%lU2=?Tw^$EzAjMK5_H#{1)Va9K8ZVfasyOp6-^&y9l@rjX;Pfv_ zd)kF7VgWndrRexrR{f1kF96Lu6YMV}-#vMTMQH(Ds(BjsuY?~qhTCA^EpOIAlMZ{< zG?*4v0hL|{BlPtlQQranBZIB$n9!u`oM+(<-}n$2!d%TvYkat6W?aE}w^k~BlQt`V z(z7c*ILk&HIQPVf<*0T(Pw^$Hx&ScPy$h5s$^mgJ_wK8g9^!FHW zX?nm&d6i58_=Ii}*QK@|>SU0Sb`yvjgoUNrNLzsBkzHsnG;o%Hti3L$)Df7m)VN#1 zs;Y3AJ=-OzyfIz)1=vb%ougZ^(=H}=fUj`tY@Z7-h;&!WIJEc-V0;n5B1oW>|=642PQe$@QW z`IO)Dte`;6SJfGJ<+q)J>4B5qIWf|D=s%kDPgg&<$dLb*srj0E=3r*qlMwjMB>f9J z22I1RW;PBObI$y{QZB}75*{fOPGS;l+X5*}OWF4?iUIv3g9d-$0X2d|&pZs|y0^4yEF9R|A!~`!{I_e5d+a{^vJyUg zvjLTbwccKWo_iqXa+@CLExFh@`Jf_({R!SM2Jfl)$JXkbdF!!emth{?-7~+JR@mY>fsAC>v^?a`G2k-)$V${3Q%7x;y8se zx8!9TS#9;4cOyvsgMa9T4IRVW3t!FqH}A89mT&gl8g|2NPupkgwMv;d42vHQ;h(qk zvxU(w?gAHXY)l|VbRN%+=r!@=TS*el<+_1_Ae*G#HCF_>%q2qqdZnT*Us!|i$Y#PA z>}{_eQe1`BO#YJ04U}Ki{pBVN^82q|gUPQ8cy#zF(yH6ra_ZmfE_WMt#_e#4b#!eq zkCx8J)a&$jj{%tAg2>WPQG%OVeDgmCH77B!S#87m?)}HKy1Ws&1iew~@qmsPAWefN zCE;s=x+eYb{~>-kHk_Rb9SFLxud;$7zX0XiTsZ+QH*h8xI7Uxio$d8$N7m0ShVkPq z@UdNt`#9y;uS@8g=K^Ym^>vZnqlVaLg~63agH`nPl=^}_;a3~T70hR{_Le8RG<vOa71VK&{0 zuyb$KvjmfHdy^A#un8?KV+S9U2#G#~-;84he=N~DfuH1&pUdo8)2j2qALt1j4aKK{ z(jZs@9U-1Thxh=`7{(Szu(Sm|MKu936O=TRPO35riOF>9!@w}HDeHyb9Z5|@+^}iU z$PmvH0iCB9;AdY4IS@zE2+Q#dH#dGGOQ2opX^1knQ&ZAY3=pErIN54Sf>cnt2zrN9 z@6{CkgMPkXW4aA{J*$>zwZ|ppj9>?`1pMGfX21}X*O4AzGu-hUpJKwLDG98O_?ecS zUGRrmp9_Xbw01!IiPJgmw>+B`F>&Y2F(aH{dYe= zzY<~j#3Shp7s@dP-c!Ku%erLP%RFT^c*{9`3;n8CXYs52<%9yuyt(AS&ZGI5dw;AE zo|t(sI@@YC67Pmsm_u?nPUaJJEUp;bIbZz1Ud^!})|ULS{q5-0eLAyMEruTHjKn(A za^#c25)yVZN#)>TA1=f*Xdsz1@Q4D;mxp=iiP}gTpiZDb&U#V}HjGWehzw^b!)|Il zfs@2fGnrluK5$6MpvGK?f5r}XLlgoVE34hGbv~-S2_S)sxmIy1qtroI-FNgIaFl z5>pO;DJef0iT$esAuRBPV(IUrF7vOmU+|s922;_O9;fk!!T8J%Y3a#=B$yfOR)ecZt{ti0WaoaeORF!Y`k%Yc z-R4JsKGEFn3UVuny$jtvOzk~H0LJn8zL^kwa`Pc#5wZ*1A78qV^Aj=e-9LHZefs?* z(j*E=X?jq)SL84f=O@3_8(kYuIYmm~?Dgc2Snadt!?HO$ctevPLpe`Q5>vW+{6#+X zahYU~s^OfL1PttO7heH4s`(;xdWnN%T3ULiZmW(%N76eM9pw1kRo&T5Q+5hhc{`cI?^jED1kI-YZ z2@8Fh8VeDPb6e5ydp*qd4!gnhXWuprb++$ed^t7?_Bd0F-2Drbi32aSz|!g-H>Uq9 zBSguS7s{O`aErkDY|?X&iHC#UEs_w$sruBR!v@0)hHYwy(j z{oIL+5hLXd`ECHy5y>_t@mCEL2`A4A*TdI=@0{PLU{ZZb?>$JZ6)hzg&L5&nJzJei zBdInu)>huSLL3@o*mVxX1>T(ti~R)`tZPnCBR2{VSn3Yi{=w15+nP)44nWb7g5U?y z=p0}n=8s4E9q}r_HFCF-z;}EYSp4w8|6zR>OiNW> zU0B|*weNg8+k)v5ZP;gr_x9djK5NMJVr)i5to1rtZiBS zm|s}Cfr1{*Er>DKv&o29@_My)eJGJ&9@7z-ikK71vlW;aU~#B&jdrCdO~sJ}@j>r} z`lY=Ss%i=A+W*yjUGU^%e>Lm%1VZa?#2jK3#Ievd?6qkhRWiIz?gTe265%He>%eux z_1h(TB3(c}3dybUcs)q>PN6`71v@!WM?ZOQgT1hwJLG;%>NW)_xwILdeHO$1EW#sJ zzxW5^H8+3X_?BvA1OaUldhnj5NH1w2=B%! z8%?iZB{6Q;dZ0vZ;x9NOEWS$co&vW4Q#nUbvY>-M0b0|qeSMqoB$U9;!QMkS5O{_% zN3`spM&I@IUooqu>0zJkBc-5t4hTc5rT%HT_~wB8kI4fT6^LjT|;4fvWF1%dm| z@1=2(-`ZEC$Px84Pg0Y$E@&ufEtC{^)a0o~NcUIu)pEH*S`*I*+r1?XB{7mvvXst* zy{dYqOY8ztlA3?8WE6>wAa1@F|FP&~we(?^-#aj|v^1GY$EG@FyEYulq-2&tgCCyA zKRIg_o`O;@2P-aoPp)UW%r$RNX+eUWyLt$Fff$Abj=~8{#o=gmNcKYSP~+Ye@#EaR zBR|OoYn}*`!XVfnFT=}IIScsWPM!?8^QdFKWi3)B_4J6|Xy}IBNX&?8I;tA~V5FnS z#tWyoEAzo3ejoTqopQ#yj*sYv)~etSCRh*b*De@`yG4?o8DpjkUak4tRgQavmpl48 zI^j$FqmV6Z*-%4RPul#nlg-O0KK}XNCtyQ`GuqdD{^1;FL`i$wtkO)w8G4C2@h6Wv zoWu3|Eo|K811!Xm+@l)}v}G(V+ZP1&FXE3W0!{NuzL{Hh+|^*S6?>B+_6MsNlS;+o zJY{udTCt=_ePaSPtb1cz*}biO(h-_7O~gsKd*m|Vi8c!O>m5)B`bI{*LBFqqfdkFZ z8vS%`MyWD(-b=8rCOxNN}5HxU8$PF|5O> zmsJh^OHK9F3H0?`i%h$$eKV&_TraVSm69q%r+O`)I0BK8Sd?pOzs56jcdD`@ zGcT;=1XH40FjN_5Kxczcp<-AxbkbOo~0Ac0sBBi+f7VPSNjxLxNMz?r(%8A zl*OtzV|a2L$n}OfS@Q)}H68ok#up((VvvNjIMJ(=^gD^iMlB^f@d|<-AzyG0I}>j^ z{OnG=v_-4*NIwv2j}eFnES@K$fU}F^X!mmc`=7kEwJW;|sbcu(kGIm^ zxHu7u;JjA#Uj8lq57mT#x{=IN7{)d)_0LbLVWE9yNaTXQeJKY4IkjYfhVgm8<&8Z* zh5EoLRgqpf^XcN+mJRGP-E7*K8CG8iZ6%!dAiFG-`z5SP|1WcI8!JaWkow-!kcw=J z-Sz2O2e{gM|GpJWxzJm38R6u-P*Em)ul_klfu9mx2<>87%cZfUq}%fg`=NlOvJG_XTedG4oZ%@r2Wl{SjG! zXy)G?!J#I1Li+*5+!9HamO)V3YHwA>apa#GVSNacK5PlJ()^V_o-_0_+#E_#p3-&( zYFR+(@DG!HWG^G6uXoUWpP-)^A^nSd4)hSDAIGU|d_yi0l(wAQ1s`FGG<~PLzEO30 z{Pn?1s6OMTA!d)9%1(K&v6;Y@Qe2<7Bg@J_^ZPMIGF8s;D6cTZ%f002FfZ?6axM{aAoy?HT`>xkvC5i9#Ti^;dE!J~K4mtp+gt13e67)HJ|%07ax{mI#((GgvZ{ zNn7zLgiF1wyo9jH1kxMY!HhH)CMjE<1$CS*h3smJp<>4( z&efY`#YkAKA98rfS~BW?+f?zAyr1>~{fTIcS7;?!H{`Jy1aJjRo05T zIJWcVOXvG}`Bg3L(Dg1v(wPjfrA9kL66z={g3u&u75uciI@|`UN7t)Wei)DsP7~=d zt}}Ch=L0l7MqsNmHcY`h?CdF+V>B$n^br6gx}v->0yvLo4B7Kcn&MzFq6pr^6oqWl z-XJLq1Zl)I4QYmY{WCAXP5W`58sc6-9{0a?h`#XYx4(XOdEedVcX{33cU@PNS9MZS zDx`uNswIR7M@?@6XdABaH2eNowSEm_4$L$+aZO7&lSP%KS46v@Wt zz?IVKB1J9auFh|zJiar1;PW%hXq2n_bBRh`lx(+yGT$UH4b1SRe)gS%4otclh&Wb$WJUiaciaq>F zBa)JN)|s<~YK0%X6Fj!@p6-7dZ5%g{@@B-x5zuUCBa zz5losKc^T*p3FDxY5O+dt?bQqB{--1i*iQiO>aa?6X~tfN+-Dvm_sE|FjMXQX+-#r z!95@+h>L5@h7S*{wLd${NQqiy?}sIg$R(L8X}|6hEXM~%P37eBP-Lngs=uR_H%}8- zI{Hla>vhEczao42Bo|&DaQxpqDJGLX^JpFNf9;?uIti-z3J=DYKzTQqLTY557ZPP_ zk)O5&BJR5Fcm2=aY&AEv+=B_SZuO0N(vv}I7F(>fGKuYbo6A2>xu(LS>FRv`=bs^0 ztmh-BoW4jWMCo;2${SyNaNM-(ljS-0ffu`U3*8nO=@^V?$jY@pzFl%R0HXuDRS%bk zh9i!8PELX3TUrtq|3$U5Fb*cq7HCFd)%qjJ`Cn3yRo)pr(wgjQsIwETC1?43=}38j zhc*TFmfG_=H%xzE!}A~i1=3n``@7E1c5if)hf}-Mx>tQvQ(3>NaVYJzyM2fQ{~pA} zoj5rArYz<#k?^Vrn3Xg%RXM2W)ph-uT)2430XcdY-bHhN|-|oNtFeINq3NU1lUZEY9}xvbTqm$C)?OXr3;5YfnBC+UezPgbbCrS2Z#@FhfH zO?@^xs*;8+zeD*hweD?ZB|g<(gs8Xuo~6_TX$wr{#L9OMjQ1a|g$v$I4M1@V_1~62 z#^=^t<7#eo@A}1;I{KTMkrR=gk(1A`+f*{;trTuRmIfb z=^k)@!vF3M_NI;dNGYC}Y!CWT;QuXuPVB3Tf;R|eyBermUaX5*URL;W+O+P-G9-B5 z+2X5x8NYn^J2;h5`xD3X|10lget@>+TV zgnNp@L0e~f{%=P~v82|17bWcT@P{wHvmP7snab(LF4?hBtKyGPsy3XAQM{6lFUmtr zscwPBDG!lrxWM*?57XNDpkL#{jn6AjJyVeoUg;43kA7yu__;;{OAXT;|G{^}qC_8{ zAhxJ;U!5|22N)|!3xia&fl6FkDVo+)eha!T(ruV$P@h)j>Ig~KG+J~-Ee>g)Mw_6{ z;KA{v&k3Y%d8zJQe61!-1wK&Aca49=t1(uMO15;ebF=QJYhddr>tQNuVRLDEGIvxQ z&Uxpu2jtiPjh%n~Z2NV1@f><1(L9fY)d(T|ahnBM z=v6D%O>I^~0=()`Oy4stY56nS+;=SA$(%a&>+h6dl3(cUof65hxGbEu)i~w{lQe6% zf{I94r7tq)7pKxX`c|$=$?Z?8Z;Rt2ofy z<21v&>+t`Wl1pwZy(~_?9}{EwN3!8R@>dthT#xGK25U?B`fP-my)vNu67;yTE3DUS zF!8uabV^!vHJFVB%ya9@^7#oGr$3&U0Y>Ig>&dj#AoM+0CkRVT5O=wzK-h zi1n=fZG-LkNT((A35+GFl?ve*Ej_YJURj^Q&BcDg6YP*ezI_O=T7CLe#OQt^KWjc} z%ZwT>XC6iLY-F5UTzkwV@aX&HrSoI^M}D!lVmZjSK`vGn3uNgSAtjB=)m z4aXU%8_|aZg~TZ>^6ITMRnKZO)koJX?J|~2ROP+~W^A*J^`&Ox*(%b5RBV{Uk-Wh$ zH^3$XB}I-T{VgDgKU7uh&*8o`m6(?WX(PObv8^Wn5Ug^aw&a)xfj$`m}DJs^| zA9lKf40Guje5)ZjYauy(y#<~9-DzUmVIFD_*e;jSK6zIDB*Jx~C-lm90Uv5AQ}4Ab zu+Rx!h&V6WY$U)U(JhCf?on)-!O>Nv({n27YN^Vj{Hp=r;e?0u?UAedMoQk&3h6?AH-@)e)Z^; zM77x}xX+8zwm8}s3Z-}b@-I-K>R%cumod;Cm_z=iS zAda<-D0=YA*Q3D${krwhiwT@)wgUfB*RZC2XUklo?=89Qw3!kAsG7hg21b@Fz)wr0b35eK< zf_YPT@>A5++^T2jX*KngK!i>`+q`)(^b-_MM9DwYNW1bR^Q4==)6-*5Nl=#f&iwDm$5@Hor~By2xDzDHKxsM&(x?tA+`cy@`Poy~#batj z(`0bKo~oWa5;x1u$2;|wsyAVVw-+Zb?&&igS>r? z8LRequOW-0|L9`(3jc%QtPk8_)85^-+BDWHLHIT(G^&c`Ag0Hu_$>QtpL(Yc65Uu2 zslF>jhgwr?=dyAZU?8hjf$ISsh=NJCI3mH&&Lg-F34$6e7+@;vDsiG|Ef>&11#u!_ z!UzjuxE73fg!~r+*bzQr@aTpDk(NrMh+plfXu&h0e3A$!=lsBSl30;cv-x^@%Ide$ zbOTr!nF1Zq)TN^W;sb!Sd*wTQxRz4kd(c?bkv@naDcZgg&=A$=(qvniE5gVL3x;*O zjE~1H$q~bX0r^3k6*$TSE33H>Q zt2(dJ6YiX=wMNE0(9C{sjPq)mLfbUMel#+w)%pBkW!;a2^K+yLn}CbM&f}krRp;@I z46$Ss9TFcgi!5%N=WnD}_WVq{B?s4v$Vz4(S%SAaMHlS06g(V3pVr=i*?}U!4ucV5jo|1sa8- z@Jit*m3NUI)F*+(J@B?1kgfzB^vXTrXu<{1o$0h%9Xdk79rP1 z(0nT?;F<>;O7o@(^OwHYXb`mYv?3)V{7A@oc6r)5t_9Z} zk#xrf6y)UJnZREu9?Llw7a?2shv*pKKBYraC)qE=7hadNN_R-azcFzMX%1Mgs zF?rB^P%Q~rp4XHI&GL@12NPenIOH@F>o1=%T8Kq+;GCQN;JP)y=MJv&iEEXjPC@GO zwCR2AO%Js9G9x>_W8`O}dl%I1t%~|QU=!X3p6C^Mo4A6+FCNPRQ!Q7T!uhq|ll|{z6 zDK~+Q$r6lBOrjb0j$FZP-AxtBs*=CVqMyd)S0$yOTFAPcGTo})&?6kQO?_L$1aN@q z4!}6|KeqY-h__&)Q$4ndgAO^B^qiN6-^>^PAAh=d8m;te-Ol_%_R`C(M472!s8nTh zC7yRC*c!Vvn5(vjJ^9J6l6~ro`S(_^nZJFupfa5aIfGiw1&#NTFQ=u+HsB3AQ>8P# z4cEhjT9;EWc$RpR7eNpSXB{@Vg3|1Ki*h-?@y7Yay%*v$jUHurR&^_}CaN)c#>5C@ zc-z*PtS17p%E2fW7H7nC0S3#1vItVT^iOw62}K4|@;$=rL#DqXS7(5Gn-$X&;&{OA z|LX(YykL4^uO)9NSQ~I~NFa9(@UC-bJOu~f(3-6FOBmiVGTAgCuDySW-LAhVPhjI8 zNc-QKyY3M3HD<2($KD6TD#5XcrFg`KQ`DWQJ+VKf*~;i<^8q$Ym1QkmCCZ|mN=j<5 z+JvOC<)`uJPnD>tr^;-pD1Fz|A}U;Y+?Cq&KR`>Hwr{$wT?~>PC$zb}N2C2@Jw?ak zFJ!m@`7`rQIkCW;03%--4mS~AlH5B8=a5Qu%!6+EPdCYT|98o}c)>Sh8wU&HJZ2yo z{%HGJ@`mDIw0(vf4o3cY`xN#_aFv;>XPbF>yzYZX659gKzx?LbYp1c(40%H>#Z%jj?o|y+9s3qY~!EaByc89K&p`xn9 zQe&yEs2*BL)zI*G7O`NK7al~ue3we!nP}G>x=(-((5uc-#{26Jl?1UH)!g_;x6{%6 zR+oYv!=;b(@`3(<;xaV>hniI zdU5JYLIujJ)RBky;e2E@d7p=Hgx3Z0UEbGSWL@iknsW!@^8v6M4>ZQ~I%V=}Er$D1D!bk5yqdO9~$cMxM3 zz6B3=Aonl@^!7o!;h>Ml-h-UNJ!0o#9-~)qt=Cqw)h|_xKD(~?o)IB^8DC2%6x3*3 z=})Gix-orDsdvuT$Y1G*6!id&&vO$@yMBfg`YoI6Qz$;yqi&|He11=~6Lb{stY&F3 zwUv2RGup`1H+Sq?2LW(li(A0RlAren58f8Pa`zgA_i`Z57gEEy4XGxW6UC&$dms|J zW2)+D_IZDejtTiIlqz(2w)-OeUi0aGoC^#GnNWgk6YXf8{bglTA57H=ycM|3V)TPQ z`J#uOziaPWMA{XEZF`G{b@WfG)^_WVfs;!yx`X^3YZ~qeCD5MyU#EGhahG2ZprYVX z+v=`RpWCU!>AkiRl0P~LxEM$6%88HIDY!2jd-UcWOUkho%PG#}$!H<;5qIqS=EcS9 zEuXjfIOo>%80IJjQY$->3*<#5Xa%1Z(K6Q@$sxi=cw!4dq8b(xfZl0*$lduHj za<>*0l6g6}>DC#L!)rY_J^LQcd4}U|-|nK@KjnQW=O1)(lFND{1FTO0hb@o9|2h^D zRWwwzQ~78dDcE(e8O&_U^j-SrxQKlYE1NK^sG*uPgj~eQyZs=<^N*I?*E*OuaiwlS4mMnOG}r;F!_>& ze?CdO{uPhcl7H1O*~z1HLkz^beO>2(3NP9Mf8ECD%cUEX^3Uy0()z4+jF)I1|ArS9 z)6%sxRP{c)4(uc?#*U=*od@nKG}R83nEU#32W7n8Yt6R*3qSV`o8wU$t#LWSDR})P zO@Lu!UQCc}zphiAYs%JTloVcP!|q-q$+uu&rWFGi*TPZrmB(L*{?Fz5HeTl_OG?;O z36%&zp3h|Y22ZRtBfuDSZor=omIKfyu_269h*9--I8on)T!cVBY>vy^@O`%(oxuaI zKRP;)MVM3`d=xj_iaF3e4sOQd<~2p0V4iK+`^VL#8I!NneTOktoBswep`h<32z@p# zNj`e1_n1vuI?J!~ppD)?Xb99|V#$I3SF0DPKh2Go%uK|*=`h$vK~8o+pO& zvfn1nYl@0W3c5yA z^xCNDSPvdJY+Rqm&1%KgaeO`I1_3TTT_24t^Pz3q|FF`ADpUH?N8T>z#^vELEg0n3 z<=M^EOz6#NH27w~)ze9|$x!O>rfTwNDT1jSvo&yg#u@=ZE%3 zwIIqJb18`TEv_TAAy-hFD2n(R$ zBopq->4umcjG6r)$X&_6AZ;6qrUxn}fF&H~qYBm&M?4^Z{`74?vHwg>iWf+mD3T#{ zEZvN|lITZdqT~hTAa3Kyn5zJEzmgbocSn`cE|lrtZwNfxDwlt62*ajP|{0* zYb1(~9kg;a)vXFz07kjA88w1p3K_5@x<7*3&p7|e?pI^Ex`w?-^G| zj}vaZwO;m(MTgeidYxOA*3So`sI)GIJkmGc_#Jisc{E5h^)h!4gyMM-!VxL*?ns{C z8Y9~hnYO;`RX|TGp#a$pI>Jq_5EyqLQQf+aU@^a!@Q{-vfF{|={ZLy1M{t<{Mnn`! ziEtk(yVPy5^LGuc!DV1`h7RELCphqeb;9vBbF?MOwn_JZbobqxOgr_rK#9d10g+M<1tzga@M1b)LU_dE3>& zDTXQN|6#rImZaMY>YR@sin6>P+S5@_)c?q2|5f_&2nED$>JN7qe&x^~RVp~gL-bht z&1h!%oCfo)gSQavUqxFI!gtukI*Jua-e(5?HRjWoZeh93Q^fGPqO_Hk}z$BT}>yU`+ zH?P=9EL;vd9CP{_*#r2|ug+Sd@D-VPyAred?=CBVktEpVFw#8`)PB?2x>)FWn)I>7 zamw{q7bWfQUhw{;j@*g&*6A_l*QD4bckZX@xdgC#2M7cwwS@Ou!Tl*=fdhnAehq@* zJ}!Q%sMq5ybvH;t7z6)5iX4fi^YbrG>_N#6lHX zwD!%k4$y^(ghlcEkz>}LXxb1ldy42onl4sBUZZ4GliA0!shM%OvVvfNGx9wsU%C%& z4Zdmh$>BPu#ervQeCFPlFen1Ex_UIcb^91ybSZR!+&?@z3iRK}tq6ymnGXKf6TUdz zxmn^LlwYIMT%T1TpUzjab@sZ(SEUzM1s^ML5VI$GDrJ1#`OFda8)rPV=}NJ@C_rh3 z2N@k`PTE`-q3flMZRPs2Rx|UWMoL^S0rFuxj|4j&OXQCN67KtRHZnbV6TU&mwWvJW zSCW7FI$??XHCZ|1@!4i>y7*ES(HE+T^U!x|*G?%21~{+d6?frIplhKai*0$)uw1Uv zadzdtO(f;JJGLZIVRHV*Jd@ow#J*X`e9M&EYC7$Uy3(&^2|{pv_S`^%VnpgA*Y+GA z`#qtRdqPC7WJACdActxXwjMwschEPA%FNMHW3ly#+CVqw>ZFK{;t-hUq^zz)jYjYu zoe~qRTbf{#NH>!*B4r7K5p6~aVb&TMPOW@*Ci5({0yEA;!vyn9&x!n-@#1Ly#3=-{ zEiG_H%f6)U=p4PW#3%dD@jWCohQc@`wN**!v0SVhJkc38tKH|<1kUz7w=dmTT+^hi zLjX!lkcgc@NmivUTo25HkC6s^&6@r&2!37gFDuO7ThhoupZjGUciY$)`P5{X$9pft zbAosldjZHg%vWp3XIm(-mGQCU{#N32S>SsaL&-=!M-X|BVIlXy29Q2la>eY|a5p2p92XSK=B)Gph* zZPDJxA!H8tAcgL)ksaJ|&W?vIYyL%0smxTVpyz@`aLGzB$NZ#EY1EvM^x+@oM1jh_ z0_#ovQWLHBZa6zcJW%#sxOo!v*C$9A5JPZXJ7a5W4y>JGfO;c>5Wz~i$SGa8)9(7K zV=Ib<(AT3;@=L(%*1x*(Li){#XJEk%z0LU+O?}1;lse>@BR`S7;SJpR zknJG{RI1^<{Cb|eMc)H{_O2N?+y!LMRnpjWrdeMw@q{rp+jf9`{kVwd+D#2U7IIbG z{RIGm3))M|{2*HUe2a@9F&oOQ#lk1Kat%b@4RbteR`&@I=i?b}O=;TC~n#b!onbv-*MznyMEgr$ok6cQjAd=!-Y*jE9u`1i$ z@Le4xssyO=jM*^LL5wQd~Us;AB|H*m3Q)XFp2jIaJ>B&{9?)mb_d)HR}Maw5M_ZKGX z$21wRjfzXBm6fk2Wy)e{aE5FG6D~ojXe^E>#}}Sn;@dwIw6Dpyy=#5gt0>elerS9z z{?Bx0--DlVnU-geoouwZg|`0~sKbhq=%Z!Iij8|gXT_MtKt_1Po;EQ?M$a8K6a94D zH;$T&YssH_TulScOw8=b`VYaJ|1$u0m43ilUt6bizSS{xIg@7rfX44-oA9twoS>Ps znY73)$lEw_8w$iI-EyHN%-VQ{yLXr*%}mU6%W2cT*)nv)wf;6UWF)O_y4GkJn@?#I zHIqc-OhD4|o4d7ZJ!6z<_u5SLa&tUb{~hqxa(3QdIJS@M@>b1AZwrY$^K2^{oLUzF1yRiM`&$Y0$ML31+sDCKEuTy z9Ww=}831>$o;_IkqK|)0Ewy9I?m!@Jf=QbndInBe3iTXqSlTfD^Hy1{d-|1C6qLY& z@{>4@fMRJ>kc;n9^30Ecy_**ru$A_9v8L1m^&9hpi_fL}^@~;MkEC4B|-lwk7N} z0PnOQSRvsU`py=}lMy>XDW7;sgL@*AM5#(?)?_l$#As$saxJS|C)X&rm@yf+j;U1g zj?YQPWb-Nn)EuRr3kc+wgsx3K%smTE)Z-Om7T_rmzYOiolCS)E}0x!|C?i$QT zeE@$g(SZWbr5!6KzOt^J%US@6lqCHIMzWv~u9tG-S{zM^=$ztP^nyw`!Nhqi)>FRRsU)tcO@>E|W8TMlj!W!d)_Y5%t z1;A2*b8Ep2=c63N%AEN8e1oB7bg3MvobjrB4B*B-vJ8Ed(&{2cs$0pNzBchRN`_Vc z`YAd$*0_=+BR0Ct7ZF6KKxNeTj0OY?(7vDN-bwUh@g0{{R#DN?P$@}7C0e-dOq}%# zRqT?BL_qI?kzj&ghucPR9DF91zM81I1Ci+nLUB~2pQ*=DRDw|@UUwV>fsp8kqB&4M zi`FSfbll|K_G)Hmm^p7J1ASv|#S#|-PeDIQ5>004s_N*@sxAT3{uYZRQHDB8D(fFV zS4EWaMEznv;cv4OAcUguPn{BTju2RvTG~nG-wgDjFON3)-TxrZ9!kvxq$TinJ>`vp z68bs;*n#|SrMe_S^7E3TGvThWS8qR0Z|R`BR2QVPjBd;dt@ziK*1fhmzo^cBzH6nY z`)aN_=9D?oXt+~opwKu|dVfi;1-brjC1a0E?P^UJ$oQ2=KpxerJCPTO)WFoUfj!w- z4keJMKo7v<7nOxC%O1)aZReh*%!3e5+I8)EtNX2MuCnh@X1^PYz-fMdkWi znE-$?Vr4RV`tfnzo&K&q`MNy5isP;u1SGhD@pzwR2;{tjUMP1A-R&&%Svxd6oATLC#Y29e z^dos$;KTuT*=F13w9SvqjMkI^+_$9s43P9Y3x5d;Q)2Za>9dk+C7x==Jx|B3;7{SM zyv(dTf(376_M~7;=VbIYVAg08*5(h-jP;kUTH1h1>>Y@smk_%F7qbEwmJclNz!%3I z9Got7{w8eyA9C@e9Eaf_VbzRU0Y&p~W`ysCu#2o*DjZp)P}WNeD22Zn3>D*0P0pgr zQ9XIek?9+kfcHZPIDz$!&plv5E0YVBY`H1byilm=xbYhQaUBjDAr{E5FTIj_%ds<; zL!}nrXE3);rorw9`@i8d5_I0fOAQyS_FbXHLlU`)TJ@LkPx$o90NurR*#@;7I2Sg| z^6lMdz_*3KolY;bayX8O*_GUJ4ysSxgQoh|F~8jxYr(z#IyCoJOj_zM%kG4zdDR3Yxh-m9%?i7I{ok##Nq$*Ub5*+yYfmL{F3N!^ds6G( zwC`+YKTGz{_O$(uaqnUrZ8qWh<Kf7PCXBRuir%-IPp@9cHogQ8`9cW3lLW4S$Xgr{ko9I? zQ{~9?E%Z6q>Jⅆ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�|?tX>C-mX%#{7763B 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

      JY^^-M~X0TN_kA_2u> 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%0AQ&xe>c+2iGI&|KJ&PKF0kc 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 z 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%0AC3qLMq5fhe-0{J=p@bGY z>s*8Wxxz6`W(Uk0RiowotX1U79twpEogq__uDgABk~P9Yma5GU1#)+=2fbXa?IL%l zC*#<4=diF&FS-~teuOP!gyZG<1@+>WdDd~7{Z{+UxoGyiLKb@M^^!>Ez_>CFi35JcjVNKu+yXrL-THnbOWq06XV0TK4%Ft5L6Sn`a*PnG31d)@ST)!CuF< zlPSOEvz#J^xEMd{?s>%pV~6|-3y0?6B|p~@kD%PRc^^+(%1X=;eP;|ti#Z3QYAm%@ zbV!XYV?*m{OvxER&a9NZ@dfW(j=CoVkVu`Em@Jc|nL^o;P+5d}DUsKfM)sK!(mGsx z?DkU$=X5qs^S%wK^RwQ?A3OJY3|#N4K6bh8c1u+}cvSLymM&&`Wf=Y9clj0g30AWN zx)76QjE~vnq=%#uZ?zDx(c}qRC|^19^anA0*&=-(ZII|k1!KF)6@Pu*e<}GMhfb|T zIEkdR^&IVC&+=H0g*22FXLsn;vicLZg#)R!@5);vBUZS=gIoPMHTmGCd zf4N5ZNmcQ?qLc;FfF#jYILwkHBuVLOS4EOVHO@Y-MB64eG4u&-8_cM)jBL4EGTJD5 z)xbK<9k1iUNRjLjjx#Fkutkso4H}xQ(`<#T0FB&?PoIF3c>^_s7zL_1zb6SNYBzCd zbVBpn?ZA45zh4&v<}CwX2aT$+mbDVKP0*Bu_+P*bV$C{Vat1D=Cf^DwrU||lNwf@e ztH=Gz^>>0?YTw^}tKc=t73M*{64syxr)>Wm>BXc`&FMeUi9j3r|4t1R#70kO2&H@r zjtmY+S--ho0!FVmbEwmJ9I~0DSPxz#1f|vR*v))Th-@C_$mV!E6hCJ7Q-v}@d8-ak3(8H6OU%=ccJZ-53o3VYN7CohlFXj-)K`(!+r6_8!S0^X>Wqj-G7Do*Vkr^2bF|G zJJO#e6d#F1SHwl-*cZW8mT2UayxEEaZCE>F-aCfno(N;ir67AAYO;_DuI1fY^Ufqi zl<3L?_ev|0=hbAKUS+ubZE;JV!$WFFl}E|1#hf2?=9HCO6mI^}Nl^VeGL~G0nrxjY zg8XT5eNOpY%8auyaq}r1)cypLfG0v}ioVdM_@ygAfEV!^)UWyx%(dbzc zPGmVPa&jL3bpnT}c?TiO*guAG_x*;cS*LBzxDz$Wau?3O4r8-M8|(v_Ed|+wzB(h( z)YhhubT&1km}?z1f=9Zm7D^;L!Dq@9RO(j0Xk*3G1Lm4ipCSyxS$RMK_aq`3!d zvHh&ejp1RYZ4PxN@Tr%X6~DIyCoT%wa*3#Nbpz8!!uPOJ-IJ~ASMB}dtARS2fm5$L zQKxH9_h$E_H%vHd#gW`JdN*R039GNIJ71V$b+`oG(2}jPzzkV8vhPb*w$c#k*yycg0oK3N8Oq`Db;v! z`K-`l`H(!=5X8*1cMdtyEx4S7yDx{b_-o0EJBw! z!tgt=frNei;)vw1Qfq&B>Ezb-N18aHDOS2EtsPZzb6OB|piHqfXhzKG^nF# zQp%c)pdrpR?dcjF^a4{R&;aCV>U6>-NP=%j(QQ3S`Z|qmBTR)oOzlM(?DBN=B*UV$ zmH;Y>YMPKODMlh36*xM2l70#h_FbhlEeIZ*?IOqg;Iy z{tP6sfQaNctNt_;;Ce~4eVM}e0wCe0knT^T*V1q-+uM~yXV#JMR>vY zBH~ERL;d9c-B|RW``3?EfA2-^OdEsb$r{{y4|_0do802Sv2~BF3p?EmUJ%M}2t#4Z zlxia-qPu$wsK$bmsBKe3P`aQ>GZov}HgCp*l%S~W(}++}f@YrpKY$8~4%#|Ux1!(y zbM8C<7>S?_2`x=gN8A);?*_zgu?qMG36)%?E0!qGG@kr`QtLaQ1>$=B&pWL@CQ> zhYF`KFzrN7LqMuUxhd7{s#?=_pV~#ne$%|AKJJx2pD=PPSJ9cRw0cDCeD}5WV!0f| zj@DnB2+tUe?7w1UZ*|C*H7D&79CPyq+zNX!2#&9)ljg!R&;a)EBO8Je?iK=@=mehe zUvUXAYO(ET_9vGvV+<}^5@5`^`GYPV-1E~0zaGnEfjO<1HBb5Rn5sB2ff?^SH}y%n-#54{CP{$vj$0WfsYXa;7J^cH`!V(=aI+CBpkc8CsHr5|HN)RNFrCTm`THxuDV5GAto6|jk% zl_TIB;g%>?C9O(D-re?56gSEBZSKNc!N|n7277^LOtVgOm7D}NvXztI9PyS5%)pzk@QQlK9;jBOeYmSOXg_VH6_BSmPq`5c`2p$J^*ajKP*FpQFwqtH06fiN@AmL#|o!+n3j%qpeC21#_O z33cZvt2Kzvh@X_x>yJWVqZ`$M zxClhhJ}!@`N+b58^AZQOgn{ApIY&YeORRQ+U1v1}yM*v@fjoQ`412d0`5j}&!C^I( zEW3J&4$_W=cCw^(vXwF#!1(1Q894d?SW;3^)6}$Ctf`WysHW|*X^+a(P*Bl_DjlL; zCfq2GDLNW!S2j(|hy`58hEc3CzW&ED-?B5bO%=c%Y!gTD({nJk3J$I9-t-=ihWQ|5 z8}qr39|jWP$3||B^uPax(^N0shTj#AE`@@^dE9WxgfX?nSz(18)s8%}5SkfzAWFFMf0Z;fy{j zGx0JHxE6S0Cya=hHbQmT^jH^9ti`Y{za;APk04?ZY0D1wGvj28Hci?Mj%fDpyRS!Z z_Pk}s`*+>ecyb(P`uE=4VSMiUiWyp||C$v3H2?8OY3(Avx4!fu|BKQD>-3-H-*MnS zbDa3Q?WoV!XJ$=LpP4i)>Eg`0?(*t2oXbM&kN1!yE3yPm0`d;7A9ucw*?d6ayDy!9 zeMd_0f#+ksVh1-%@(@1XLo@ss2eKJi5IQ|H&+Z_2zMg0P@Uiy;FXk{0y-HvGAGek- zev`%l^co4AatGlG`8m|&uu!Uh{>kJea=z$-cbhNJsh)8|n>jK!Lmdh(x`q;F2N}qsu zN@cW4Q~wu4^ny&Joh32^k$Zj_0fC)qRM&c>rHmKX&*p+Z1fc6z?L6LluWTMaw)cST zMRH|7XL0f>KHsQ#hZL)1g-`k9w#hoWIJbVJ4cS(99KLfw4N{ZS7)A2M}E z-He{xy-`v20^L%e9!hG9{G&V??gV= zsreBOX&hop(1Hr06b^C@+?y`1S&L*{pB@ok7Vi&{e=d$i17o+A(2OCU;S`li5NO^SW@|y&|$J_9(^Rd^EC21a;v;sitXF;$L_SvDd+)vkwhLQOsvl`JfgCNzwI7Ua(k_- z;k8=g()k}_TY!=u(ucB!40jC+WO|)m0#>rU3-g}Z9@bVF`qox0`r1`-Ps6sAiZ82K zSP^RkJ&7_Bu;|c4B$Js~fk~1ELA;>aOuVP-9jv(|$6{A&P`0b%HHAjlWi&rx2)DzF zMaWxr8m_*~A%1dsA2hTdvW4;tViEq1z*AziA85Y#jsH#>7O3idK0;M|Zs}m9+yJD- z(2<8nbr_OL(?v>b(7o)99O<1GtL_N>iD+nC#Y}87we0ZhV0`^4k@mJ@7n{Qxh?uZP zRmi|e9(BW}M3zt+a2^fSHrKMV)yISs@e6$F_`g7oQ z^3Xz_c}zd8LzGyPe&#IAVw?9c#%s@^IJ!*;G-P`mM4Z8%qQqm0qQd2#aGX&Iu24=W zgwoeL6R(zw8K2_BEYGTC64xVI$|SjMzHL5R7@IUb(Y9B^p(8|w=Cm>utITa3}KJEN7^;jxZrTe_kzPxS|D~A zYvv13k;6kz4ubV^v0}+_VclV2%oew*!ZTe#!Y^c5AMFwL;|!XRD$>`-6Td>$2=u>+ z6DNVl-^+h+W#|luOTQq?$*yiT_Y?s2e;z5#!$=futxMgvPY#0`BsRFaZF=NtD&B3m zr+ALXnW?VOvn{8^S3Zcx1HF<{QQ4MzZd)&@|NBms386}Ps<;m{YI2bJ)dxdcxU@vI z)%HJ3Su3w3aNE^E8LIT~sM}QdGW5QnDdH!U=64V;%4#_rI_Ve`^DF-;`3qvz0VAfo z>?`K*Pp4udePe`Oqx!!GAu9G5D)nuA+IspT0Wb^HeDi=`3zTv0Z_)e(a?KPir^_JF zKOdpc{)IN5d1%xd5ZcaW?(13MIbnu_HK;I#Ltzet-P~{Hb2olI;0N966LAr|7b7{F zh=3nxgd-vK;n3?SkaAoG=5Fb}!wAr|cH<&(`g^w=wXnM@Q0=Nweg%RB!e-;7wG!_Id8jkJM1%&DZ~PojmPQEAf8$E3gQ_rwY30sZkqI{Y)Oe`PIeqF zGY%7rOdo0{FT)$n26t*;F(rWBpS`bf^(f)DdS2wTy|4skj{o6FDgHk2sq$_S^3PZB zp6A}fDt0HPu=M-`)Ah=mG;i>V%e@v=^LB_ch#7h}KYY8Q(04}l0otrC(ezJay;nll z&F+uCZqf2jak>^hLB}uA@k+&?kTns=FoXE{^4SURBp5DbkGgh*0R8|YomX%iV2;qh zelF0g{iCZgzUb^h?7;VOJH?6 z&uQjAydWCV+PVdDQ;|l;J}C8YTBQ}e!?=gDnMU7WQ2kGnlMu31z3N2h(uKXYV{ zW#O6Ub6=x@_mk2UgmcBD>ne$9Drsx9e?Q(&OIB;oel*K->64Kim)=uM)t^k(oPZCk z|B&}SLzWvf7;ap!u&?k7AM+p{>ub!fFoI_y(?O>K9Lcc9r9xS7_A5$++U+fL+R;uO z33@8$HA9*L(JV&t)bJLV>xU)-El|tViM0sWY48#T%P58-9ct7UroYPRSQ^#vHPWzE ztKg88T;+P|=~!yj@W^$s2rr0G3MRFDN)oY7SH)LK#n!Kjyo5UpJ)Nf^B^gUPXz)uh z_8har38-dFpE1EnCi?}VBnZo+U=O=IE>9^85T?l0@G94G!v^yHJ@D>fswe05JO~ouby|X+pG}|Rfpn41)L!F5te%oTXHooGmb~$pxP_;WyvQzl&LfV~}@YEmFQ$iqo z6&+JCSorEQhoo7mGR)pJDZ%OzRjE(t)8Hn~xe&bM^N^u-!CI6kZAlCcXY>e9t?4yU zT_&m;cqq*uQ#4HjAAwWrFwu3w8~D}>yeRGjZvhW1vbhE;wh+Nk@vIgAZa|U0p4LH( zR=x%~)#Lu<_%1(yxY(qxy|WxSA3Q{_3s?9^vau_+MaWgI3+B6IwDim64UurOmj&{N z@gI*|ALQi4vdf$!E^$o3>E;hlGJ1KF(}+DdgWwTIz#^Vt9P#ft`ykS$D)ACKCi-1AJ-^ac-NmD+#Mjt{o{7Hj zjsz|na&#x$D9j;WUnAoE!awVWAoSQ=xnXx-H*TH$Z+|HOqZrrF4kSf1YEBn!<$yuQ z70V0S`MwHlnPP>apj@fK!cGDv_)b_~*Uh?7mE(e=(VqR$8WAOv4!xMr3tT$EIldy@ z#v)vQN!v*6?2CoQ!te2Hi<}JBO`2@cW8=PnZo+=8(`@TJcAe9_v{LYh^RwK)UUn?; z+5Suu#e0C`W7o*`Shx>JFdl_5MA^f;Wr`zwp43Nc-r^*7Sd~Pc)a; zdsykNY?bTwh{*KS^LHh}ZO+nQOfJ~B%-zZb#P{gx@?iIvTsYWVB@0>lj>;)K9+7Vy zj)<5;@N^_&+MA9(VETgkL50&`eiyO~E?X@td_(u;{Dz)rZItP^vWHBDH>X+i_riXd zg{<+FzRV|m{AVw%$<=y_K0erq@GG{+>l5DB&F&CpHkI-=2f5riVCd@;w0FIyOG(?; z&FzR6vN$f;%K%^dcPuzaaV8%FZA&IzaBZuW0MxukEI767?1OeGmj{a95S8e)3pruf z_ni>Mj%xR*^*RmYO9^Lw=e;hjU)Dm_5jq2@QM#ghZnU=GKV*al5Q2H)O8M(|5{1~ z^U2rs)2>O&KGI7sLT&1O_CtDM%rhz&;ui!MR zy8@*F&PDfS9lu1Dy$D4eF!J*>`zls{u`*5a0qFD%NT}o?TrG zT^+Vtu9(%`&yKIKWTzD8L8ex!M~pC`5R?%MUH}7$-HbLi`vxR zb8w0)mY3es1)~o3{R@`J`w&`jhFs0xdwca=WjIne3ULnsYq-6w{;~Cap(P!j4Qm90 z3@$Bj(1Qx`9}+qyRnut`Ft%vygdFu22-oVK0zV|pdVmOXWMotmcC=7-{9Cl(I5}1X zWs(|DgLbH*T4`2IP}vmUbqUP8$d(RB_$2K3X_r;_dL2a!Ur7u51D@~)mL^eT{6cmT z>{qQj(#L^}b|fs`Jq-(2H2w2oT%Qfz6#||BtK1nftbH65wT{3ahC*R6_49mJczSm| z;qG{^IEub+gg{eR*_NQ-oF+u&P`i}IyOBPQv_j5&wvwB1vL6LFA9RG4@I(ScQU!9z!w^Cb2Y2x2n#OLh{ z@X*HBa>J6TR$&m-vC6C76t<@;T~EMTK|6|QM^VE!EFROK> zHFi}U2hhY*Sz6SomxcxwDr^fCHUPhGc{qU3@7UOmM4pucwWK=S>6?9e3vZUAR)H`p=a+oXTd?Az~!F^^zG2MfGWIGg4{qb z5aljjX&w!D89s+HW)gI7^y=myJN`QOE$Y`4=u~xvwTJ6(u>EFh+>Heq&)%%zwfg8R z_M3@~=D5vDVjVy&bx1JyBTG(ic)|obJ1#Q|FK?8B%blqM01nryPn-Vd*Tv@kUV%<; z@IJbH-k%cpSx07^QZVC0g_dFVibsVU6tOl@2-aI<)WCoj=uDR~&Fmj8A#oP33evB_N{7oK2~Ud*eB(B|sNA5C-V;21LB76P!kRhB78 z=w2krtX?ywI4@S<>|sRDlKWl9YYXcqi(3-OY=M(8>YtV7F zMEeIDWL3SsSF!pKgZ7SUo*m>m5M=I|RJL!ZJ36=DS;oTz(7pBQj8Gxums7`68qh^kq~&vg(Q@u z5MK+h#49JvtToa+;#ouMwOe88f4!nK@f$T#fq4kea{P|xl3JsjL20|FrzVxsE^IMN zq2x;UGk7Huy5R%y;Vhtb1E_tho+WINltVhC^R%LYL&!gPl%~&tUaks+t8_>D5Z#2`^6Nk zAqU+*xq~~R=t$0>-r!=Vdk-$7-|&Zf4dhvU^88q`^M2_?m&~UYUzSE3oA0sQG;M!C z*Qv!__ZRbGuBiB$^&ag_-jsM5EJ9L}Zt2#;b>$Q=v$u22^H+luvqv}eunUjvQJ<11 zo6WLAMkmCKhHGkglg70?Ntfk$ZC!tfCyTG^`0DHM(ESM3x_@&KNX-gtpDFnqJEwam zo?r3CCmM3i9`tZfdC5Hu=v_Y0!|3>;VdPKx2oO*I(>01u@Z?YFlglb3kt%xS}Ycc1x0|6B+S8NiGd^u1cFM)vJ41VW-KWP;^84O zbu=TUTy~H6lTh0<{Gw#hC^+jlCR-;@AcY3E%JEzx&+Df?Bt3?YDRC zb9ub`dCzm)=e_RX+Q}qsuXZ0GUFUy~AX=bqzmh5kO*2!uspKLNIru7)T|`2o9sj|_ ztc6B4D?LBZgWH%&iYd*}T*)GS3A?`hqcJClr@CrIA`UIm|_FPYqNL zmhW$UALXBsHWwyWhA+0`&aC669&x+#+3kK7@J>P4n zFwNa=%=*$CtiW-kCGlGj95}MV4-BZiK!d8-(=qTKBl*aV9+?;e#us>?X_LYv& z-sG>5j=A++GE@<{ZljKH;#iwmi7H!8VJicx{IQ38%PZg&@PSReYYOipJ&2t+%;i8I z*K#fgtM^csca^$~1{VT0V%cJcVgc-x)_NyHwgstM>QdCCr11vahNIC0rB3Y{dNtIL z7v+OXnZ|-@DoLmm!yC$E6;!fi_6+!=g&;NDEd`3T`Ns1cbzHPyU+Zs-qP_X+y)#C8 zL!dBjXBsnGSE>E;ct?n~&^q2;uxRsm&Xs2CiwZS#Yphx5m!m|$#HqoQMuQgGO)a|V zc8wwepfsnG=Mawz<}2{&Rq3#fuGIxEuCsqwAdQ_8qpW>_W8c8SCYW$OP~YPxN`W}! z-ILy&0?+&|uqhwj)CFHMey&WL_R$$zaPuaGA;_cYiYYNBrSo**qiJx+IO=`DGVM-y zdR!Zrg{`6$P@rNkVIaQIQxLdGzIGXKnvB_(2u8Qj7cJyZmhmHmxzNt&4xW0% zB5I#=F28+f2Yn7*6nqSrdwq6Tg$X}@OD0W16Dgmso0C-xp0a{tVsl8Q@dYxQL7%3i z1_1)R=bWWaF8o~3%cLIuB4ITu3e(%jA?;(Y^(jnmXsTXfr&6a^rKfw6dGkhB$GrKe z>^cY3SUX&%>~XJE*$u%zf;!bNTy?JJ*W)Uu_swyYfg=oRz06{&%v)(`DJkBwsk9hl z;JN)%ZZfv~T*+Es!(DV`|Gy6}@gn8r)Vu1AUSB#{e?+!lER4Q(E?@I4m+zXEUv->` zm%g*lqTkO(AalD?MaMY1Gy4%+;VW)kKcP)amJJQZI|`7@=lNyY0h(Q)8McdbpV&Wc zkb6w1=OTWYCWq2KnwTFE^o(+>8U}sbropC^`Nm?|2o47j4kCGZdV{;wv1>!kV$vdV1Oz5y|UZJKUPsImr8Q>?A{18#8~|N?ut%6nsCCN3z4X zAc1O5gToJPf;g+g(Kx&|1737&MbC%5dgY@#z|MXi^-UnSsi&Y9Xis+~#+}FRDH%1< z`UjrA6MX}wYM&)QVmO5SLgt@5n{6hsUe}SV&5wv##G#!|AvXvpHq&s#S9RG!8gg!( zHxh*Y@hpL9rJ4EO9G>(P@!94hREs5ao4(u!*(5vfU8m$L9c>*1IJ=IW!p(PmXOluZ z{>&^SMTSfRe1n_!$@@L(o9rVYGQ_0*C%I~RLR*RZABMj;)YuJjr>T-P^_M?SMRZILrs+^YSQa6902@c%S9XCY}Z{_IMW&UNksa3+5?2^d~kUwbblFB>6fe}Y^ z4!AHe3#X#$OtO*Ry$JU9O`*dqIENyh%?8QOG-CRNqXnUj57RScMX@n#w^Mu?9uzT) z%Jz&^b)b2#o>s%Gd9TweVK$k&>5^eehubvuv&rl9()d;V5KJ{b>bOeG!Ps-7A7s1S zTp-h#0FZ1=sov6MjPE4RR3o#|r*p}uHs6<(UxBjdZa1c;E?I7};rtN#%hOYh&zD(b zPppgNV_XDcY2EclPUcR`{>A6MROEE;KX^L&EDQXcI7Q+>JjZEhZ!XHlxsbxTbIm}} z2oYHq_`v$X9sCMjWFg3a3hyIa%@BuVZ${+1k*^-l^9>?G9>}kfz(~1Qdz_iB#y1Zd z_@qh_)b3Y-;v^+wRoSv>X=Ykg-zGK8d%jF_sVhcJ6pb7vddLEVXx8?HqZI9OsPScb zeAvx-rqMVVz*487MnF6R>e21xX^uL`vETTmM2XBM@oK8Fhy79YqCESRc}lH@ZK+5m zHa2mqd)H}}5-rv!vKg&o*#Kd}D)hpw?1CfxG!OU&q7r~0Zc8FcB`V@$QRvp$6}`S* zy!Ew``p@7V@FrHQjE9>?r(vvzn3atQKMR+jJsBAR9I!pGsr{C;nzxxMGDvE_x$`QoBk>c7)_C)%-U5rQo`hJw zRQDwX-HNVdWWOQ13GQj7;|7`;$Ph@3OoEMgxDO0@4pP92T*z%srSnOt4?#S0!=1~02b{=I;-fpizW&13d`Q+D} zbK{JLwdeqSSmkEeEgT**Nyt|}(9N-1*2}(*-sjK|aT;y~I3j6aVj98|`t)_bA5UC)}eO!4>G5-gi zs%5-Wyv`S}nV*N7B+P+|Oz1cYOTj+gf<~zX;}1t&#Njtx=O_z)mV(9Nq73u1?vVvI zKZS=iV0k+Bxhy+fx}Ja0WkQL?6z_k5gu8`!xJX7+OE<+aK0RX-?8Re?7qALw}BZq zE70rZkHMEiuV#J>C>9!8;YZ>H1(ETBOM>6FJii3y^za-YxlVux z`N-`f9tXe*42F9Y@j0ZS?d}6Y9$$9vAxKGVr9d94w6V05olE=&{n-DJ$WEo6AN{cZ z+7JJHe}!H{b}W!T9g&a2X=N&7^k^8T&JBJ;^j!+>EylhS~W%o4JOh;5Gk{4|&vY(@3q*{B$iB8bW1+3(KIuqZ@sBb-y}E+9fl zV1$X;5;3^c#tJVyJ$)o!Xe;=>{9?$L(?W=ed-%gdz85<>m&!l!-0(y`c^+@a-yDDD zUb|&?-Ofw^{vzC|2VEq z*s1b%#Z%`!YwD)gZuPGH^%tS%#;wYOd)c3V#zXDALYCdP)si1(|A%e$WSAwAcVG9C z6HcM-Sctnpnd13LMMbHu+yC@h$addKEkOHl`hb+-^Ifr`S?z3TTj;jjzO}>dOrfHy zFdZJ7L?O2ReIudcD-n=J*m7(sHV{n`RR#SYv2}QGU`4IU`q~NjO7)7ob_PV@ZR&$>#`x zJV$uLH5ls_Zb9S-Dd1RhAS?bN&>WlydVFiBvY73JN-#5@?JQ>#Bg>XCOph{H&dnqZ zIP-Za5?0%+@_G6c-k9G!FOUV;wCQ|A`6oI}!3_j+lSAWhe^ksFF7Nc0p3J!ZJB2g5 zlJ5Ny_g>Iv5vYmRwu+nnn9S9*V_}LZ!=8^6)U-H|1kN91f5-`+Gf+D!AzVATGsVA3 zcPa3c-ceyIWw~(0^ zD+U5-*xxcRsx1fm&E%{%t+=#yPj$>jTiP7%Kx+8+e>7vL?=mvn81oLaqzBlbl)vEs zzRUvZ^L$X9{*Q%d1|uQBF(xUsF_B;x57~okdUyqo!Ygu}$J~aansu$5;9bFoSN#e&!KI-T zKPtF{aN|qYj*5pHzQqx{{vVh5#_!wV+U?ZN{{Ccc=06$=P?)x&srEj(57U;Xdo1$_ zS2-ub1k&mMN8ugz9GMIoaFcq3?%)v?9swY|+%fmPzpjDzpmbzD_ZRGt`^ytk|LDo} zf=`K=wiX8&J4EK?W3E%6X~6k~uh>dEcJ^*nIk{-zbD)&Nq?U}=vN+ID8ao(~qxZ^v zQKR_rbb9XY_dXMiAhdY?J>(%7S~Tv#gm+-efdEv)jXspPO!7Rp#}W`pghrux&`zbu zAN>dFs$veNSC;IZ_w2{?xb_WZ4o zl;?`sKffqHV8e}Ldm5Mjc^V&U{SmLhhZ_HD^v1q54C@83XmPLzgRhp2nk}7?!&wF- zY!_u55+i2i#=(3L({=Ggje;~$Ee%u@M!|m=x-NS+@ey-`h}d&KVs$DJ{^WoAYkBp5 zW_2nt|F-)-(l#FA0F8%d7>Pe{nF zUD?$6f-wX}1p13^v|o^6#re`<(5$!DEk?|PoUy#H)@oAJ#+A1EI9q>r zPCh@&4&@5-Ve0J#iGf(ZL0Gq)Iaco;(OrAGt>xyc)#3ZaimK}cS5TF8fUBrJc@LZ! zt8h!tYCQ-+=C{|huy&KKtw&S*JUl3eX!^YgJIVTxzQH@ok1S5|M`Byr#fr!IMV{jh zEcy)?s|2J$Q@NEKNL;t<6zcozC2lOC6o%>96Z>B{%58Mk!)&_fOr&l@K*qJB7ucQ@>jj4LZ1nX*aU(^^+EQkSeyu^1~23v|`PthE@KC%t)G} z?);n_3JC>?dOq+-hNN0t;lRPC#;#gkVFjhzsk#PRDfju#G7Lz)$PnAYHKMB93ad#r zmUgUAT5qngiDruMXbBZ?9?!u8{Tvbh;V%sqH@gn4^%e%!zj!ysji|=j-~mxC8sOsJ z2Wje3eMJXrwzn0XNmfsd&9&hBfgO1NBE6pu2Bd9PgSbh+gg zvlhi1*+Xpk1z~=Y9zWe3HTp+y+o?_%Fo_@0W0PLT>K%;5HJVz+f}!+);P$Ljn!y5Z z0i^(L>O7KPUS!)$6CXt%?2Qz7{_5;<%K@zuyLbEJ0z0s8*E->+Z`d3?2!(91H2uV3 zLldzCaQx>T=N+`G87m)*p6C+7iAwRI=?JdVk2r!#xCT+5hlh(>!zx|_2d=3Rvg6oj z#(iVX9~sgPKJxm-RUGY%9$q(CR~0v&=r1p2LLg=o{OHNqCo~}3QoA|}xy27K*m|+% zoxPsR{Nqkpd`-s7^N$$l7=(B%V743t8N}?X<4+Okf=?GAWB*?%UByZfE6VqWoXR}x zN150x*YNO1f;e?rO=7rs<2zj2%i!YV-uu+xy11_i``((3lrt zeYDiZDWp1Q_k;UYeZ%<)r%A{|9OQDQiHdi6mJ|wDb)gYqYGf!Bay&;Z^zU{NFw|gN zK1nu&5>I!LzWYdX#*~WE0zzQpmvta+}^(0=g#xpTd+robcvo zS}=8qnFc1&_Przq8d^IHqH-6G%Ia4C3|rhMZ>5*rr_IK9C(S(HL)?*R5IQHcu{6{7 zP*l|&uH|c7;?}cj%z~6SOTRFt(s!ID$r;-EMb)C6J!2AxqK-}8yg)^Z9r^7{@)eG@ z1}!4RM^h5k;!y}1YE1CRfb@bY$6OW#qQP4~KQw4P$B&ksTGEMZVGM)V64%ELqx%Wzn4;2(;?qU9lN zW~trRWfF6UqEiHLogk`rw_;$p3NI^^iX|9|4#Q4{AE#UHUSVrlRIH~)o08{?y~QKeIUb=(jXLGe2z%DBN3?R@ z%#7UmWE-F4aSYt^Q9I~i2Hu&6kJ`!y3*Kg$Z3KD&$SP?4&QhU5pU<;XsQK^}j(Az4 z*$d577xU~?Xeg7}o^ii>&MgoWqE@7Jd7D9-C-FMwig+Y5`^(1%YyPRlRYgpJRLyG^ zhKw{X&qAahU|Rm{2Q7gF;-h_h=9W$b-8cn7z9Ko7ulnfictlaHw{ z1PB-AmkL<%+^`J2#fV|pG&+Xqygha4lfCZj7uxPbY|05|BE+6S<0V2|_7MdE?N3|QQv^djopH`j4 zp}_-Yb91L^Pyjtd0%ng7Q1wGahp2huyfe!Qw7)Ow!d?<{=AX~&fRX4j&i-6B>40I+ zKbh9C*klgtIok2boNSNNs2+n;%v(c+y$FK?5^gf90-}}YA@*_9nkr^{SMCa4Ov~I%AZG+%{CXtGh4^RGFBJtc4C6uWimk$b8IK`i7p{`Ed-oaFd8_VN)d~Sfd zN+Go}Sky-5BA&7+3B2-WqImqVYM;TE}}6`(aSsN182~7<5V+SD;>mierq7(n)R0ZkDSw z!~5Zy3A`;H5{^9INfIIQIkd99gB>Dk2ru6J>Zbae0+_&^S{ z5x{fb9Ju^j&`I|E8RmiFt<+)?nG$g8#GD{p=~n{%DtrS65-zM7A*p^G#_T{5vnFlF zP_&ep-Rv6_chct3#j7PzSt=_!7tA|U_GE(3r1xNYW^eh?)^)h!^3t;&eYAjTLl_JM zr50r&%gyAsVa#D#%nq-)5gCcEacg_vq6fQk0St3ulYAku6doN>cwLt|W9H6U`;|Kr zi+Rjs_~dViKTeh=MjT%W>B+8!^t|eR&Eh3xmCki8p^&L{t1gziu!$a!` z7^Ay0AK{wnPK{RK_RIJy=2BeM@K`z`*@{ot{4!nF09Umg!a7^QK9-f;hjZda9~|~= zgbryGsn2fVJ;jfl7qhH6dMC6#3de+J92F*BhGOTp?*eg{nK;BuWBFEuvr=iEwkDTH z>JP$B10$~l6<+o1_LsA4-}DdiC1fI^C9h+joy4l(W4@c{ubXFgBTh7B?_S4f+I~vJ zEO6Yil(7lnB39v#4zeKdkiJSd(!kgHD}o?-%NylZ^BB2LPr_XtMl z1I${$Qcx{meb+O6qaxFFylVy>nTzck0cPEcGv>^bXEU=VAJ|8|(aOM( zm(jEzX}DoBaR?PGu~Nzpy&A-3+o^Hu;gOn`O}nYdegASxdXR3PGCJ{^7b=u|1s@uH z>2me#=Ix2c&QbM0c5tjBRw#($B3`*OMuZL?LTsewI;{8gb71ZY=9Iil@V%fkA!rcA}JuAjHQBEbbHIC zU`fOG?Qt7&-$Z7~%J7Z;NcTkuq_uR%xVXR=PY$R{BkZ@^LRB4_Jt zJ2(-OW=iikIh(L7%EsEi;ei^iFzI=;@d|Z|Qs0YrMkZRKV*9>5ZY(dB)twGA30aDx5dn&F6F7%auX*{Ot=q>vtA&+F<%xN>qb=)T#IRj(Kg5MJ0%f6TGq-Tl#HlfmV0KSAaaUH!00 z+dk&K2X%HYtZ#)ghtIf$ocHP<5a6gmrzUkq@m@vTG2twDpH(AV81k0Y!kR4S81Mf# z#Ec(>@+znoXfN&!rh_uyuWwWdc&J*1@*03JQSSyQ8euxOTEdLkmjuBnXfoA z^$SjM5FhTkA01vfUe%JDeg0;H1>7XXx;K{s z-v$BoUQckk;vht_Hq@IX4AzaA#0~6k`AU)1g#)_-e*JN@i?xQ*uw~%6?aJn{lA~rD zY}_XC1=Bo1cW(^4yV(clH8R{mdfA^Z-q7OeacJ_q?@64yv&}N8n<>N>`9STkK+XXY z`+PnX?PS&MS)s(Mv%TgYK)y`%j?KygAKrw)P2qGz%fg~{mrdrd{YuQ}p@HvxV3tmK z(hUr}Y&Hd`{>9!$ZJjr^cDkqDY0s3|jB^H#6Ku*{&#OFAIUYrb%bD+|l1C%TxfHUF z6YH2ulsNp^Ls&L`SzR3REiX?6MXBlF)S6Y^hO@KFt5f+9?CpaQ0Th7$#5>%Y9!YFS z(2{LB9<#^!3F|i3jct(2$TxW(Cp?Hf?7sR)Np4%dH<1tqBf7cN+V3w{cO~aX_{Ian z^si}dwvYo0_lE8Zqjv|Zde-TF&R7U7`{uXGdppns7e}|x7-q$ySAMJ;%~t=1y;H{c z1NNjBe$)~U<9el`Qeq-Gr5~cU{ww>$Ja=jNr43+^JIL`wQj5okrccEvb4#)c3dxSYNx5_ z9sTv2gkk-nF!Eo?rwO=bQMkC1dL*6^FH&hsJ6^6(>g9f#x*zR#q5gMz0uJNCA+%0) zF0<5FYOC$=8zZGc)OrKV`fo;4V;J#SAwDtAD1woQ?d`JW-Glu5eyL39+=;kT*0Gtm z?f-Humg;Q2-yK+UEv^weV2H5IJLLX6B1g}g%>ffx5PR1aUomHw7Ddw0mli}H^kT-G z(~HkA(~*m*O12=G;0kvnElR-2M!$w>w>~VTJ9!IU${IkQlAhPsrCcuMhmv?^f=_CLInfE}wO{0MlpimsSUUO1JYA7Wz>653y)w&Au$3|fsTd|gCHa8luTCF5&yrxGf`dN;IWy>x z&7d2$4JK@eX2&x>*8qZ811vlOap~WP8WX++bLIlyZl-U9ZqY(VIF{rtaNo8$I^j;g z2!k169X88=qlD*Jr_ByVS_k2fRq59o9Gg`=d>d7X`LGZ$7t}gDRR1jRd+K2-yIttN zkaCYT^UBG8cjzT{*Xf6knq9DA)MQiHmmp}rn02PpwnzuH0Z+-9<)R(5^|Q&%>80)~ z^)o}-Rd&`ahD&;vW2U6eX``l7HDJLc2HBaJ*3Vcp7(*um;!VK^-k+?Ww4`QJ2)CFM zpFT)W0!R^>$?aQ4ZIuxsy4oxq0y*sj!GJmF>C@}j^g4EZ4xU>^raIWTD4|9b{&*8r zB9iy4b;+2vqN(hs=TfIvEl&1ZQyTh<2WvTO29B#}a(K9XMGI?J=?V_Ks0XI=)9X^C zQNn+UAQJ@($Z~wcynnX$JAUDTWpTo!4}>A*DzELj@!T5lmhgMb4z1>sx7ouaptiU#Lxy4sRW zQYr7yl(5=bN=kRE>UBevA2qt%V+rND`0g^c{8}JwoCpOgkY;&7k7^@M@dnZEhu&m; z*^jxPNjAiN-;cLr?u=&@xbO;raZ^nG4?wwy8i+nU#lNN|3Z_je%!{XI7+ep zt2v=AIEb1an)$`P--~hv?|}&PTh5HG(VE#UyOC6-5PB4keZEZ<9 zf^xCR`QiPSl2g?klajB|Rd#hH;X_%hOFdZS&1R@k)OIduwSApkK&P9kt?Wy}i&-s0 zTU3f!%Ff$Y6VzDiYc;yk%Ic}RI?Y`*T(Z;@4rz`o@lUF()zib%b9HqGQJ<`>s{6H? zw=~shC8MaVb5+=vh#r!&wx+G8mR}A_Jx$p5kv)H|U)NS@>I}TPs&sw17mA8?{^hz{ zwp%7t`Z{X2MPPAJTiDcU+@(ED_Ua24Ke=zQEtA9ZUe`TQ+0+e$mQGrRu(gCcTHf?) zT55W&UaYb*`a|*^erx^8xSdP>KNWo8B)CDREoPE-KlUU3 z%zxL9{pNaUE8+huH#C+qg%4EFYaG>9YW23Y+{|w=NjjBYhIK5R8Y%t}_u&a^bM?*A z@j8t1RsVsyS#QGJ@xK$)Zx0*rg&tRA*(N{Y-7Y7Yol1|&ZkK#N{C_RFTp1?GdBXQ8 z=88PVc`g6O-6%dobf&wO$!Uep$+B#gT0OE}g?nV7en#nFYnvrp!Ln83{{PHwmQ$t` zV*|hzJpMJZSKpbsUyt&)N!~fKRAUqTV!uE4TO`9?J>51*LFWr<-7FtHx=frlO4{MN zQrqU~Ke}#~*n9aS{)}t3ItIyQ24_9&H%eFgnx^B**Y$b(lWnW8zD5Da^x2VInRYmSlMJx^GYs(kI%zTK9F&WSZCyoN-DO>6ZhEr1Q0UnbfiFcW zD3~RQ(bZIT(-VWbd31ebWwi_or=U0`E zEs=?%rmm{imd49r=`No!hw0R2Ptr<{tkw24wHl$7oi=FcaR}bsEYasIDD_oZxyAgc ztF!BQRciYg{Vv{AZYRzb(^9>Z1zb=ZNaiSvBno6p7H6oL4jYftjmZS6{=zf;k zFRovBc}$8elhs<+BLKQSD8-_T(bLsFEsyLtzLZuZF`_}yTt}N`eUv#XHR^_on6Ok|xqi5->dq}!A z6kNxr!HetE3=$`!}kCG`_F2dIw9jYTHF^lo;xqM9y^ zl#7`4GN+Cmk+oG_TKNRF9g<@#(HU`B7t6AdY#lCDf;&u}fW8HmJo-olZx=nx9^sJ` zsDQ?tT5~Yy+*3JoQCq7Nd8oMlUTF5_Fj#a!=%t2>6yf9;ORf)#Y>Vs;fd z(_*J8J1S>YWqqj>7?iOY>Y`14maZ?ZUs)H{Vae&dO8Q1%1O}EVELkX!gI=z)v*~Nt zA*DT?ZB;w8dD0i2#RzT~nNZtQ=5Di9_UkOqdom3>t<_T@ve=ZdsdvHsn4+Vb9m3|L z9F(_TI$0HNs&b=R6`x&^N{mqRf5pOcb#+~jX(pF^DD$8ODm?G9Lp7S zmZ?9x;NQkuuFUd8pI_dzpE13IBh&A=0;AN!wuyZ<==4N!fls^|qE# zy1P4W0Jhkjw*fmMV1N5tcIRz^ExJRtfUp>_{+cEc+i%6Up*wB*c3EHbw&F_K$M6-k zL2dc@1#M9~DevWN{L!0Ry_R()GAaTQEUik#;1nz=*%U8IeRlkql84H5szOH{FB1P~f~bHMIFBDyIw?&m>l82PglsK>#SQ;GYq2+4nl2x0AyCBX*- zNs`1S@S#CX#Y%0c&;WL8Cu zwSzOTCh(rJrgE88gOgk#LRpnCKXHU9)I*@e4)p;rZ2P7LADtgMWEriB1Ce(pQSAz^ z!OftSQUu@6k%$PnWM1MG)@!p}U2ZJ9;!7({opGW`Ms7go9x1cR9T`S;r-i5iYfx(w zvMAsbuuc&OpX6i}A!6)`I0ZE&M)Pibe#JW_&;cCkbkkC%jYEKPPp9tT(gq%8Rnjs5 zXd>#So6h-_xU%oq9}-iqh+Rd*E!3FdgEA~_q`Rqb!l|dNa4uTlq_Kq->OJ6L0wVIj zgCO&?f}HR4003FPoND+$5|9uq(w&0-|5EyUt5v{xJ47?j>d*Ry}J5;ky7f1QgxN5joRYD>m`){gnSk zT!mg=cJEuUDmkpf*6gBIZ-ryl?8O9^=Xa1IdRw$Q)`x_&vu`I4*&2pYAG&i)RP3>Z zf0e_dWc9qa7NR+QS&uzfVrg{#`K9ii6&OCeI*jkWTNeCmSil)-ZrNe%RlSt?F>y96 z`uh}-LId9WXp)nEyuiV6QLtEPXtq{2X3(f)sg#|>!!rdCu~k)7Wl$kvMjXZ&1RVg;HhCP%S;3$yMMC=Q`^`09l^GoPXOZ>_F<=PA(Cs-6V^|*gdWiZxi~L`s>I3W)N7Mn` zsE^oDnH8dG7;iIOrfGvVA{5DNY0$mT91?~Th1c6#rVU8G950|DTFwJ9iRV10A7by@UD;dWG&o(JlCtX!2`95|{3Y6pxoG-ksZfm=GX7hEQTC6seJa2C&CZ)Qv<@r|Z{6GqqV-LPo&SA^+5g_e zcE%}e(xDnqrOz1-*ni%{bD0iDV3i2co-Pd89e@4oM-Ay+^OxsHb%iX|4o9Q z|4o7rWp+7(K^=tTQMH9ci-5S+zk-}GgGlJPolDfz2YpI}X&jd$lTAQuB20hUK!voz zXxioyq1wO=R9sij(;oFk8dgfkQ9q&zWFG?EtqGz1^Gp@leXe3@+FnNtFuRw5gMT2) zPY7fg*VGJ;MfXBmAnx@*(p)as-j7Q?W-=FPfv{Gbq)1$Q(&Hjw=BPiou(JjG<@;hH z^|;mm{qp1)dED_H1WnjZGpRR@r0g9@*t(Olbtd&lpXjsdME)rum|K(EAH0U|_AMTa z4zlBAN76zEp}MKsBMdcN3)css{E}-Rh8*cVE`Z+;Kc_QlI0+MA7$J$cG++(s$=aXN z0~Ex)j8FhYK)S#1t1^EMCrv-;nYN})y}E7fsR7?t$iSBrxNp2=z_J}hlJI$lnheZh zbSUDP*9Oj%Gq$O>Eg(8<`P+e=10!NN+sc{KF}h1^Jmq?V20B!;VIW{d-ZCR$EBH}n znF7EjK&UYW!5|>_F?_*#+#9UT!w{JL&qfiwdFNFea*4yioBY{Ff_C$BK$;svE@J{T z&>sn>fS+3fj|k$Ym7g9eJg6QBmpT29#D4Gl4-xR6SaBbgjw7X0)w@@XektO%g>=W6dM2QDQB`8KivIc<)dS@&gYgCy<~y({N=;t5GAe<9CLT zXZJLYo6lRIpHfPB0K52H9hsiZdVC}@1EMHwV)_s6DGA%KeiS}UYRla;2g}u!e|T%% zy|Og*No^tM54R;O5l=tGS$LiIO*=^uY6E!iyj+d|b^?wb@p?J*xWH^c4T3nu&GkSG zoq{+>?7xN7Q7P5EL`kG^dA^rPIzg4J&RD4&sCu-FFMostvV}?J0iQ_HH{j$<0afpQ zW$ey6JAdFWed92e2?{?Y4X(!twD+da*yaWUS^#+Ha3^qOAC8AfJ1_7uj^p)F`-3R; zh-~ZMP*i%sQQP-IqtE}Mk3Vvwp}0zHb!poKR$ZX+2+hXCP8*0v5BS80b2lmr8k^w! z!w1?wU&DIuYPY9!u&#D}B<&%U1BB!k#o3Q8wzoQFa(1r*B;_bWqb9jYy@p7zo7Y$I zLJND$-&bXlyP3d%!WyFXKO!d=+n#ZIUZmpwFAYh>+(I9_$B2|@_k_!|l6+32M5PFnXlHX?1%pk-&GtJ6dtcHI5%$ zBACVl>pSD9ROEZ=&ENU*j~q8SRPWq;GoS+ye1uEMG~3;nn~mh+a{xxykf%pSj$B>G zOPZaf*L4VAOgs#LLYkKMmf%X`?+k(l==cgSejk!E43|r!OyDo50NCIXYY=b)IIdAN z6|d;RcrC*Sam`^%JlzC1km!z5fk93uB1qq_e3v)81DU~u`*82&*c}B{Rl9XGPlHmd z=fBtIK8d8|^7xd9ReZn+P%DDgLiI{=090H^SB)R`xRF^gD zsFL4mRh_fGGD_RTIE460h>(1csjPR#{as^*ZmzN1qDpG|dN>-t*)~l(J<_w(`J5$Z zjHl$EO6e8Sw(o{ia#ccNP_=FPYAr?AhmcM0+8FPG>Y(@}VLTDy#sl`#)i6=YaYigO ztFPGtQn^&5ycK7UyMC!p!uVu2`K2o#B|nEt|EW*8asP==nQ;9n@irio=9Qkm5y4h@ zZwKZ&Q~cFRa1Vw{{Lj*wvgP$C+=uA1ju6epM(flNTlS=4sZkp(-%^eT2QW=N{wkRa zL|lLt9QAo*a33So0ER#hyf8LSkoPR;_@W4D5 z=feQUKRy@-iO)u)Mgp3x2N35z z3v)$a=6c{Y`0)OQ1LKcJa;l3?7_((Qlw}!0mMi_Tv5Zy9`wC+h7pKPkv6Xm`#$E;< z;Pj{uLnXX5#4=x?A}f3hKpn@7q(BsscL8D<%jZJ@h}GYU!(tETP*A$mD~aTnBD)fj z#$=&VayPO|%4`q6$wMN$S0@yjba^O5oZCQ^gC%`Q%H^;#u?aaF%!SvRJAX;Y-d``8 zZ0tHtR=}9oB@&aEj;4167C#3cmNs@RCoylwQRJf%a~k}CN0Py$=L^&*#-!wK`Iq;Y z;e|=gZ>f*(l5>>mW8;!?H*pJRqk0(pGEQ?HLCg|!jDa1WAtxhxc)qV_GYZkOTIKE0 zf0JY!y-p^B4&F$aF#q&}{?I@By&?bg0sibi!+jj`M^fekIzEGc*tv9i4fj&YBhYVA z7ZM(cYX>5en$g8h#f1wm8DSq1e{i7ugc5H^^f4uBJq$_bV0xsU=t(`g!>T4E@^CNF zI=l<=O-2R!C+rxLZupW|pd|9h{S%|WzeMM-FV)=?0#10un02a>b|Ojh;1XCsB;g7x`@a}i&2V2T zxLA`&4ZO6r1|;QkCbVzV?7i_m6M%4)N{2Tb<(_+GMWnCkdFa#=f6N7y>G+ z^n;RmE?aZkh~<@AKn|zwNO`?~?mxcZ_mK~|np{aX9qf4=GGI$+$nsGK+~|MtBiIte zKj#1)XSaza(+M6+EzTs9v9aWl4?R$Q&-ZcU-G*;q9(vIK;0K&oWBS7wMg$%_GXh43 z+%7?k#&T`6hJQITHQ`c<7j^0a6t-i_#FFqu#|tyz1ut;UMgu!X{bAEnK{*6P(eqO> ztmd>WkY7$WtAc|i)sAyS+dnm-%w=(8!hqZ_R|2$+$G0xccJWmUw@}Ppwv(Z9P=SFQiGLkeKnu^2*-;6qF?o?2L#Q2u#X|sFi<-3NfSAHIzCII2 ze321f*aanz!l=Bku}xFZcV^Tz?nS?L{{c^G5ht<2mq+M7NabKKosWJS9Ny@$flRu${O9AA>mi@k=1VO~>g z(3;Ty+4}7X$zIINE56gTGYac}yFy!fZ3x3s%$b16?Pyt&G7*_L6RgPh+GtCCD>6;zcTEYn_SzA}?U^!wQ``XgA03$%>4V+7Ft|Jfe@US( zH_ZtO)tM??v?c%GXiEylgxUwb)Iaioov!d1lLQAmXCa{?HEhYWoCCR964sa&y@(_4 z8WMME(2qm^DQeK0uwLXo=7fp(ni3k!3E+dl6Y~ur8eqgF(;1x3%S_Mhl>q%^=OH64oRyZF$4h6XrsZ#-lR+V~gh$v|ttBlf@oeU% zn}6mnfH=F>L9TPcmXvSeXH>_-zsIeCkF^Ya<_oy)hXDwoLBJ62xdt;+E&NRmD?=^| zR&ZNpa#j5t)hK30RkW&O2OoRLWHXuBnP>`xEB7{!?VF39Xa1kJAU+sA;k7uDHV$En zzURaL^mp3o2_j@Yd`U3A#w44)t|XD0Y)LN0T(Oz`8)T|ic^4*q+nFL<06Kk1!|H?H zFaP~F|DK!P3Fo<2rtNc@6?$&Dtlob@+C8>}Sn3|kW@fZ{%|sY`6L0mlJrfc-bj~m?AsZ+Y~yKb;W&T;tW@@I3-Kp65=6bK5>9Ep zj#@%%#?Zr)UKrcTiz6AF{(Hmg$)W&o&&<_&!#zzuqUrK262_Cp-~P%vxZ zCP4}770{yuy^`QDcY#qPrL>}p!sGOPz z=Vd>0)_y>H*e(CquJm3^m;a)>oeuY&E4!)~o0v!5D&{2mNIWj5T*5nYY!xv-}4KT;#i)ZhJEs(ax6oI<|XMfD&>>5H? zZqO4-^A z>5dd49>@a1R)Ae}#yCB;a#7?i7wQN@t(|Dv)JF!kf=AkYoYd+rYtJqxlOtv2tl?XyE9DPLLjwwxQKk_^{5!yXv6^ld z`6lo3lHM^CzqT(a$mm;V+f0O!s0RWfaN|Fb!ao_@Y4L<^JXTy8M487IVZQ+k+Lu~y zyn%H?_KrgF_Nww1w&5F)sZ^xGI4rGIQimh0lGDbd(iHb<=y(8VY8;Z${#?}Bm1pDx zZ#K025{SKrQhU4Y6p<^oJJ8#TU|Xj2Iu3X?`w(hKt04az6AT zz8FGi=#+#d#+Vd%p{Vr5sdk^&nwtIRD15J0A;;W`;qvaRMmt8KtPN9tR}0IcJnr~P z!Ht6l!x`PjSvYG*dMjt5ug{`^MO+Eps2Kp?NaR>9Tu^63EdT{{=XNVNdeeuk6P@e} z@1%5dcM_~k+&_Fx!@5*-qlU*zr9^DyDT=UQls>Fh3)-A%=7yHnW^Lbbo9!?QWO0vv zZ(E1lVD-!a?KN{KSB#fD%g%pW9gNsqFt~KcK3=+HxJ33_N;x6`pBm_KHNlF24ET6= zjG>-o+aQB(>6AEEDs;*iM8L*~n&8Di1~_!v!-66(zB+TN9!|H04|`?f?@DiQ=P_#y z@2xku-Amq^-(D(nk$Z0vEFgjENr8dA$;mkk~8q;AM8wsyKGZPs@x^u7( z3g#`IOG8&vY{)#15W7(EHE-x;9Os5>;5LJzYv5G`c6esFM$4$08rd!!gRXx(C=Y>n)e6KQ8iaf}8NSSU2a#1~w$h7_)x?`HADCrxslFR!;a1dN7)d zT_kp1l7FXQdmm-B;*Li8>VKzVHI-RI(NFa3g_tw_GMfbqUNB&n?-@dd4%FB+!GpGe z$B!W+@#0I0HYH(-$BI0F#D{V13TjOJIB}9M{L=q}jC8+;#yVg8bzk8x$R5-=W0gzt zixf-7%ZOmJYYvy+pC$6E6ien7KTGg>qowrRL#6u8Af^6a2lh+St`-fMF6>a3b*M|Y zilx+)B|<x7W!+HQp&Fs)z(#%)BP$S$^Xi2e=X=78 znHYvVwRrTt3{<rzj^R`|6CGTm{(g0!`xO}>swh04d=^^mE4dgJUJP6C5O@8 zSMNA}{freBsoY2n%^CCJ{;K4<0mRGvDel6%CI6*Eq6&j zuZ20hzO_}m=6X=l3WT`0gC|km@+vk9Jq^vg;Pan2eskwX&pLlR@cHMD=PEvOwMW=7 zRB3ks#_=HoDooh>sCM6SI;zGvxXy63%pgNU`SF6uZjIDld#XDq@G!65F-mZKWB_{8 zgZi%z!RyWs;JiS32OQSuojKeapYELP5%;w|GZH=66y5?(H#;0@yak5zr-L`4#NN=L z(eqHCpEr^|aeV?C1LYZxQKif7?Zyr*hCm?Vs_VJNgkuU8Lk5p)v3T1AwT}nUjud@k zLfc%B!m%BX42Em1K0-AnaQmf&suwY_jY)(mSow!ReVER^^4_L2pG6aozXkxzze2ji zUm6;~cze*V_U?4iq;1-`(`N|SRUD=0RqW~gJKNa$XOHQD>qkbE%il$=>5VI>($CY| znSG5IXO9uPo*{AhEGHq>L>w=0XOa18@=cY)iNGMP9?1IwLJz-`I0Zpczg9hHFA{^C znS0+L7T}70979(c(Dp`Rz{FnaRn`Q%Ai_DRzKiv-*@FGGHtCmCIe%+S&Jv5Z5@a!^ zRE>iAwZoao5;yE0)XSe5b(+4m;9pScK155jikDQ(_UO#Ei4O#rNTo_MKn0TbRB<4Q zRqAiy^IPTtCwG&$Pku2S8qu9`NOSrrA4;(F?0=4`;21phtE|agvb7v>en8?A zrdH0`TauF^UGS2(u)syzKrX*!sqiB zxVKCpSe+31Z9h3YCm1TA_W>IF6C)C22de?gFb6C<#rnBO5P9oEK@PSAg_n}(fmaV; z+@`WMR(;0!7#sDgi{*way>J;^PIg3ZcP-#f9`BB1AWY4oGz6DQ^MVB%bp^eR6*e8( zyFFEB{db^F;J$|GrlLH7*|{ zH6+2o!$863GqY1|j~6+d795M}are3D2OnQ>OMo(8>90Vz3`s7sk^{?*FPQ(A4xHeI z)^$+0qleg#`cWXIU4>MRKbVa}kSxaJRK9NT6ug2#G9{kK+ys^KYcl9*8=fZ| z8s!C{<&Ta#p2;~bU=ts^SdsY*z>vx2BM9L-Hj@=utZ zCPuX?5zQ7O>*l9k#&zVI()vDlOS;O+ywJ0V4N-s=y~wi=Kxu#k8!IPFt!v!8KtBip zrELb>uAAEl{*-9FxTw(yt$h9PT8MQMdT0RJLvEmpzxn|yX$?_RQ&K|ixk2d4)vie? zGNqBS2@bA4v1aJ4UVl4HGeJ|Q$~t9kdAl9+yg8RlheE{nX|Ds_ZWD|dII&UO)}a*S z0EWF>X9U>9s`91Tgn}&7lecfVNZAlF%zlPhhuMk&%vJ=ywPkiPCEShhgw%bQA8ewg zTr=YmWQquBk{~c8f69dr$LEYIRVbl#DD%}PKFoM)N_YMsPWlC;sK3i*J>a*CcF%q46$4QLhQ7>;Al1vmu`0QOlUHN zm=OL+gWr@7Goa9wsE3*`b%+nC9k0+$7rPNz0}A`T#0nk>Xcrf-5nb_xd@2eaglI11 zOd9TA++kal1rI~?8Y0;Us51)JAXI$rgT*f#L)uOVdF3)w@7S+ru@^7kcUI=NlOYJi zm>)RIXm-OWKUHidBGws_oALW~l$mvzdtS-w%gs)_I05zRpQ_=6@YqaV9WopNUF)B! z;>||}!KkMg4Qha190<5dbpLdsl9!85Zk!Cwm) zB$ezYey(_Z*JURuj2^W>^9T;wn9XXK-wNmF^SS9(4>V+SR2*jab7-NM%wxI?xP3{c zAG;Xgs!(MTgDGDOr9j3LrW37vCt9Xi!kKM*;e+HdLz;|o>`GLlL&6S}Z|fz)s-+hJ z)fes#e1s|Z(|TElqW$G)!sZER#aCRmBqk!I#-zcsrLiOHR33ARd8rz{)e)=XQgA*> z4ndD%1!snb_PUsUX`E@L2-@~Ep2nobNuk)2<_Zvayu;f-89L`9H(Sq4a(`FiUt3vj z7#du7$r<#^&{ydpLX5AV7uvanZ->+q+lLkL-wzOg9ROAB39SP2l()58da6cRdq$o zT#GyZ)TBv!-=0#PZ=kKR>T!@II(@14I262G6Zh!TdIy(Zw)aJtU9ROyGgP-FdWwUU z`YM&xl4*$QwKmYy5R6|PXAi7@P5dvARL3)L{lPO-`$`$VME@LvK6ab+GuMGV5_dpT zXJAcBpFx{0V>VS&GP9YgXtUoO(RA1=1Xy17)8$Pd9z4#VjVWw7p*XEL_QqZ+oO$^# z6>XptGpG2bYHhVekpE;`?KZk@4xLv1FZ3$&usTP)-HJ!<)ET%>vP zBzfc{asZK?B056{PC8%m^z^W9c|`eMht+8inqq+lNK-mqm+YC~;3jbp6F+?koEeif zom9;Z&rvqj?@pU){TKppv$(G}li%EuW%lXF5gd zpLrYY}i$qDCd%HOsCdN|el%#TffwU5yx&KSQZ#2c9>ZkNyuhRKXX z@^-^13$p#;3Hjhz3M~hkA8=$|PTsA z=wG~V(+u9C+#z;l$8^h*lPb`LVvAEMYuHOso=RSP>RdN$>~?UrCnqG`f;caBT{wa%(9!K1@)=F+h5?BfQDe6==YOw5 zPOx4}Q~i@o#{6maEN_^XNYd+OEI@k$J@e7W&UMbCb@@k{f)RdeE(FbfqHW>YdNxvdN62A~zNw{uJB zzO*#;CUJ$h<^vL>-h)(9^G36gd0_%raOZFb+A~&51WQ&mmlE?$S=HHZ!Yef>?VO<# z_iT<2q!8J-;Eid(qV6u1c3-EQpeQ8)e9u$_u|QD(3X3%;9zL(y{nsu%Gf{e|8=D1~ z_65CB{;)Ty(D7oS*Y>EPM`|`J#a{RJiopL=6`C)L+>1b$?<$>8jn`DX(>=q@7qvxs zy7SxN!*fOfI-q6Mdn;qmr%2e)+FZbOPOX)~Bd{9O{0C;PC}I*9a1$bY=uVmSd-dI& zFxq}-wAA0JBsNP*=W%YE7d;!Jf5qEKh$Puu4D4Rc&a@KRCV5&-h~I{!$l8s}x!R$f zp42&W{PzdByY&DWcT84~pIO8Ubc}9}*xf?!vlYpWVyYe@(^fK}tQCfYZb&+zsapOO z>dm0)WvOm9Yx#d&P-NvC1L7bH5dKKs7=Yot6?Bv|oZSno9)*Q&0-l{^-)yf!T%VbX=i^31 z5W!prHhchnQQ0&v>j(JQJ0UnQiYAncYLcJaj-Zx@aAsIT8w9fs-s4Yqbl&395>kVj z-{xqWD+J{1oA8ZLN`H{B+&-H6(@v4d^Hz#&V`3V3j-h&bM->s*tL^un_zl%jiIeDLr{=l2zUjHPQg!J@G!QJs(Q$RlF>Ok z7XEc|7iXxPh*CB59vPOu^Sdn_$3la)ie^^+N?fOsHkZwWSgrK2zGx9u&9sc0*D0#bXq@exzpziNi?;XGG zYn|%UU-df1W;EAkZNqKC4tsOS(Iff4aSx-mJb?YFkiXyQKCd}S{_wgGt=8P=R+HDc zlW$guHrLQ1j8MWyw)nxYPkM;?{Sd`Bo|vVNt>JOMxKMbCt4Q+J({j|Ai|hXC%UuCg zQ!r&oxG}9+Of!79>iqYvb$zF*D*G*(l5_sb|0CBrznk0KtNQg-{afXKjqyHL)7{k~ z8Tc?uQ8T+$MXor%?f3&_;Ol-=z<1C{uc0r<%U0*?MAIDa!~a&4zZdIHlk9%9_*-+W zIiFBgoW9BO(h?1&N;QI`(r`993!MmaYN<{S7Jzbx27gP{ka`2N-MQ_?9j(+5>ljPj zR^)O^4Rtjc^ki3#cqtc!(lD%Y<{Uxw`X{M{V@D%fY`t`_R+e%$y8^}Qo*MK9(dK#y z)Gsp%jqm(}+-~RiA@y44@9oeTu!cz0$uTl1Q;Ex+?4G^{1l1I)QuoYD6XCKxtgk^l z(W!r)y5Vf}9R%u;eQo25HIsLR^Z#(wdH0QS6&Y!%Qy=L}fBAX=wLF4FWLF?>7cgPH z#mLxH4RQlQB3LB1j9&e~T*tzVREuNc!p^)OC@d=M1fYN{BDqCj z)gfaQA#^nWLgsFu5V3|KPd_0@0Sf_`f1tZO_dz=`kWp2GSDya~CcI2K&Y^}zC`>%; zyY!L|lv-@R_(?J%LThr87=-cp3P1=`xpQhqZJPbHn>2B?d7s-^qB8H+4i@b~#i74nzG%Rfq?^QPpDDme%ErO-*_yPQS@FSSwl44<&{mBH+W^`YFR^U8E(imD;0*_9 z7$Lhx(9wNx3c(;%*abpbUj$TO2E8g83Y;f>%XlZQeiN7DT|>mA_K&j7`(bBPJ74_A ztTY_mJb1C-lyV))ao7g%jy@HZk#X3D_v}1eO!PaBUq#PJW}fQece&}uHivQW!CEhl zj&FDomq#4FlaGaKDMs~40cNbMLV%od#_(=F5TTQn%&8WlRiLb|1!t{F`N!bnNk@AN z6scb{RVeZofA6k=h#9tVP5JoWCQjoYlA@F7rTGo@9LnQV#;1KSQe2|s0m{_~mmIyA zIx2~m_vW(x>le^*fRR?p*+G7Hq%h_$)zFQr7DYTkyrC1W8}qfew;y~KkHI|_OKeh5 zW-1$t>9-m!6mk)Xmkc%1>uDKSmqoJ?7Bq~k8l?tYH>5XZqNMGyDM6)?wk;X5)(KTq zL5UW;2PVqe)A+5pi-OU_hC=KBaO|z8uau0QQRI3hz--3Yz|pklY|V=Zhf2PKE(ZHP zNTo1kk|WU2e!kR+{gW8FO1SD`2cghrhCHw;e@oF@pyLWn%*7df8<4_#}B1 zN>gMim10+bRVBv>2ArL;VO9`TjB;<_DA!Yr1r?P8SDd*2MAd)%e>Y7c@znSYYvqHdU${r<7|bAEw5B-aTsVx5baX^ZA@ywV<>ez{K7SU+T-n3TDx8ZLjNkQE*dzfKhFu z$aZO$h3JmQJshUDVrudXWgGm8>>NM1YBL4g(+87UaJCH`eo{bRM6Kv6f{$?mv^vq>?q#RdW36spSkOBm-IPjOP>~y1z048+|$&WFHV_Xw{cqa#t!SED2SY z?>7K!g0h{6)>FkOkn#jRM#U8p_noF*BZ> zmbcJ1O5K;jJ-3)L@O=X^;w(I=!^wkKspq*fmJPHxlNO2M70KAC(tzw%t5q_ z?>0v-SDZVs zpYq@C!Y{Rs-a6kth+bv{LiD@gh+n$$-$XAmXoboF|LgFNg%7=-lE96bFe8BfpAY&V z|D6y1Bzpo_hx|hp1chZG9x*U7o12=O4mHSBJ}t1{$rF3OeeaeJJ)nQE35e!?=>lv! z*z*?cqa(~)U5;d_Z-L)4Bwv!un~6qbvfScH7ldX`1<{!^cy?suuVziyX7&-WBCz-0EcEXf%N82Q#@un+rvD>6f6PH-}?3ZW#7I*qb(_6Za$UCO+~z z>9ayz2e68VJru{guHn3PPW@ z6Laf*%v;6Bg8gp5pek+q`!LivsEIt5b$n$TAK3x=O`%0S5Iq{JXA&&vj#paNM7t8I z-sMX>33#6EaIq8h{Ion-+W~5^7I(=gac?^D6&G$O-7}G5+Oxq;o;6Ge`RSeGG^+E- z8;fdyCJyyu<(s-~EuiG4-?#w1DgyD&;*({a6(mt*(mRfZJ=+b2P5w+=^#UP)C7>0f zzKC*58n=9M+A9?>T2xC@VA>FbQB7xy3Fw~2|JyI-QJXB&5@Jdc|#8-8gl)|HD=zF z%SW#YH=-`XB+&1=`b1%`=*b1FtLe!WYVk#f?Hd-WITx=oEKxzcz{EW95*whAtidWQ zSH6CJuw#7oeJ+=xYEH9og1*rua?4T83KNnz)4gPGzu&}{4p7HjC%GWyM{nRhlt7AN%Y(#e-k-xnx7HpwwRLnarR2iH#_`)EhBo-S|C85P(I@q7Ql znJ>9=|Eb=Qe$iC3B)mB|lN8s7xEchC%EC=Z3xvN{`(rVF{QzDPDU0cS8 zlN;Q5A%cOxh%Qy;UQhQTKA~%sKqx}NnAgL%isewdV->tEC{ML1Lk_M>L>!k+y#wbE z9PXGVCdCtC3V>IVV)E$`9$CBVE~VrnRO*Mz2Xaq?MMM~`MQ;KE6=B~#t`4Kp%$v<& zxA4bO$5R#dtbYW!c0p6v`|n)$u`K%mIrl+dapz+6_a43!HKO-RoWVP+1pH9Gh=%n{%Sd`9C%pvoH!ysc|Yf)HEmF{y8 zo%w!$<93M;X}T>8;^Gr1#TUMH+BPhgjg8`nZnzhSL)L8zM)0p;yf!p#TUVRX+`~58 zSm+mWuK6))csH}g-=B1YOc%(&e!dK2#2{!x2(6+TLZk0cv?)S0gnXB%nHny8ksGqL z<~=n&gj6I^BwK`r(s(k>=tVodoGteEe(TNltKgPWxl1KlO_^mbzP2V(F00{jr)I9z z7!#!&2R5rIC@4qVJ!R63kdQHBte5B2eaM->=Y7p6S9myldwL0h#{B;*Law7XfdTQ&)@>FC3GV;!8OwVdc4BWJmzkO!7>*$ z0OI8B_tzy6qwxdXBo8itK7Jq=K>c->ASAjJDe+Ny_~`k#N6Z9#+>%`U0pCJH44s@g zEx&ULjAQMxFGlEUgR2VGBCint+tGcc3z3A_etfSfzVgcrs{5jd=TijLI0U&jp@S~_ zZ2@u*R)PstJ_I9Uds?2I_S)fl$n;(nTIq=OmBemC5*XEqHosdMb`s^%JyC3XcMx^B z6qc3shh<=E>l&)xLj|>8&|H4jK^2^y!*(H!l##(;3W9J%r(*A!XIRi)>wvD8f5KSu zLO@H)ZEJ5qn~A{#X3nnwL3-qgIXhkIAQjowWl)8KM}KFh3rA>}LLz+H-@u6GgpQ?! z{U6?2AF&8Y5Hr#ILl`a@vOs2kd3n(XmJN{4!NJT$U{a5!7GR~`BMt@3dtP1LThCr= z!|k!x)q5Bvs^wJu>*98v4z@w|+mOBQ_oDQwo}KYSVjNDvUI|b3-t%491QvXNjo~yR ze;&A&>E&3$CraHCTaw)pbHCl8N~DD>@7#q}#zR?th>uBP7804yi!AnkK>knLJXm2DeNK@#jv6VgaJ5xR!M0D-QLw)f)ZmG&U5Bl5!pzJcIw+eb z%TX6?;w4WW6}JdmZkV5)rxy;raooY;gAriF^MJ)T*-^O`_#ty$hdnKFAE7^B5Y5dI zsCX%m1H$u(F#G|BVd%e9T>g5AAmML%+pXavzw_m5NfI)e@@6nUaSamDy5daHK?b;c zp@2|8*XvG`)rGsaP8Md`vc4w7KRt-y99uALS6+u1`Q0WQW0&EMp$IgRLr;qzk!SK?W=5e?CgVT(SjR^LPXvkp{GtcO;G$t2I zuD(mum(!6Q;8(`GRom8p6=L5`f_lX1f>p0ahh&uUYy7s6NOB44iygE43X!?9{t~+~zQwTZIF7pU^*YlIAN!XPm zikzV1y`Y#}RGx}TfuwPdl7faWxB(9>(#C|$66M_}X>XoEJ17O(f2ld7&?hrhR4|B~ z7xD7YQlui3MlpV(wL)_wv>(%6XZXqm5xjDNa*V4|h5{OU5S5j7$XixfmuusPQkmzS zB6El`QBzvnXwL-u7g(=8E<175>>x=n2;Z!2R{04uL5;Rr;vylgyl>dK3CUM%EP8Ab zT2CB1$u?J?mI*j^?@Xg=!mt#;nR8jnBjcu6zoRIeZDEk)nGzxsWP#}9&Gl1$1WpS+@7AY$+GCE;1W ztq%&mcwJhb%LTME<6l|KU8tYDRrX+(`6A;~E+OGB@AeY)H%5#ljH!nBG%c%6)T0S> z{>|nR)B-AXXV!q1cG7>y5&il4jnX@m#*Gn9CEI>`0GH>dXAX$D8x zPLOx{^1;3JL15T@_rrc&4x8y-YZ>$o@nnE}q-f?CQn{!{crjL!ElYwG)eUyT+oT_# zMxtR;2964Me!!7@v~QK-q5l|Cgyj9VqZuQ^#l6>qJ zdaBJ>^|q_MRV8&YM>?&VHsL+%SsE9191`R07I!ziW_8}uc57pflo~w^dk~H`aOM=RlAmqG_8UG)FBq@4<#>NNcNN<-Y0r1v4C~y-N9} z43(gWj?IihjvxhSweY5G{9_=3`A$}<-Ie|^OsD|s?@4lB>4rp8lhT9Tn6<_?se`R% z2>%2~ApgXXNa^f;ds>Je{nSYZZ__ZZn6J*P4>^O)`d+`M68L@P`mXanQj!)X>2{Fp ztbP%-f^Fc9YcMAndxA>{n`TWcTGjEL{&6=^8vT&2oEN_EyNnR@2#2i2Lm{(4Sr@;! zahq=#24aG5M)_sJVrDg~h_(z0Jnq@yUEo>hvHgWJDLWEw@+363Z5~;nAG#hSNw+N( za|CRfQP0Eq5!&P`-$hX&OGfh0b(AC%DFj8T?~3ZWVTg6FJURrww`Rot(6-OzIBxo~ z;3EQmUfm9Egx~ukL)7e4#gjvL6Zz=3g8F%Z{qneAqd7Ypb~X$zA`)YGmylfF)RxEp zcBr;J6K_8Vg?GQ_iW4*?YxzCMjz4nPL{w)`PmSZETrE6>?X7ggYRBUi+A`$zjBi!o z2<3|1#ntVbZ{7qRL6_F_jjGis^T+8FpLl#4nKy@vQcdB*mRKTao98Fvk2u<{?Etuj z)qJE-Vy18ewyXYR(Z8lnd$-8bMb$U!TWmc6RAW2Z1XrYj8 zS6K)~p@;Qx_nviJ$oAy#0Yhv+Jo*9LpCRNTWo=x+H+~`oU5z$9l|eZ)92Xo+hb?1n zoLwWK5qfgH)>I+N0V741C;9)IqL`w>)9J#^ zs>y{kVXs8jm@BPc1#YU7f`E<*5IMwpMayqYoR!;n<&vG{NQry3B{4=-Oh4mgqjxw$ zxg-jyC`e0hl!cmk2+4ktWWGTkyx#KnG}{&Lyo=jnz3=POg$3iKC(ESt8{DH?-tr%KNNTa(IYY?*&;X;*xS#_+{ z`cW-MLlge`TO0|gOwS&~IPL}Q^A%rnH+_rDtcjGE5B3J88j^BlD+`e&ItA>LHNT=s zE~=v@w7QsLJ(xAF)@Yi|ddA(M6f)hDx7EVs<&{%|Y7Fd`sXG%ZIOpGZ)h znLjDpI~Yoe_xUW0eNmZBnd-*wNmA4lNiM`bX?@>#xE$q-1X}+ViTnQ2I?#Yn z(W_j2Pn~^8=lW?7Vcq05HSje6sjWTF9*;(oJ~1*tbwIpe5-ZYU+EE7<@GeCTJbabdl{T3ZB|s`+6C z&C0tpT>DV<6C#c^cwv?AUjGVn#d7P{1>EuOhC*ebXi;XN@FL6LE(Cpj<3bGjJCyOS z!0t>jZFnM zjZHl*BDOR9YvUg0j}pFgQ}73~Ln^@y;&^>zvJ7xCGRQHs%{Yc*-*vMl$LwZJ<#tmh z^IhD@nfH?> z&byg0#XC@Uqn4R7S2HHbT}_*Zm~d%FE)BR9_aoldFfll61uo=1sWO%$vUi zI`C`t=L1P2*FBSiU5~#gtBArLeCvZ_Idf+3#WQ=eW|$6-ZUe>hTeGV&xgP4ryRq+tJ+&U(4{e~$nm6v7G!g4r{Jkcok4M|kIMQj< zuPuv;{49%WeEsQft^l_loW}LQ8z{;2?x}8(DA}-s-VnKMrlpzF>gY6?x(a0{H1w1Z ztIbl=cV%A%rlo~+DMGcu>8W#CI!!eM^#vUVZl)hiOEFEO)lAa%?&;HGL8OcTG`gwn zKX<33(+YC*v~cN*dD>p)9lB}7>8VQ}3OF4#EdGzSr(A%7b{kDgD@Ur)_f+%LG`gY& zrKT93eudtnwx6ca_Wi&WPHo-%GiJcGyv=m%i!xX608>D$zs0*IJw%!_(KU(diwqW< zNedRm>9mN)v>HgEM6>!y?LUww;Sf(O!#t*qN(KZr8t;)8Z6jyWLYJVUqjB8OQYdC^ zFf-H?no0_2sr<)nL@tcZRAyMLy&{wvY6@XgWoT7cMa$^v5 zYJD*GWJY`>`5)pLa3A+F#zkH0`%tiY&;ur1)26O()_eQt;FW&eN|IL2tolO7Le)0We;jU*UO(Qom z_%GW*=`Y=H=)PaOhSP?W#ZDSP3&*pZH2y+R(@}GV+)vIMggxqv&cg{|8(|?~(AZ*Z z7_jJ#g<-KYa|VWB#;i266l?*o>@f@pef`C_t8o_dmf$Vst-4ylZ;fkZyv4t2-df&L z-b&s=-a6Zrzrkt+!jnTf|%SEyB!Y{^k8y7vm?#B2*egmsx*_ zb}nX`mr<7%TDWE?srp;%3(~xI%Y3+bK153QV(+6B?Ly(R_@@8*xPBILaM@hsMZ>_G z$O{AJ1%LgaU+My^_+#EU_CNyBk8*k0!!}(k3zT9?RcuRE;=dbW*a|<6_qi(l&m#L| z{9osNUcdRLWcXhv|F%vh$;Hpa)^gJLsFnq(*&*&-ePQd3SG#a+0DnBuQ8+Cxfv|G4 zdVMt~mFYM(j91U6ElW%m&UsGij)Pa0mM|hMvII@adxH5oBW32o#ZB`i3lHrauDYSZeMJdaY9~g2&KT;KP zrY14NgF=*Ya|CD-xYnwgh-fbRV~pBjgG-}#MxZz6H2Os-NGBu$ch`Y2##_8G8sIJNUOgY!Cs{OS`70rKV^$Tl9br z(|8C$G3IDMlX`khC06~xv?BYp8!vhViAWJ_xnVaV`$#?6ercF^PZVgU6q-KTj)O>B zCnzzD8_dAi6*>c8kk9Nrm=cPXYnQ&==>g0V;FRPCH~`vB-)-hBIrU4bPTl}4r~=$y zk-8Pgz#g7Ha#++L|7B16ikVbq2SYhv#1Ee%!LJ_1y3*&@xtEs;3 zQbrglBf$dafi6D}d<%^>2_U7I$P@cZb??DCSXgA6`~;XbUq}eLYC?BMPuvhafCI3<2g+Up&y91q;5ap?Hd^1D8ks#mz_u!pzWv~eAQyKtxV`BJs`ybbuGcXX4J}gGc(!u}+*8CT+ zh6+fYM7v_+Cj1sqv9bYOYHY0p7LkKxFYt`1qgMmYP|#3OkSri4s!Pz67d;?zoc~Sp zMfG1*^?DIpyRh8sC4c7+-amR1S9L09Kf+Yk9k_VkOE_mXGN!p7ar$8IzXDX=5c}Z| zc(#(J?D$fqf+@N6WlbYM8wmsTrhX_Po>bp>m@X4>&qv_e_Mji_4^r7mSHxOt&Pq8dujE=ug8HlYoYDHZ7;Lr zf4gaOlt1v=TQDF0#?t8MubWF|9N#Dm{yN6fhwn$eQ1>UNC*@*mqP8WeaaXoQt)3tA zh}%eVs(4E1^}N;_eZY*?elhM=KJZR>&_B)R1hdtC$JG)oJZ~9T53;f&=t`}6z)I+D zC{(dUC$g;y*}FL%VVC2;R~ z;db{n&$Q4&o%fkUw_CE1Kj#VCtz4__t7v}(WXD+9`yp}ew< z;A=2y;l#4%t##t2x0Tr{$?irRr%YGdHfVDkeVqYI7Tmfi<`=TWdAX5`={lM7$s_=S%228sT-UO$(65f_G=^+vy$Me!r**tRb={Ny_&L5r}oA?Z&nKZ z1AnropBBvQ6^wm3x@RO<&tvMJm692)liaO>C6*Mpb$POW*qx<|tXWQlT!@{1+GbDG zRzkJBhSA;*SF(3==CHTG4QTK9D)3Mywl;n*G&(Du&DHyA3FYt)`&@#jz$ZR?VsJOn z>8!FSY_>eq(4K`uudQB&>VKHEp27+yI@#6nlx%n4g{0aOy{36&)mt*oV5P)AyPf7N z@@<V>jWpcM@nUC)*u12goX!@s@<9OAsf^_op zRnC@#8S*TAI1JHtiQkcl;gReXJQ>(zeAwd3x@(qPTseYYGM8|IH_IQ|og|nRkaV_# z9rlS+Hh@Z?1Q9bL-WRYnFS zkB)nCvzjAN`_Tpeo5C0KfVp6pT+6|pEejl_!9K{j&s;M*W+w>1E0g|$wr>D)C!vE` z#!~>_Lw4>paBiprH*t2N{W}hP^U$!I^dh%bxmn5c1w^^sc~b<=`Q>ysV4sIvmGcDN zZ)*sXpuNO*Il9^2TKye3g4@tD$UQE%u2PBQ9+O-78&$d*{P6K@s_W5145nq}k2T@g z(`ETSk}PCfRo#sTnr&97`sDcqX$K*#!>N*Zewnpjl2>X-a(m~C- z#w(n%4L?#T`VfUJky^?ir%wn{%@;Ui3U3il zUkFplMQx-(NytK->Mnj8vJ|XEIn;uw-MT+$xP)V)zh2i!==KB|Z=iI3HQG0p4wdFl z`yI`b1K&W(Hu@{49JVgox<17LADPkl<;No39-S6_4fd91yAsmJZ6RqwN@i0K==!7> z-9fIM<&lFUz#J79S}V4WTzbzFIuJ)35LMzUu}M>SvHtwM%GJ!7+hgsi`YP-^D~~l} z@-pZ);H=pW!%y_Qxmr%fxs%8|_O}Y9Bg3>)Pc)`2;n}H+w|4OH>Sx{^l8s(i{n-N7 zx@o(85E-}6z6|&|N5WR7(E6&PR@VV!-eqJ-J1q{)_)ZW8?krUHfHk~Oq3z~JHb95Z zLc*g!`y}C3Lfk%-IT_*rkL(${J)hAhm;BylwXBVESr}Szy;%5=DW5Jk%crvC^8)bk zN=4*3qeax}t>=d;lwJ4S8C_EnDQJZycBtbaqTTBJ!DQicMR9MCKlW>fAh2Y&q8^!# z#}PrB!Kc95U|9;%b}wEPvN^HlXL+k9uQhFGmZ1yBt)bl(f(J@AJxEWo|F=NWaPJ$Tc@D5o2@>G)BD< zfvhWfKvxaLBe`-T|V4UNZ5v-)hR)7fL>QcWc2x3WHo) z;4OUw+Ut>Pn1!v%*va~b`o;!-x?qOd->%cyB@!BP?ACx>0#-;h)v|AM^5j~0NaAS#p zRADrc+pJ9_K}K^uW@MU3(M_(>L3J304f8P>o5KzN3_y&GSmDp;=B>Al4SEP|YGAhh zP?hBNUCp~qy@F`jyu^aT3rB)VA&HpVN0X4~T$rQ7-7gQa@%XtDO+ zcAAy!NDQ)xND#AlBO@7=o5=K-#FO(%Ac`c9q6-z9&5>PMyxJ$}@n&7&N#GdnV-ALo zM*?Dpn!r%{M&l}sRm<{7m=!j06*5SvH!!U9px~n-w}Doj_x;i(^;J@_gHBFne+HbN zlffm;9|X)z?T<=7Wr{hgKUXrAxE0t`5~642g>EHR$#xpb&-g@kIH`g&1quyRzZ z(Mm+ARti;oZDddj_go=ep)g+nH{-^8p@19M_yY!HjPeX;7e;dFw92|_%3AH~fb4Tn z&og%yI>b3Hhb^)6sd8V1^#nF>)#k43)j1Myf=F@h9*hD`V5DJL*0NH!b5dLyj8vkr zinZ@pPQjL%cXMwTi~GJ`(gX-KRNdB;HyLMoJOK7`cVh zSt(!)(Yp}nI`&N-v4mk27%_&JogmD?(9`YvB1``gXeIb(5)3Comu(KoFab%cyHa;i zwO?FJOuQvLdf+$dk3|cVpcB^zS87}Q^gULoC0p6vEYsHh zAJ8-L`mpprwk7kGy&>N#hUB(TpZ?!EOQZ|W&69s2( zQNlA`oW_RpY&3(-s{!kwuaThuUe1y<1d1HlPP7Qn63@QI2Np<8sR_>`sc(0+=B;$` z4hcJo74XAlv=7k;3_ng?>JPBmO1{!NdD@PXLEw(U5p8*UT~&!gxnQ5ARXiE=mKFY?ZPdJkYrcpQeU9xNhsQ!bHWqk&wxJOif z$qSKJ zKdApF33d3N$XjMP@d+L2pYOrlEV%uc3jY!R9Ru^9i2WoX|KSjSVGMl_MWySE?l3!R z(IxTqYs-ELo5XWdfE<}*mj_X56g_SFny`ypX@T_KDs#=@`iroB`u{7#V##|CW) zv3|gF9#Nn9+Q_%LDHozPt-Mp*tc%qoS}I(M{)|`_M+cf+|B$i%Y^Y|Td@&eSelo}Q z@~GrTjWAu_#=>ZR604&ryxyZ^l){!v&9Ho(x7}PL9OL0(p0zlpIu(AMHR|D4#PpFc zUyiZ!=)rDcV7;RVs>@MX`RgywlsaqkNcA*v!_ zRK?m$vn{E&YV*8iYMc$DC6me2K5WaAweuUxD)i=R=bJH#>siRv6SzG?>G>GZgFMhv zpAC{UCdy+=;yk`Fi}NTD$7}1NX7q_Ao69XqRs9XG!sX-gyx!Czhvc7CRB3{D!TIBP zql+FYuMo(0rE;_;(e^*bIQG%+50&KTpV#M}{EsYIJhr>*uERgN%s#r{zTD&u8e?}~ zW&pmrdndNppbhi0&1PTcm5z}QWp%$Jww-SU+ck8OEb}n+ABzuB?NGvmfh_fdMkv#O zmq>wS3f{dA`b@^3QKPz99q`7XjRvJ>knL`kx56U3La&Pz%kQlLb6U)yFg?X8|9*<; zVc(%wyc zGx+jZe->O7*_%cx((m|79xEt^JYva?H*A(G>$i{?E;k*odg$*gSg%>0y$na)-q^Ba z^~J;@ozDWEr0RP4Ug;nkhn6B^jctRWsq}+4ZOQ`g$Qx3$OrZ$qO+nb99nlXd~WD1|D7JNspILf%=H*v&m zv+oI_#~eo@`8pjZs4Wi5>IsJy)nwBJbB2|!IYL=>PnJ^4l;{X7mH;>c?+B|V`?NFC z&Z>8m#AG+qRYfMqcc;ieaa*vuamr$+Myn*nyJnz}8&$hX>$MiLk`b+{;1Zh)Vs+HQ z7FsQo)B|c2Xnnb%98c`~i=}}%f}MH_k_xiYt5mx-md%jOry;T#v=?(R+rh^A$M!Tt zs_l1}LaFQL0=h;Eu$ZUwh0Et$Kv;XF6h?(tIOP_H2A{p+cDB^lm{~CbLE)Qfy}I`v zGXz|B$cFDAtyMuXfa*dsU#k=p)@L6(;y$T?#lY_;t3)SQ+GjE!C<;C+B8zPigMG>DYx#oO%-+v=M2@??iro;ri~%#Zg5BwuZc985e+%wk}G zY>&zh%e?Fjt-(Cj=$G%D*a)wX6x%)pF6f=`I4XjJ3q? z;qn%@OAepY$S(rflPeR^a~4?~zLz9t?9o&?^#jo)XC=Vvxro7Xnv>z&-7VJHBYBcTN_CYB>DH|XlD;icI?)#l$`b-E zm?dKqkQBl^e1-ma_^#NeVTMAJ#;yiwyR=G?lzQ$Exl%xVD-~YdR@6t*RUCwu$@166V@1A$P z{*M1IdxvWzk+zM9&Fp_yEvcWN{ft(h2dFZ8>}?EWNPZdh)Y>U2Su4^UI+W2vaGRi9 z9P!;Bb1?imo8`EuC{=P9$bN}Z!~LZs`dJ}l?0G`6Dg~^nPtQhZ4pcJPKhxHeC;8se z@Q}^UNwfNLbLN?f^{MBPU7fuoM|Pw_TQ1lL8jTzdU4|*=7u~~0FQnJtscn|5 zpUP71Kr2zO3sg`oSwobB`tsq_f{$rv^n2>+EO`R~zG4<8WXlO5tZ(nopGb{4kzTGl z?fU_auyXuzYT@MxGFfZhGW2ewloa(10i9L+(44=!pUbMdwiUslBSCi*3wLxmaptWB zN6D_D$wGhs-2koPlRC~3d&L>r{i@mq!svWcjp@w@aAHPBk`eI$!eLIv!MsnmUQ=8` zorh73Cb#ZNvn0_@M{3H|gWJ%*6O3e`YscAu;Sm}_JB>5(<_MAaRgH%0g;3P~XNN9A zsBl|;qK2l9-n*!$Ei*4_m7TDQ?+WIzsM|FSV>gA|I9j2oy^X~s_VmU8K3^E{7ENvH z4NoEnj63p6GS-byOg2bas_3~1h>o@s&PjB9`A4q9_#JXX_jH(Kg`+qbOEywH&zxap zB`hhiM^Mm4@s_f^uAa!!lfRudUE@;LO)^<$-#J9XP*H|L2z&#lr~(O>s2c2>M?aE zxef^^Eeh?&Av#QRk{u@j^{6|e1O}nB*}f(4N$L7KdkTt@d&;_U%G$rB#fr(Y_$0l& zujbB0$uGIW1npK!3>hSK{Cs7XbshHBQi&!*vykX@ph&zZiEFtgHBPNq(jG?`j@5P% zp7>9+3zeN;AhkS*5BU>ssFJ0on7VpJ7H*Y5qv6U`{S!r}M6L9@z_!p|-Oj(lTspg* zI1p~=_kYLaCC$lDEu5jsQSR%sA$Jg4VeK0V``)IQEVI z%G*Mqz2u__^aY_hnml_#AOjyEHUCx@i2sZ)^i0D2UKiPg{)J&?tm|-;#}`xfd(bJwvT1ESqEbEfK_^}$G5>!!(>TN9aU7MhCuMeIsj(|GjX-owRTEv2L1hGS+c80<0z4)%JrO*r z(?mvTEI{xl;WeKggsVMN)JEVHU(-UX73a?{ zPW=mn8)h9gPv$u=6X5gusPI7urpY+`KEQRuxp6S&50eJ2KX$SWql})XNGRy;9LF zg>&AO5tQC^vjgIc$5utn@(F+7s>xs-2(0bBS;{#Z1`(BS3ykSzn! zc>N^3z(X12+A(-E&oAK^2=pvPE^CA6K5)c@C-3mRzl)FT4KR!$n@1l;Wa)KeDAd{{ zoP2;wG3rWvtP(QfjI^_)+#M$34&`)n2TL}N=M0hMDs4;U-mIan1&M3=E?-mHsl&#@ zxhSztYk@qTN-VgkGnN8ONY%=B+$UC~>>XtSShWkzs!xNRVLb8v11fd6)lzxX$4Qnu zNqLdFT-QFqx=#_gCIhf&EN-$d3l(^iS9Nf$Rgo<6))Dtp#D0II_r#QUq9){fVW;TD zQZN~r5>`V2CKB&MMaMYuywT6<7z15;Hk{*-FO`J?*|v^zR8H(Lu1v^!;0#MgCT3Iq z?IukD(+!X9HZ7kYT%bp0YCK?nnd{3|kG1mbW9?O`9>X6299-_~hFnhAKgu$SCt z0>bXU02l<(G$T(nBMk6_J;s|upOoFa;S0Ivv+<}Z@$8YqsUcrX@jSL7QQ~I4hP09v zcHp?Rs`-Yc>rUg(nnqhHLc*V>4IK=xLuEQUA?{drQ7aCCvmwqVpJzyXVAfj-BY&4h zvf4t~S;oaPcGEO5JmYFS<5g1%Jf>)*>`%CmJW%Tj%B!(x^mJun#4V~j7UZa36^k#8 zO%YHu%@&YR;yBTzR8c-Nu)PP0T4KOEe=Mr^n1hA+9{wPYG5h6N9WebwVhpjx%yI9d zk}f@vTf6z@h$?4NU~Ef` z8a}Ls=?4)Vo|#+=B^-a~rAE^l_DOTz_QS%y{Il!G(`!DvTi6zOi2nM+!cpx-;}GY> zOC*fQ;_mH?O4m%THIk1j{@9l`#EqM*Nx?!gDDk<_HjHWZDs|GTP+8=17u;n(Hf1^I zixyOi9o}YVL|kH17dmDx59aZ+WzpP@jB}62D$DSlmO>rSmq&ZWSs#@O9B?iZu+%$r zcz5$R8>#6F>bGebbYX^>(9Dqj@llnDY-%UUTd;Om6tbd#q92%EK?dv9-agr3_LF8-Pa+Kar+Efak~6LeaC->5-Nvq((ZOe zA}T2y2lqo{O3)*FaOORJ92IyaR2HUr6O=X3gObYG^E|OjsU;m@iu_S2m1ZdYT8~iL z%xfVJixJ_A9Nf{>M!_*3;Pz)UQp|@9%|E{?@Ztub6Kgs{s|w++nc6z!CKLv;qrbBz z8T}C7-H;6=P~k}0#>K5}OpoJQRtzk}qHNM2cv_O;;>R_iIkOgXo2sfKn< z#XFZ#+v;E(nBq@!C8Rm&)tL=DzDJbALXQrmqHGO?gJKC|1e+qr-7uCY^t2|$9<5MT z{F#f=NiK+`2I~fa-+V40+7pJt$iUf`1h)=@SXmbtQuE<7rr+DYmm^x76^&5E~14Uw9` zp^0i737M`E5t)yB@y`_0Mb8H3{;N7~Pv~^4$;TnQL~k~5a7cv#970DvFV9DF7x*znk6h@c?qd3knBcVc?Kp=BwiczMdo66Lvr6~; z>7{($UH4n1usj;T(>CP%@}=iTb6A3QWqM1H-;z!iwS zDD@h(t*_J%TK1Y|)*XTT!kGh$i4SUWh*IEfG;fWGYf`9@Muk^Q3 zg-nV+e#+_lLFfwBkwI% zrX5}a@q6WXGENOsULg%+uEk>!1t*vCtz`-lx`$)NGEqQ!g%k%@sU2cEN*nkCRUYA< zJ;L^IkDPsfxOHY%h|{CNGv`QwsLnEbj5~J4bZ~jIw@{Tv$HyyM(66!zev&U#^rqa~ zv1(71^rJ4ho|(@NSSD7(H{8R*JiXSX9)TjXUa^_O3Yh$iDAM$*Po?BDAjRA|yI5}u zr5~T=A+O4itwuu0@dSl72MngZ=NcYy*Dcnq?+n7sH3hVj6Ug!Nkf*J4ZvQsr^mqAy z@Ij6DeB&lSE$W9nH`|EcZEoqHy&P6z`TPi?Fcs0?Os?MPpub_9zPx|TCjHo^{Lo*b zErudWx1OcxLa@eQj8E;oAj0#51-wV2F0iolUy86~0tHV9*^@dZ4Z)wWZ5KJlfyKFY zhjKwpk0@Hyvn(?x0t0}2&_7q660t~gwSLen{~6CyVS{tmS6~a>d8pG%;50`Etzo&a zNpD)T6&eevq%dYJX%ZIqJF=_>OOB<)KfW@VYqs0Vew`@BW}t_7Pg*?V)p(iQ*6 zE}jNL^0haU{jV~!&Y?O&W_rZ8S$YWwJ9EGt@(H>ubNx<8f?;t9ANGAdL{se5X}N|liF{Z z+q&YII}W4*6-XJdSaCGv;E|dZ45gE$63N|@goBBgDW-4~sYVFLoPHr_Y(gFFZx>!S zGzhg`uI=}-tVU~#&kTG?vBhIlswVO*6@aQEFzs0=-~21C@*Atf&gyNd!oziHjDkjS zdyIIP!Np;!2qWp$vN|PJ^8(cEOSmw{KT1b6+IdT(zrx=JR!OPuEh1p|KYI#qed+6L zmwnPEoljJIf!Np$K}H8)jN(xH6nOi>p>MF_=GY*QC}=;Gyj(#k%;`h|s;H5ZDvXX; z!qs9PI0gn>F)1YCE~=6i#w?#*IRj&wN!YyGG|P)PkKgbRT+*M7c3x_JEO>692jN-6 zcqvis@Jo2WD-){{>lw>P1%}cyde)L@y_TfH-(mvX+Rr?3bl>4q5@g~!Pi%?+)RS%} z6AJh$+n@*|N4s+J@%|j4gdI1fXX%p=z#Q|4;(*{|V_q%03Jv;7Etu4A1@S@`UD3pL zBQ2a%k&zvv^zDYBD`#?XgDX$84=^N$g?@OxVqabr_JxE*}dj#VDcHh>hGy0pL9fykiyKj z*hF@yg)ucH+O2YiCgD!&;oE2CN}iNk_DgCtuMUJ}kXI4c=)t0~U2@(RHTblrXs@a2*;kzK`}+3)r!O>Q4pLqg+@luFJ7Vv9gw8jWMeupvk3e z`NaFc*!e8ZzXGcJujR%Opm^owJ-#n5W#CVbzx1V*m<=r2I9V&j*@|OLY}BfWq+Fdx zk1jW`z;wp=@M<{;Q(HG(`17|vHdgMJG2*x#WU=C_QbMeRcz?+`@({%jUMO6;@!sC~rGJV#f_m_6TV7pyS=EgpCFcBPTTi|vMz#=9$*TgW*ulDiIFS&$pb0g214Nf7B~ zR%aY>W+4oB09$6aSyo8%c8jh<>zk@c)4#WvQLJYF06Z=!^^DkpK88p6NR0$bM!yILen&jfdxuGoHfp9!mQey%zd(EW3#K(6U@9wZ~R5K zwu91j7>=Wky}g%oE5wUfQ=_fgYnMmnY?;?9ZYIi3!*>mmXyBmXWx z@k9N3y-Z&GtZ- zUZEjG7nek;qmU)k0`g4#7AoLs{0-vvXU0)@?9*#g)sEPwt1)eNF5BxfPWX|~*nOwE zI5IId9P4`(iYR1X+t|rJ3HJ6jgTgMgnR@gM>~!K z?0a!X7fwNo)!4<-m)O{Uah%Qi^{y@Tj9j>)#lC?TCCjR2D!Qg*pl~A68y$6Q#=9?_ zOjNR4SBp9fSfIdiuZ|{g++UrSD~+Q2?60j@OYRwq5tlEGqL9x)2LucLT6|f($FElb zj6KV!75J;`fZc3oZe3W{w!X)8w$#-@n;NLyV(IA$1mHFu6wN%ls}?R}0Iz7~?XK4h{*uw1Tl92{Bm>p#wK{Ue*pdX!CnbEjq0Q~b(CcLZEfFGw({(L0p zv(rxHXms%fY!h0Po%cU*9JEqhrHJ$A@TM1E_?DEmro6 zKw}sDp0acTObKN7BP-5qq#jI$bf>T0k#y+!{dAGd-suuv93${ngye$wBI{Ct11XOy zDMqi_QGZ7nd+6YrPX}b2>4hK!?fGe;O2;&NnIfAN-jT<8PoKJb*75cLv3IuPr?BP_ z@Fz=lR9r8V@}#HPY!F>9;hY?6>YEAV+rTZn%tHrEP?JeTKieo^yj*aa3>7x@!H7#G z7=eSu{9@+DJH9GiQBwD8=4y6r?0o~Ck~=2)pEZr9mIz00;A=j;%1tCQhp!u%ZxMy^r{q2t*#2d-4Q`E|^Y=wGteO$AY%oqx`c4&&0gek1X(}Zlr_2vd^y40@Bbli7!bYq#4I* zo4(ZB56824$Tq|jPjtJ-ou(DhAoo+Gg^3pXNDAf|@!0x&vwIy=GWKs{$tWv}nDdKn ztsZgBCq0$XQ8jqFQO}|KM2>TG$2Z~};3cs~pB6a3%)q(U6bk7O)ehn%v>Mk5_xMDdaeO5&za!maMtPlSXwLtxm!mE+-}R$BRnZBT|Fmc4 zR*b@{MrQ_$jBG5c9yOWEO1?d#&Ov+rkBVCsdrocDRJOZ`j6AT|_}?_9D=-XMN+O{k zAGlD*oE7+GsPM2zfV>de-X*yO8kE}$(WW)%=?kYaQ|b16Lfg4@CBK7(I%*o3bnQx? zQ^;gv|9;z{%SURj>t$bG(GU&vyOJ!*B069r%)#znPYOKF?5@-SVB=@j$xjRQhCyuL zUt+%pymaelC~}T=&-yaLJu{ea@V*DZ_F;2}g}5v&ychBrKfk926bWK|_(fbBV-BuF zJyG;1;cppqdmNJCXWa^HjURMBU6We6Jj1dGW&tfHijx}s!x(%pOKjni)?`+#mgVbL zHl-5HaEV_SQ|T>`{A~an>sh;%UsS68s%3hj7xp3QiGt9~mLz3-)xfH87PF!|+v&eK zoU3^a8j+%KU%+pSg%gT1Br=>05GR9~U-J70Ur$D4k*dG0wJG+V;B3$BAFlt$UL%v5 zvF->cHJL%!j_7u*tu~Uc9@N3)vwwa$xZLZ>&bAl@x7k6H6swCZRKaN*t@856TIH6{ z5aSe-NFJ1jTuAFA_66);Wr zPXnt;y>6W=OSu8L_ur^VPp`%)3&th*h9olVAM-xIGPBcrcE#=67rdd~`lVj{bsEFpKlvS=w)Hk{d z+=UZ24`(ZT$|@!O^QnY&DwhmOd@K|vE>%v+Qss2x!8d#`k8CD|A*O91d|@4;HC9ym+=r z<7&9ha0t6f8D_=i6AvUEjd86VVQ}Wosg4{uV8b}2YmK#0z9!-X0u9M?er?1H8GegE zEFm4woI1)YBHJ6eN=I0>fvgykK>X$j^4M5i>0rh0NUwVpdzJ`J>157dx-xyr>(jo# ztv7E24qCP~{f{PctbLm+P8=|r8V2ONg)PIEoE|B zUh+yJd2=?QL?G3C$7t~w!Xx%KT6H+4Aonel`grK+7^AT?$}UCxVJ03Vgnm|!d(*>p zc9R~d7=*VJs7rW0iABqIFO_wJl}r^$ZbM3ESLLO3j=Z!y9!l?eXgf3McfANpq_2`S z`eWJd)>_3*vaQ;Gs_3@8n3Hx{WTf9;G)Xp1myI0KX=`QxD#O}k8bFHG>sT99K#RZb zFZP+1i2L41!jv2|oKg3{%6L08s6G)Hu9z=2sJ&r#q|sdY=5sS5K)B&m znyry)j$^42oEM+0FptIic*$93vX)y=T`9M4GU2V>2~r0S$ECWhgJ1=1{8pXuLkb~} z#+uVxqo)A0W}$_~c0L>z#QA(syIa64C2z=h&AQm7{6AR7ce80l0-B0x_cP;aZSxG4 zWwHVHu7rNRK%JI0992!e!m(BK6<4lxR##72)+5a6!;Np}H78AkoZny`_jAr$La1$_&)*h4d6HtOX!ivIy`~BD?Z!mb1X=@5 zEW`foNy^Z(R85w(o==N~jy`;#@@TQgq+U<2V6v`JKJVjE`Q?da5SEo@fvvnsIV| z(R_i@v@2}!+i94#xD@S5+dP|VQ?|>#wtU)ETZgysr7e*f+!UPc)78EG+$17MLXc!acuFj8YBhp){f&Phkb2HFvm1!)yYF=XDvN&=o7Y zXKM|Ru`boZDT=$lQYz-aNF68xUdV!0V%p;1YZY-rr3GWvYs$w|s~#fu zU5@smfy3Njq@d{t@MpaUpr?J$lXL#j50>_N4#hGjU{-+bFcRil8f}jMyjz71x{05W z-o&!?b}LaU;gmEZCD|Q>R3T+ zp1%7CI3WDyWE`Sk|NsA*dCwEg@xX+hNu3f-!}PuK<6?zfh_*_6MG8meezSVPU=w!(O%y&&@lxGEg>V##g;s59&L|mOfH+J3|KF>%Zg=AM=o;U? zyoCDkVMzE>-U6iJBb-QN?#dy%ME0QI9~|@^wNsi5VXAS0G4>)pJ+ku0X%JPK8P@BU zE=}GZkHMA+?4Aj`J|EHc6-=;gb5)OY`8U0v-vPjsZOpxA6zrN4B5jinJaxIA#9B5j zSeyN8m`-8TG+TU+!62u#B@T(PpOV&Abq>G$1=rz%BEPs{^M(o zWbA$HNB^^Nj%C>HG0dnpB9HgunN;lY%)4R#YCqt8+NMp1{V@Oa1^;ih7C4yZR9kUp z6n%jEvmgHHefqfOR3i)25B9?k!WV0Hy}#a?Y{Wg|!qmo#ig&6u#J7NK~QKndHFF zoLlJH{8LT#9FXas7uMmCJz!-qX}|kyA&KO6JIAd=Oi1!$2_SBvb`2|TDZ(?{Q@AOU z>29q(w*HpA-;tPQk*$TMo>!Riz*6pQ7R?`>OKXaG^0tgEx;+tuX*?V8b!codqi;v- z6r~8&FUwlBeD>GlnvI29BGG1^SwgzsVeKQE8jaI^hDEECS8zp8r)=M0n`$>AIXj@N zw^j3@lbLaYu^8KzbMLRqRM19qTD41Mz0K@pw@vmPgI7DPJ4#*5Ze?!4qRo~9eqco| z1EBXdzXa6Y=n0-xlS^OWJD-J9K(^IUv%EGOt(9!I7kl$ox$YY2`G|RDaKt#Z4H2dw zHBlOEZ|`Xf``Q;rz96X2U>P1-H{L%V;5$OvUD#^?{7Dm>@p9X?$NH(%PEwE+rd?9B* zW{EMKmnFPH)E1&d`g&FCR?7q5QN7=g(%6-z!!=0Gu@2c3?RdNCE4+`L7$g{tGC-%1 z&hyS>Kb(U8?UUWw?vQ;D=^e^wd|=VEvtd(vk=*$?E^*E)=S*?v&8c@bTgS72u6S7a z3vF1lhk1=XaOy#C-II+0$6St`KvV~LJ8_*kwdJHgJryWWxA7g@_RdyI8=#8X7`Mo* zwYv#^hm2ee4Cg~)L~Alsh14RmLYPOzKxv6p+Ex(xpU}Zog;3U4f85z`E2*5;HGkHJ z(f4g~^n9A`cO?%t%y**Rsv(K23?=VX9dPch{OV-(F_G?T~;;7U>1Tx zUW|FJqeUwi;h}~V16zd>@iIH&vFa34romH zH64_x@M0p1@r}YC(HCRP-6KxnYId_H;}=Y9l5WfE^)0bj z888l;%)}uH&WO#|f&cPl@;1}gN$fMiT zb8MdA2BqDtQ9!+9{(dF)+w4<_Uy%f`L!$I}=YegPV5Bj^XuIR3nex?}cp#I+@f6hI zcCX|e*<}e7SADWNULg|G5aUPLJ^QKb-*mD8_eh+hI=ZH}Ot5S!f4EA1Av#(?@g6Sxqxo-Q!TBDS zU=qyL!g*_)szzbV&pElSz_I2jiwpgFNo~ij>#74=scxZ+uX-<`QJXA&V*WiSPLw*% zeA?eY9;O-fch+It<%xU{8p*sudFuIJaE^amhi*=QShau`_l`uyyjl$0> zjz8D4m>_a^7C2!&bv{Ln=$)q6pq_ov5$F%Fo}S=cQ&o&#H$oHKGJ0RM?M7MjNIR)} zXVL7_wp*Ur!EjRTrERpXxj{%$8=4cG^vec4?nWvxDk+}9fwUyGnh1)VZA4!e3D@*w z?ZN05q6Ntho1Ktq1&-Nz#jHYg(+UXPNPP!QGreH)8CP@1j;CQ!O!J`?tG?h&aK4q1 zamSll#~c%&w8Uw2i~36T)!Ixl3td{5GU0wg-*``ix7fmna(Mwju0UL^9hB~YOK`#D zM8&7%%pL(YM+ut&fHhczOA4uU6gxYfHc_nZddqnFY%Bei^1lLmz=BT$QJ0YfY-jbz z<>Vfh(yW1{EwpCq6(9z{V?Md#IrHT(_VU~deebVuVU@Tw@TP7L3-2dzbumkDV?F}h z8TCLP{kI(`&|Iyl-!ZiRi8eP+DpGp?c~WE(>MH*zWHq`ziE&eG zJ@2k6V9dS`xx-U3^JwxFfI-@OrU0KgvZw6=9(Tp+i6qff`D=yF4%2_iv6reYPR4#v z&c}1gv6@VJ2V*}j)L7Quz~D(5qvaaCPy$YS+%@zv+IAZ*6i%i=e7hE+P>nKFA&0ru z$R-cm?6>8UK|F4(+~#B&lF^Fjh{^n_dxWsX3KE3eF}Jer2@C&a@~~6?{05HbbQG|o zvxigcePKsS4$O5WVMU7{l*o+!miW~kpyT^_+EPlThUz=AYsi6MSN{_*`Z&tbZWUk- zR#~j7?xt>GvJ|>hwfll(L3lg!WA7^6(fqR$KkjKsGvlM~d_Q98j8m}PRO&C>5<2)gmem$z=!P?D38zu`<=kMm)^>W=dlKFem zyP2mKJvnxdSAtq{C%-MkU@aBkAlKb{H2s7$j-;S{(RZ6dVEZE>D_+ht)h*PxusQHF z3?oYp^Jq*uAh_7FsX;-u(yh_>MQ$o(Ce`(3^y>^z|}Gtg%Q#Q|E?+7R?iTr&;BF_wXbz*7%gqmxdol~;JyytUn#s)bmD2o+jX znu=a(ZtJ|~tR7lQDiUj-zkmPlzWbP?RlVmq-gBGI`R4P#1HJRk{66{Lh2N3ikKX+Q zcjyPdL;d*S--pqdgOGu@lY+) zJL2TTA`tjd?)j-STaqXgLLTo%;$rF*^Cf|+(8-nGK5U4bGfHj%KZF85lbkym@0EZ? zW^PThaYAKihbgSyDw;O}kgQPOfjzLH&qzpDfw9!ZyAiOp@6_Kubf_G=#u&Y6gLxlB z2DZ2Z%M@4<2YI8wG+J?cK!@tANB9fV%Cxqg_H&;>TIn8sVgRr#S)_LePJ96qff=lK z!d?q80{|!>CVWL>v>TKaC$s?2?1-QqIJ>L@BX8Vv%AmW|c31Ti?K*G?@(C03a0&g~ z0)O{^4zWCTz`eSAV1Eqjlbu(67=XC5=6;??A?xAk{pL(>mRZOJyku14M=mKd$IrNP zK^$d1Sh&PX+*u0`O`rv?jGWKUHfupV==NHJ+qxt&=y|i-&>rR@a%)MZK71^5L0eN1 znh34>Q{1dsHx6iqDvWvrY8_jYSxq<<_VR`-lbl zYCzUiA*<{|-w;3iVg95Noy{WxS9cP{FWyMY6u-;QoS}V=p_wvTVjO{`4v2owFpbig6_Uh5;E&;z+{)eKEx3hx^@8#MG@g zl)?W3OyXnm!FB{Y&;yvloJ$zsDdEl~Mi@WNfy^)FJR^v=!#J83XAuym=laYD+F0U6 zv^bkzQGqX6oJkDWQwsZF|KLp=MZy0b2Kv33#A9B-n_Wr7@<4~L^;i-xs1-dXOhOyj z@`$vNq?p%&*_%Dkq>5P5XkP_sbgM-YR4XlIK-JV?HvSMsc1uNT3B-RZ;j<66|of^Cgp)UGA>TbvM!Rsa?A21B9uO;AMr$8GU9=)3sdL^MY)f#3M`Ph=N=BG zURaW$dl#x_)V*Fs`QzuPCY!d^FmTz!kq2S`_{kqAhFOva-)rcW=r}n3#to+Bv64K=5CR*S4_ib{s01x_#n7qM9nu(dNv>l zL?o;bOgR_LH-We+n)XEeK;+pX4uWzfAduOX&2+8hefC5S@n7NtNDy!FB#D+kPSv6NEe4wc{3;G3~zik1#E zK>)hdHaTn@KUnvz8?gXRDCez2+F@ z5f|Jd)0{VSDlj+r|A&NC4A2abl0(cM*GoiD0OMu;iwV?6RS<+)%=#BXe(ys27l%8k zoAHE+X*}dO_)N&e0V*&^aHNHtaY!UB0A9t0`EK&6iI3SVYMr1PML)ytu&t#*+y&-!^`!i;o4qUdfRzLjLCj4;(lw0NOb|mXt{d zfC4xmk^_Rk5_XfQ={|pr0n&Y+;pl`p5rR`{jPH|vr8+RCPz}HIbYFx@OH_Tpp}SaX z-XK#g?@c-%B4FFtkEQrC!%!g9K-_NZa9~qxH1XlkAXB6od4p5H3U=Di-x)HXTea5Z z$CV(6fvpZJLbW6zZGR!XYX{e%F>9SAVJh{t3cI=T@qVXw5{PayW>f1piCK&#!tq{M ziD>?gDUgLlflKbPNNZ%pla2t(oYu&VD+1CMp3(J-NLr3ZY!s5hiMx;JV}6v~$L_eP zyN*~J0@+4lrGXK*&U8Vbx20=EI7qZe7O_$fX{|0yc(&%yna${OR7y8+n8V-xbf0iA9IQldLaz2K|!BX-uzXCyiUl}SLt-JL!6RZo}%pg$kIPcA%3SF4u?pndc!K-31sb)vM zZzQ$DT|}rYc>>oB!V`w@Yw^f6_@f9isB7}eUgSLA7QWQE_-F6R>xv#)<36f8T#^pQ zqQr>txYxx&(lAhQaK1Vl={6v&x4s0w94UOcI?H9%#u&|CR~SrG4SZov0m~UZdW4P? z5P`RPo^g&6e^JA7x9KV`3K*BQ+1AQdu}ZrV*G;)HxWW&8WVs^);&zML)hPS(!mk~m;3sSKD6>6cj`-Jn%?DL~Oiee&LY$*zj8Us!652(BOF z7q6D_m6GMw!v0Sn*k428D}~vmf%xGB!P7U&SBrs#^2WmE)V-QLs(5JD5OC^XUKVl& zAn*JmVgvpm#1s5pq@g*qI5L%E#S^aK<@(BOtIPTS6DIVwH5KMRc1UcCy!I0v9%kry zL)r9i(BG8=VSvtAI(lLnR*7ZbNcd^x|5;*uJTXGRSItL>pd+kMLwpG2FyEH^vQGkf z{6H735U`Pe1AG8Kw_|=;eio?Y$^xcR?mRNd=Pvxw^?nh`=y3xp-4-kldSv!lnB{?e zHBACi@26RQnpush_r({RitU9lxD?KKz;rIq%NXb$UYdXF4v(m)0F3|E6+#I+cM2!J z>A2?>A@2j^=M1S+3kK!skUC?d`Nbmj5sj)hEWutpE@;$-Xu<%cnm!yc64=ZON*H48 z*3BMyS1t&UH0AY)Y2#o*BG1zqdpF~X9&PW6_A2#KG}`o|O_oUG!t?F#X8JGm_B04= z3WU4KfX5GBG&aQy1Np!Nxh&hb$MBQnz}MRH-(*nKg-p^{1qgq^fA!~$+-KR5eGs%P zHKEdlz|0R0dCi1!GR(}W<&fZ)4LTf5Zio|C`o0jvg%wLETk3dpfs8R5>TDetApLk1 zi*+ba>UiBWB0F+kzk2X-?a)nCH4qEYj)ge69e~z(^FndHom4B!ak%5~OVP=*=a1e7 zd>vPIz#S=lPu;0<@4QJG+N03mby1If-hD{M)gCYcU18Aiq+qA5s08=v%|qj*4!@4~ zM{xH?fM_EFuFj8$q&mLod%TpU@KW=IvAJ=>`kZP#_&{@{+#fZ3ab35_s|GN8* z@(5cYiPVF4$j;h_71rqL{DDN-BWyp&v>}6}Ksr-+IC?gydho1y;+LHM@}uU2jd^}K z6bR+&-FOkuzR&0^7Y9HOsrfshV&9$U_y3Nu;IYlwi?$s4JFJ_yP#{)A_a!jK)p(*wWpP=G zMq}U|*bEzld(h>Is>fE;0&b`?_89)A9sevjOWZzX#{yUIw-Q$zNl}I+c0x+)^AN7_ zDrd;=bTG$t9$X%#=DL0$?rV;2FS()2fbO2xiaV#Y;D+h{YLbzR_KbV@U-W_zAO8!a z;lKR_>~@6+ca}V=7l^_+iw`iap~joM!UfSJr9K0=piQ!Tq0t+@(9o|xP!V**jrO71 zQ4S1CdDNXN_w5nxpYxQ3m{{p%=p7H1O5S#gZ&*5r%FsQ=%4~;44*Uv=@l-1v=mH-Z zkoVDM2@c@X`8oBa=eE9x1<~GzI)N9brn6U&d|VCjh3Fz}(RM-cBYYfcn-Bcqai$_M zT|RQXd3V~v^gfH8A(Gykh$(K1fC+6AbUvRTc{3t0#_)Q<@l@!;<*4w(iJEhDIVs9_ z*Bhy+fyIokgAJp)#9qI;ls8-E0KEVYzEBI%0NDr!U>F^u9yVc4@(kOTC+2>aV4dL- zVd;4B-K~SS1$y`KOEJ*eINf{Z%a6VC_5Z(tqk^chktS)QW|1nB5V4;Dn1$IqPchoE z=`1XWqz4X}a2FAy-4_nt2(*xEwl=5ZA*5l*s5lZybcOGRJaYhH!2i-rloCuR3nat9 z9(bwxK*K5mfxe?e=$bYLwa|~5lT4_!crKbOy2Wm{0C5JU7K9>1dD;8d=-b;Wye_4= zkfFmUl7s^?ExXx*eMc$99n3q53@(J))PA3PoEj^kL4N$C(E;%I{Rim60z9nI^ps5g zbHd3lGH1^F#!UU6yeXd@Y$=^dy(6T2Py(e9c0D&^jyNR`UFC(lDhfPGXDr-tf-Q&x* zOpQn3Ug{>Z3sGh8)O^h;afZFD!e>ydFMXas*4J=RjD|_IGe>T?OP{)d^Fr`CQkp}H z3vPl2K5>Bg-46SCRVnYZG$W=igkzB3j(}SiKr~Q_>mKXy^D*JSgir-%b(0Py1BhPH z)PV68>#~ExTL~0mIwQkJ!}Rl?(Az_)E!MQU-{OuU2e(kCiyjn8@u!{c7ljh)F8QFx zmL9o&fOu8qJ_5+vuOL!$E9pYzSlXwCtO++_s!jZr76nLdsGl-LqLUdaz=#?$LU!*X zWD?plp(~?1o(+#=c)8%|aiTjQ#E+(Us7|g8|M-i-Wi!4z_k2>_?eE7?4!Yw%?6LI9 zC~OxQg}s@kCJe6lvrCKRmn($CMKZ4fz}Z&#yI~xwIvL3xz`0uZB^FyUzAlOxU{+KK zggfJ@^G3pU^c7%jHR`IrR{57KW)!C3ZsUkKT_K4zfy%XCi%3>XM-aZ5<&OXP$xOZC zYhX;%p?O|q)rmkDf*Fr^AH{d|+|0iC7k<*v7kpF$4w-ln4W*+p9lyn^y5#MBn##FA4ViAh|-h1>mEK61`94G4MhPQeQmn?PHgd=C= z0!R0A#~p?D&HaIW7^rv372i(Xf{)tW^WW)~45U79JT>>~^GApA)I4$pWH)Wg6<&#^ zv_giXo>@YGZ!_oTzbUsHgNW9e z900L-=gedz8Y4;34sLlB9@$}lI)>g1RgGr~G#PlC(?b9jF`&FB^bUK=bAdeQ zq%oNt6ow;>b*7fnLTRA@vmpy?(7vq1DnOxMP2h94^?*D^7(mESKZ!s%T4@Ol1TKm~ zLFJq@*t;)yH~z?9+SM17mzI(mHD+O%f%KT&Gbv-FFDV5ygkBdcRAhovaBdg>NZ8t^ z&1GX7C8N2WkXq&z#?;o2uowKqf(nG?lH|434Za94P)DJv%G*UnI_2*BLhu*w!F84Q z>>lhdQXTj;*YEC^sk3`caJr6IN5L{pVTiG{F-rxW0iQaK$DkeZdzLA)(otP+&^*9$ zZ+Xx8pRAp1n75~r2K%@KP26X!uY;7-Dl-W_e8vVH!t>q-FCs8;E=BHNK_>uU4R-srnFF`nUJPJ4#umH z9gSU?{)T?&?0>ZP1_L3sJXfc|mNDTvtC1U1Rshq8SQm(&9bPi+kuGx0q6 zf%!{hS=a_O7#6+Q#k|)G>hl#=G}zft(9D-X^f)e{z{_l!78+HuIxCm&&VMs}@0OY_ zjJXvyxK^s|$Lmq=qcT1mBGN zr66GWyrQOiSO)`KRT|>hw+TM(JM`T?R()Qk4Ennl!#=JP+g5#Eq_gVM?@X!u8p5ue zmIpWb?t}3{Ku_2B%66kSFl}3BWl)=Dl_@B&7}J25wd=t3$64A9==0n#*h9A+YW{+t`vQaCBj^+# zw9mBh;v_NBn!}YFd2S35Q^?sJbNMvJ%z|oxI^I@e^2T!U7JsK5Z)3oA>rqiZtAgYhDl?U&api``>6Y@kI2SBZN`d0aF}zqSjZKf z%Uv&lTTvzJEV}K(5rmwzx3B9l5)~gXk>fgi7g%eoRaK2X7yu&y#t4x24iErgJz(5m zNv0fPs+I$Os%x&+oJt}U>UG2l{X0$eF z`cK6TQen~N*z=#fwOaDcY}3D=zgLK`)}V6W&=b;8>ZyT#U*fMuIx3INruQnnVRCCz z(ktTVyJ-u0{;Q!){Rc@u26W8Rjo=-=?U2Cj2+qdY8a>Cm&M!?NqDbIx8e!VhIag6K z;f1q~_zyTr=_~funbflKjSXTtPvvfui&kuUtJUaeS-sKTasbhm*MzXNKL;S`U)6u| zXz#X_T#a03B35IOD$Hx(Z7zYYJOJp=yZISkTuk76nmgU6$jbKPM;0pLIR;T+n+Cz& z0FHl)0WV^Id`nEP$#gW1P!ldBrjj`JFTLP^5XfLzhuwC zZ9yQ~fK-f}7lxLMso!PCB&2#<;)j+{A?>KYLC}vwt(CCC0ZD>^y2AX0ArOf~{5&-QH@PA=mOv52& zJbUhnP3VI5x*qj)Va;Z;(m2ka+0E-MFN&HFv`p_#2YJdNIHULsNR9>$c;+K+6C-y8 zBQ98zsp&D-^n?0a?c{V|$kOQ{aMsLeG(&ygWNf!tgrsy{XddXK7TSg}BiB+9VL~{C z#Nvu8?|hKh|1>z3Ns2fVvimv?=dlv({j8Am4lGbv?j$(3w%IGvIW2!xen^6v0-yIUo=u167ENK zFo4n0n|c8W?=i6$PiVqf2W|X|s6o>@TC&0zK^^Aobv?TE%iQgno5K`;_tHiEaK-j( zOCH_BsQKvgLVIrRk4Sr-*sz?`hyEQsggx>h6Omkpe77T^S}ecevN6wRO8stmZbhQk zpxSQxXC-71HLohV8ovEHmSy!Rd8?U2ebJ-6s+ z`jq#A8o0n)^eu8W#suHfXhtJV)_EehaxpH2pGJ=G8XxY1rKHMfoqSH!51s8M0BH6lgv(XPclTczliMDX^2t{hLV^rfbuaF7J+W>lq_bDq z703=2X-FHLA%LFB?HqI??`ipbhFrI_1@UZ)0WjTg_7&!eZS(s>tjoVtVw(qUkRqFjKe;T5T1jFO zd68AWCTw8X@?PlfUg-H{jcHnZ8OG(;Qp;#H4Lak!2j~KVhWk;&eWabdqe<2Up~}qReAmvJqE(*pOXg-!i#?FC0;Ol|}i<3&@2fkC-fa%IvtJ z>+Y0^iY^8ml(FuP?%9$hYt9w>Bv=VLcr^(raU0`y;E#$Q4pXKz^DaySrqg&QPD*D& zoD@`^AC@YUl4VHm*)pWfdm^bN_X4R3r_yt;(el-Eu9^#-dw(ok>&0#rbFP@Kb?-vm zd?#&`u1ku(9CWETp=TJnaf$RJ9Co=WT9x5yKOtjyH|ys!jwlb$&pB&7q-=bGK!Q9! zR^m2=17_8}pZq}b;s+Txo&4)|uBlgGf@p*eE^=mil3IFyPQ);LjtB}CH3A0{IKVkn z(lMTOJr{xl=bHt~xt^q=nxu5q!+Kk=wuDFvhMsmDC&Li9iNl(X@A@BVR ze#|5~26b{?0AXBNa#-nN#sOZ(>@nMg zoL}=X-g{6?V~rc|q^64~8u%g+8-%NlSHSUK9u)5hYeheM;Ye&akFUFkn;O? zM@T-xWA>nI3Ze$w+It~%CKcE?Zt2U0#4;lW#M;r)Ha&iM+hg)_)6}QX0361ufz0!^ z&1dOX=Us;(jqAMtv&wP0w?s)d{|7ob1aWGtSJk6Z<2M%`nX}&M@yl zj>|H|oYdUd+vglNE+=6`eH&Tw<)ThGo}U{`&Xn>nn$9p~oFOK2CJ&osIMQo1oSYhG zGn&ve%&=rBJ%Q6?muWIdnRX=24}l*zzKKVr?aQS=n-M;HcSNFa?aeAmK84U&HcRsr*n@z(EFJ@6ObMlpQUnn z^s48!&I*_&sShg8%z{!CDK$evNv7(eG39)Hj}v9sx$T^IB9{LkDA@VO1sl>hD$gAk zj=gdT=%PO~R2ZGUhbF>M9ML)#kO zG_%;+x($ZMrKrUN=D}~zo~5yE*O@DdC`$;DOm{fp&|6F&JwU6^Z5*FVO6|&s3}BbR zGl@SSrrr#fKlYZ!{~-eqCQBNMq+k1?G0$Pc41Q_733QM)ctK6-tgrc?^~J>D!{`4r z&N*)&o^)n@pm^L;-es$Hv~KAByLs(TTHJHKL5o@HG2I*uJ*Gm>xNPo>^;TJ{$EV5i zmh&xjEnDeh=0kN&lefg0-1-IiRt_lX7oD0qX?rm70b8UlbCYtOrMi5uC$G=`u5syd z0_QHM=G{*@bskyxHr;uiQeJiRj@ls{b9(lvPEfa9X3YFQorKN(1 z;~*k1!%m&js`*Kdkp*zE8Vu!!6A*Ff_bxOHe$kw#^u>WAD<3k=gON^;jCP2 zF6=s7 zQQ5=8x{36`amh07z6yl@B!AY{|NWAfsd>ZoF2C{6-etV~6Nf6N_>|dGk1{+@PG!qt z3cSper;N-NuFA`r!LM>a;cRozAqYy2_jv1>kTmnV+9_9VPWRlg&_uS<+87o^L*;?AMi3xTIb#05xvx_#9P) z8USy()O;Q3z-F#wF51#IYNoN{pfgs>Q%DLGRJOfM2gm1+q;Tcb1RtDmzr67Z=ph zJn$;G3*IFr@z=W_2D8LLQEXb!(7UB;1y#hR<=R{bCX3S8xHm%B_adJX55uR^nw*m7*Km5yD84AJCxWyVA45Q5=>wPy zul3ztz{As*B|uIU=ZwuyF?R%C4+Y}*@py1Jgg%q<X&9i_+77)pv%0c5Y&XbyIn? zusI{^H=6ILET*i(kQx0yR_RS8j;z|!x@$g_o;5us=5+wF^rx>$q6O)0A%1#!zLo|P zFKA`!VX5us^-=i#&$U-&a5~rR^!^PO{CeA80n&OY=Q>pK8DYY}r<6*V^9Gye{a}Cd zyBH_ANfl}3U{lLTtJRrW)Bf^$(vak2Nd%{rBAthY-_&*&p#Crulkc z;{aVcVawmtiN_7ez{>JHw2Y2Y2M+K#8do3o(kfGt?Xt=d^Nv5?f!4r*4xMl_fxsl6Y*O7ut%4K8csNiM(<1DFPEA}pUg5$91g#QQpTp#;i)Bgt| z;ndYyxXjP6|Ix<2wi6PXP7f$UfXY&s-UEZ*{%>q^+HCQCx=&q$49zv}oHMlbHa&5K z&zhTeOM-9uEWCh}6Y`;XC2obPJ6{+jpg-KK^e#2ok|VJSuUObEmw5gu-^_v7^f5Ji zZ0QD3jWP#hki_fLs+f%ch@B#xY0}n{PO-(UmkQjFivo{CFl*DZ0a=(u0!Ku&Yf7PO zQ^<81j5uLx4;*p%9$H1AY7+$lQW#@-)OugiTw{GD(Dwasl%j(lX=*=k3s%gFn9h0b zt$EXmcm2pq$fF7t=u63?(tJMh=<|#3FpbfD%A@;7-@#G)Fc7vz*eTTVHE{t-pbT0u zIRsX5IiQS}K?Xj;(U_NrLgP18$foO#o=tC66oDqTZ$6L0 zkpTjQqx9?3%@(Nst$JCa)gQ_LpdhK=@IgEITJf5m^ysvWUz6)K3X?^uLYGm&?2$IZxWEj)Ldwksi;$RF_F;3@i%Ny$ zxCk_hs<(B8deSWp`xy7U#v#E&;HtNG`|we|qsM`d{uB+5*IOMHOZZPJhS=!n`w_9j zTOEo@$FMbyFnmY8Izb-)W)nP4$D^Pxyq5235^E9jLZz|NBFjao(qaEBnt#!F|56nC zqs^;_{x2E^AIl)B*X>XpjxI>45%rY;GptK4Aade|rj?hVqE@x>ij}&EPe}ylzN}Q| z>{bcREjr$jYezl|3yJbWdq~WVsZE469yis53S&l(#!m^wqvci#@s36HVz_VeRw;(^ zA7&f1eFF{la4_FrSp^65Uwx=Q=zOXV>);&!gVhdx%kQk`o`Q4rUaE8SUXb7{#V< z|0}faC2@#+1-BIUphEmakm5lU#lM@2@5{sb8X6=qH3M^Ij&JmH-|ok$(5LMMI*;h7 z3xYb0ti;^z*^RHf7Qc$lvlGiTYXa6-l$iO{F669dXukb}GEhH}pnD$v8uOW*ByCn8 zIzO-Bg)PwatcE6=XgjC#`OoX?hS6%ak4Do{7Kps^f{n-S3@?e$jm|i3Yr?uMM(5WW zJ^0bw4H?m+wi-FHqqQ12k)!909^h!#4IG%!*$o_U(cALGzg#8zKR7G13j3(C;OQ~6 z`bN?$Z5JzP`-ahIS|iHxLWu^C!Zdfkv;rbZ5Hm0l-iSrWBpuXItvs+D{KIG|y&phC z>%FBA1=!zJjrP~r3rND+M+wH1Z7O|rFfl@Z7}_K21*hLs<(eB#7}`WDX(m#it<}Sy zbhsRCFpAnljijjBM=NR1^Fq=;)=>IeOOdp_+^d$x(}XsjzU54#9^5fMvNn<%l??^7 z^aj$?)eA^Wp+BT8Fsj;P zi;p(pX@^$QFl{!!oGmdb+F$vBX~*=!(R#L=vf6)Ih?KURLA2ifVbXp9RhZYW^pw*4 z_}6LaDXjUwFnaOtyWaMJ>~$Ax8#1%zc_G`K)%K3f=1g{Mvd=IUtC!A8p6fK|`ZijD zgCwR7fg=nF zH$>yXm}=eCTIq6A07lmf)H&3B!eJUXq<2X&dv{_?*?=Bk35#&*<7{CUCPvJAjET6X z4Yg|3BMT$_i5E^!X$=yH2)k8;e=)1-;V7a+01(D&5FG#+;=={qz(^gDA_6xHP)IuZ zY{?_QhCkxumBBxBkrPeW1VtS)1eyqaJ6kqH#eu6Af^NqSu|iM~gN_oh3;P@pIRVCugO#Tu1HTL1 z{s<3dNN@qvwRLyCWJ`d&xWNGJ1kIa2RK>@F-!2%wqmR@B=IrQ6wS&2;hQa z#|3~S?Idsj@k2RraC5h6NU5gtE*;XICd#qG00VJ?3y@G2WyYZKCESj?@Ii7Tjfx99 zNumUU92hn`2MFYZl323Bkn2I8{OsCo-F{tXIsIJg^ezFryEISkU%%a~GfOA{ue|cWa=A5lumNcKmGeY6fM?e2#~$o< z!;68Tuh`#dku@W2~ZL*!3^Baf7(1Upt=tJ1j=*WUQmh^ttcuv8q}jpQJ~P z=_(5rgzfS?KR2HJ^y((FN5}^Z&Mtyz5ShD5-=XSr---7R(6fYf7^r{t?fL4m zQQwAh9NKs~vuDhocnp|c1DNQ3?H!WgbN;H{o+UM%bq@DnKF}>tfnSSHMD(v9tUIpA zt7Gwnp@O9gb>c)!JuL(a=Bmb?D7rE1fFA1zQ7kx#S%bO$Kx<% zg7&PsOyeW$2Q4;z&24bq_9$>_>c)*l`p0-p%ql!FD8z1I5wi*a@Aza)HMK%`dP?0N z&*F`}S#aMPn;M53yn9+V&nwEQ-QfTaTmW}iq-qDzPdif{Toi7_Fr}|I;aayO7lt8( z95B-;Zp993?8Ja+gXBW-CI0Rh11_YWF_2u*2679KoRC@%etqds&a7kt5KS`aO=yJE zMuY4n42M9r4=p3R^&XQ1QR#j=@JnSn6()WwG@dK`JOy4Wy#~D$T@t(jY)8e`8L<$@ z`8(3KC$ivmTCZusW=($unK|4OTjT<`yxlRWmn&8D-i)~AyTudd-ssMUVREXAtz z-=bWtSLlDPT%JgO^Zhw>8n4Cr(&cKui~HrtdHquV#j5-7QeUXmecs|<>T15{b1qH4 zt1ecn^dM9FTCcwJCCP!hmn&8FHnQZ8;LDSfzn4*}{Rm^U+OKDCE~8cYlx4|xv<%ng zh99^F3HH+Dz7P5vxpI2pp4k6vxgW7F$r2Eern-?riLefW*q!skf_jy2A)DSdLEPXxtASV{TwBAZ+!<=_uL`XzXw*X zt?!Ggc=hlkzOO9KG^P+QUFaJHS=*;h8<$(ERmzUGl&d5<+gP5u7Z+U-Mtt0o0y}&5(IqbL_koy(3MeWHEHqV& zl8Xv0ER_kF?gXYNh)TK_5lm2F0u03)L5akdFI=XowY6rAtD5s>maBGAX%rx7YBgH0 zhM|&g7%j3Npte(QP8Z(V-vKKrk`UUt8BUwOkit#L=i5u~R@?(H8s^H0!_{A_!wHYvQWS4z~kWUMB#a9YI*jREs;!6_- z|7=np%t1E58H9h57Lrh&pldSHovbX$(EQ2lu*xDTGq(IQ212+y%<)9isI(gy-y2|c{PpH2+&cFw$X1_>t&<@;=E@V5WW4s;Z z%+s-mPv09s&gIeJ2WbGw|2ZU>W?OxAX=?O{^Z+)a{254Exth6h!T`Kp4>cs4T+i8u z4|2@CUIE2NCYE*;CdCM5YegnYfYybKjN!N}7;6&fpzyuDSZ+3X;}nqEeJ9#1lzhJI zc*)?_0Xtow^ObY5Dd#|^oxMJFjZn6&^DL`}j-XTU82X^#A-b)q7+4^D0A@cV@UT~_ zdJg`2y=JF%rVsw@w?u0*JQDS~;wWCMP)LaDx`n-pKG}~Kh9zoNuDTn==L~L0T%53= zP%7u?wk7d)W6Mh9B0%hY;o_FVnF4&y{MnYyX06Kv8HmkWxkBrAW*gyq&0vN)5XFZK zVqnKkX1L|Fun^8WlpUNiv(^dDcwdkpXsfQ(=tex&-H>yr1M{Z!(c=~lU%>!m@G>aP zT^A|fiP?ES#|;rC*Gc`ma)%nUWCJP#tIct*JNO(7n*^EM!&TtMLz~hy5D`#F-Qrf1 zH8Tn;!mC~nGxs%b_+@FjH||#n{-EY+%(=S};Pz?`6CfaY{E8jV3_71~RG9Y)OEn(lbbsK;g6H%_LGyp`cbRiQWg?U&?%bNPXo0 z@%w+-`*;HqQAJU$caZ{9fFr+^NA|%r#Cg=({!k_*YT6Hi-)I_mY*fV?m#^YlS@QAA*~S?`&GeduOS*apQQe|`s+9`1wO&k!~i z;4rIt;UDnD2MeX9c#=L~`3BvWy8MQWI&8}rH;)~N9QrxqVU4twZKzt%Qc%zZQ*u9o z9AJn?n4A$=8$}pUq#wEH$1L5A9@9Vd5P?)*pl%2FWjY|vtC!dwuwWu=3*e`bcmUZ0 z4H^^oNaq%-2LXM73t+jz4;6q2(0V*h4u^>!MB$D7)A=iUem7TrFQLyobIJ zP=IA$lz2Fi=m176;SBB3;^oI%H$y_)@HCu0XyNvu!Hb_7TO$LMedG>VTS06sxsCaK z%}BZ8{#a*th zOWjfngOCrE8zTIkLaYkQYD%B%?v3~)EI`GjegBR z;f>U41c^1Iengb0N4*+^d`A;jZYG^Ln&Y?wgkm!%^ggIMP>wRd(`L*_qcGIF;M1q` z-$21+S^9sVcaAyV?&nl!N6~KviBRUo3J1n$2%gO44%Y zXK01XtVfg?KUKEYnhwbekfqDrBHem%>+FP)w~V~?USz1Z7}Kr9i!};&=v@!M8rREwJ(~_OZiAZAy zY6|rvRE%mb!x^YCn%2?i%3)$&2goHF-AO*3Vm3z!)Zss%{WKs}!?7!n6b}T+smeie zAZa&>81PW;H@zOk`4(5Ueqf3Au!#CxGp%ZO zyEiCrTp_`+Lx!=;*9Jr1-FiZV9B+v6Ky?uCvzzy?p_A^+kTzx5(;7RIr`PQ_p-cK{ zg+8@fcj@$zt^6k0IM?l&jP3>}O!+ z+Pw+KNv7}T#s^cRNm*@rDNBWW{%F!6u1+ny>OVRz#ayYro4B{Mip9L^NO-rR)QfsF zV&3kL7WQ_4@o#SjH#7`B+SaEQ_sk7|uPh&oXt$z;yQUZsOXvy$0Q9;~;@R*%lf|=_ zr4nH)LY;A-i)hhn$G(eQKT7w_Q_dZRf8+Hk!!TtL+HH)G=$V*UUm5_CFb%PY`8g9J znX@~Q%<@e0O7g`0|Bi z?tnBUOrLr68>pUD9&27`80{iA_o0jIEEg_pDf!@?a806&+rtf1YG!!ty(&p4*XG#>2SUHlPI3}X6%0_Utj=p4JjyRbZsLiXlP?8T4@>u*?k*IXvVZ^ zQ@)HiSk4z2si12=82V5C=!7*V12&$_TTkz}XJ+A_8N)YD8S&gRxp6e{I0@YHRe+rK zoOG4EVkSMHKYy-ToT2Z&&|Nzi;MVD5#n zo%MJj;sOsZJiBRUbXJ(xXH3e+d4Y{S} zr2CHrqr>tT#E`m4owPMyas};{Vj8SWBB#^K0$whq^XEkK<7fp&zo9v(%z-sW<&dr} zsn9C}#APxsx_3-Bme=Pagz&jaFyPXXud{8F&6OP9uropXpS@j;bN!DtZI5&)KwJ`g zG<)qM^(UkngTE4pc4-&cx}@`DM>pD{HqGoSvqHbwqz|(hseY%-eVT3dksh9rHabUq zeIm_WA|vzV=2Hz?dPH;WBkk|cq(=^s*mZe-zu&**>u-5}dPNoyuY&yJg^m-#x(4_n z-^xwGko-sH=~-k;Q22n zG0juTf4knpZ#B8@hpV%j=&p^m_>ZLqHFVDCm_T<)y?$ZX2A|@ zOCD-U$h0M{XB*Kr2ISFy`=)hZRP)0cK7RB5i*A+`GkjVktoMwKwj^sokXtU0MGC3FC}k7aa|@(`Re>ge!*ZXBC| z9t%!pn0p*)i+-5#-ETC)j+?pQ+P+8dUyTg>)gwwM$<-W?cN>fq>N#ggK|&5{jm6`o z^3y$?LB6Uo!02;hhrTWR9eBKOPG&)%vO}fX_sMqsEnLSLF5aFC3~7IwU2D@zrXiGE z=9uYqHa?8B$4jk<`eg&r`d34lE2EBW`5Ey_=;I}Hc#y1*cg<7F-ed)qS%K2K;4w;? zpZdPlI5lseQ7Q%s??O(}Y)FlKB|Xor_Tg7#(Yq##T_@}yJY+@bJ3#GtPWXfZ~q}! z=y)*uLSHSJLSQdvPI=1k#%`M?}$ZeKynRno{4IQ%ljO=Lk7@%0Pww3@`+LW3uJ- zE|KiM=ic=}=dTad;C;rE$kj)x3a9Sl$o+!G>b za;%lAkF*M?V^tq|9(K;>ZX~0TBz=W zccGJHYN+uUqzPspvQp?PRUbkXQ0>FqYNN~N*(+5a$_)=<8($7t0&BzeUowFnhu+*j zbS%&(v>&hptx7NP3zqXKlu&l~lXx|71gg(+*pZPGEf~`o$jA~TKd=dw0sYGo_+yGd zs}BwtaPRZZ^qcNkvsygkN*0=OV*#sr}78b!~AW6%Py%b-iJD1u+4 z=;>#gQmeM$Ko#xiFIr3dtpxK!?X(nhQy>nwc&=gaIQ(_wgl9WXEYgcg)_ioikk8n4 z0P3X3xt$#K29klK@aWty=5C+!as6OOK-!O^2pCT<)8pQOu_E9D&NT|c!&!2(^_R6H(}(s7Y|)8D4TA zt+Oi9gG)ZvGN3Fnk0HM@Cl4T~`7flu8nS3;VbRC5hB8C@w|om#21T;82iatUDsJ~> zfg;&vnnMs>0B3G+cbUXqOZ2?xO61jE*Zx7mb+s(75DyZlD3cKd&xV&3gX#kIM82F9 zd#HkbumsTFf?|n)I3VBN9&jNZXaq=rLfjkfuZ#o8m=uor0&YWzN9x~cV%4bNR|(w~ zXj2GuUr0I3uCJ-LUx@|)S;n+@0)gPaa4x0viNE0~#5l`*)&b34P5`G0{+%5$^#46gWwGgc_K0l zhyrWUhz|racsHOqGC=?hJp)^v`UG?tj;}y6gR=#cHZ*#gESPfpV9&O_1MSC`sb!pW zf`9>UK{BJlz!GYb8~{O$=~>?QX%b(vR7~jGQ#2j3UOYemU0#Cs3WBqv)HEF~*jOog z3*3)3Ff7$1*c1?lVJLgvBP2RWnY<+o9G9H$HM~Zvo7g)q?3xHs2AF8n)cf<#60z{( z4}Qm6YStLGp`AVB3=l+bVG50iSz+%?YS2hK-*t-gwd9R<#ZaUG(U~oi#rM`-ud5FoAj=)}*^St>Ey87SR^Ea=OG* z^AA>z2xLcnAyvjxmyOQzOi}$HCRko%u?_%PjQB!d)<~>vg$xf6khDBge&{faQC;Q;x8{r#UAvT?}sf5%W)j*%gb>jpXf^y0I2GBg6FyS zmxAzQYtX&CUw)a+QMRSgv>hr4lEDzz#>2UAd%WX!d~W%pTqsWmb{Hs-d%DnUX^n~t zP--jZu6AYX?>XwK#d&Bw%Pa==o-wZO`?!`v^j zHKmoqLEo@Hn6awk2!Ao7!*P8-n5il4Lyeu5;=#`()@g@sP7!22j(SoFBa)X6P!i%Jgf9MUYDI6Njor`$e%cj$u^Vj0i=mmZnOunzhu`y565jy!9 z{(^-)zVLVQYV`wQjQwXn)^vKjeajts^0d$zkcxehK)|mrL1RnZXgRlpUCSMeaz079 z&yYOj8~nMAmyTWE=n#``S(%rCMiIASp10i}+9L0`GIpe#J?z`NA2(j=P%w)#yHGTI;rj`&|KOUIRG!p=*rL zw8j3%;_$a(_a+zlW*-Z}m|r>GH?S|e5FTjRgTwK;K59pyM$Nz64^b}A zb&TwI*(-B0z87}1;P>$uk_>9cLsjl&dgl=40fSJt&8-y6%6+-p7`C9(9s^4Y?UDd@?YUduN-#Q&;f;x z%z^(~?5w!IfDAbKKwLn`TBBaKryR1FdghdM4+FFp-#4&|2oFejBgwYQ0}`tW3=s%s zVYR;CV{U}Imn0%Gpd(pTzz**Zzxv>7HKsw5{n*gOx2{tb!+vaDGwfQ*ct1Ui%IV+Q?RI{o&+0`)CwmcwippTY+qjZXv(r0Z|cX zg6C0wI3h(V)OZ&Vd3wGhU`;vB0@T|V)YJOI>Ez!lr_=BM_oso2nhVD}!za#2N?=~? zi4y>H8Luv{wF52d<3$V+iHP66$Y?nmENX_mJltS#7NOT1K=o{>#PRFL7&LE{O$)Fc z3TZuWX#ZP;9ElY2G&V1?9pr-}u?&P@jv_mFfDhcYihBf1ZF}J_a73NQbrd4Jzv4L7 zk;mAczwQo4BDy=MtF`6S4mbHG9~S&RaB?;&00}TL;+~ zA;>~GQl-DPzF!)PU9g+~uK2TnjuFg6z$gHCn6;yVS;SA+!T5duCIw}BI7IP%9Sz28 zm77B;Vm5pGWth$ckRb}o;N$u;!MAPaSv;ahgSxg2iJg2hkE!}c|5~y{)6;a-+pgKleiC#hWIF)sps7%cx~Xx z|7zlK;x>r$6SS?i>Ar+WUt2TmMHaqb@1a;+4$GQrAb5e5!Q+0M8*DXNO`5~RJ#m*3Ts>Va8YwV!pOUayQ-7M4zyFkrkk{3Y3 zRQUqu%p*F(x<#_&Y-?qfGa-F^$V7!}4XyqoL-}p3+P33Q=;dy)8NJidSFO3Po5F++ zpTpY($M})rmZzkWT(Q2M`V-F#eO)M$dcOe_A!X6{&qfc#47*9kfSnH=VkSd?0>ib> zH|avQkPIUB!rd1`2J3#5AA^EM#TcG2l?ad4UA|}wo;gl!`32dVh`MXke>pGhri`4S@9w$u?@KRmS4pW(a9MUxB`kC6nFWA zVnrLFw-|JIr+kWNjk*a9%S^n`CQUtlh&Z5w47vcwv_a}*@n}ybVnbJ4)}0&qxxNOb zi5vO2mKal~g?61k9{-U7r@X8-;o+Z}v!soXaY${)@mUf)q4x^Lj|wkhJSgnDTqF2H z=4_*eKmNqWBE0Ok@T@LVy)SCx&L1ZpbFulHc;n8xPW0C>6NaU5u}^gbqZH@t!^zEC z!Mq0(H@-S4&t!)1xZ#Vizkni|O`aSj$mxL^{dsy`&>_$7A7f;LM(aj^seK&Dq(&;r zX_H0J+#>wT_l|1EhfAXpX3Aibj0qkQb)b)le)no<%49^>2Xsp#z(&fn&LCzQuP#0=~~J*H!^j%lLQ&RE$0ZzVBSCzoplI)B?VV;1$g&%Cketq@w@(0GG6> zk93MmdU>Mj! z9s!NEP)Vn2mb`#taS3+-$I*y1U-@gu1{8o^?g3}*z4}Al#N*X7LIF>mWqgtmUg~W)TcCIuCX0ele2=OBPv=pNasTrFG3J-a3gCTUkPc_&Ks%Sj0&jA-Sl#fd z`W#r|*ekO;Jkq>KFD=4bg)s{ba5zse9_K%Cp# z{z}E1BYUcx0RJ~g*Z-sXSPuZ{^@e{*w2Qa&`oRO4c>$QEDe$TAWTQ2_=YW)-&BNep zV4ST=?Zj7CX2phJO)n^d;Xt1t8q@Y|#ln|IaHYv`{u!Jpg0w>B(~uNyL4kNHNWEsw zC?KDw;^pn{4Ytr&omhYO%)>8qM2tN?k4(SnKCVf~@kDW3Tro@cmMLY2*|q@1pNyVt;a> zKRnm|@2H_diV}tMYk#pq;d1vEg$lCtp?Kr&`gM=f6sbaazQNYHHS%}R*GPeYEi-YXn(nq-0ZW7keH%iEt7n#zms>lD5z3n! zu9E=D3cqhHKKoC8)A6+AI;nbKEHHsjh!dd##t7>(4)>ObU0T%f_HIz)f)3cBan@QkN8KH8JW!JXltsiEdWyYjCj`vY*>@et^{-bZJ!tgV zHYvwk<|4TB8&ytGvS!mbdjzivj*G8NaEglz;-dEI$i56X4g!lbe6HV%f~x)d!V zEpH;cjjxUV6s|A`tzPAAa9Q?RjSjKz_pu}9{?P89A$T1%EJ%iyv}{Xy$<;U=&o(-F z*!I_0xb;rdlS~Q2kHjo$tzUOmdLei***5;X%>)n~%%q3jkH{QoxS`x#BTWxi&F zPU6vSEDnN76ry3IYko4?o0Unh9m-7BNHtj z5z9ix+hsUds-M7>X1q7=5RuRntD431_$_hQ5-P(6A#pmuHi}^+u$3GVw=nC=e z0(Pb+XehK)dX-q8Fw%J5VPHU+s#)4CD?%&ppJ_uv0Y>*43G$S!8c{!r{!WFnMHyxx z^6jZ>=;)?op~8c2FsH{{9`V7)C28dewC$wH zQR&JOKlaKKUWAc0oGC(BNy!q}KXyTf9j;_W-mIZ5_c>x`zsgXaP=5L!x=@^GW<>UY zZY$XgJdBwv{|Q1n^koSptYk^B6We%fi64AqP3=P>JlskW>r}{;>sb<@KW=w2gpJ7t zSZH@Z2P=VOOK)OOn}1$Vl~^W3&jzQr4EbLHkrw`t_iV_84>y&PgnPS`BrLlkS6Ipt zGvJgbAA=}QNImw!`<@PVyEMp=p}EU(B?%YevL~fZ8@Xi(bF&WDwGKY&P?Z~LLOc)L z^~|9?pzmyXQiNad$`T)z8hCJZ#KM6gc>*M^3pqbKNYXv)|4exnKJ>^ff9W8(|E5M1 zJs=4P!jDg)qm!ej$HRxb2_WR#HETyjkBGbV$Uu_?vAKwP}PWpcoL! zk1(GUJ-|$`qoJdvn4Qzo2vWjF_pAv$0)Z(o2n~I4J#crRf`R)TRG~Z4E@Pvkp`{FB zDRqq!g{|zb>;=j92bcS>fzS7m`=DICbclB}aA>YeH>i7_fpuErSAEj)D!G@;G9!_F*nqlT$%IrXc@}QNt8is}6q*qOizw_md&GIS7>OOK;$W z2+Zz*-8Hm;0$vzU3m9>%i;j!u1XUy3i^9eZBiAt=LNOjnHB=zJ<@4r4IR~y*)graK zjc>OU94(M@cKti!Z%I|Y(BXyXw^gIY3$N{k=~^s!E?vTq5~#6eI7ffj^51I=`GNEx zz73*xLP}KJdq26lYaz8^9(E|gU6kOz-8OxXiUO*j6YFk^f-oOUDh)ub}ab# z!1td2#hd=iH-#r{h*4(Nf{P}zBjlRPkCJODK1r;Y`6jYA#3!g4nPXG)$V5K#kcxfh zk&80X!pXIw?&zAdrPNN)(?%&J4BI+3)Xf;t>S&^guf(5bSE!~HC5vWm(mf>DSW;2|>^uIP zY-{w)vp{&n@bx9eX#8ndnWOV`tO&ofU`>bA#G9Qv0!QIY(=k{$JF!t(L$tyTjR~<- zX?R0i4CwAQgE8HCR(ZhFcH)tU%gZ<5Ek(GS;>Fy&R~l9JHzMFMpv%~QAo{|iF)NI- zMh#@VlYhDez(UIgR%ghimc}~_ibgH}lnaKT57^j&sS&URuP$gjY+L9>3A6eIVM~zr z^Jo4WH0EmlC$3SJHYg-PrLObcfHb!kAl7Q109ws*5|!4;06|)0g{m&WtkzgTYcP`% z&vrv@C?#tR+JBnyCiNvFSl1y{uDrS6_eBeEZJ~c1K*^5U6&mqx-GIY0nMf*8*OzA; z@MPhGvDXhTfMgAehO7M`))w_I2-_2;CXpNbsBh97P1MNnRI+^Zk=H2XQ)w$hp1>;A zXzsXMeQtK&d-(CN&vJiF?mSzU<^zT-M#Xc?z;xkH!iU~wjxvE&*QTUt zqoC4IG@i#1S68Y2B~sB>T*9y-C(FzgtLMg_&Y<_gaXHoH z^{Lf4)ZxcV=13@Woj!e{~)ON-oj~I4sjs`b0_#)3$ohA`X;-O2^6*N+0hn}HNK6KI7|M+Cgj z%`RW@c&_^8N<+=F$`C9e`)aaP4JgauPTSvdnQk7%_Y&tsOZFoU25LnM6u44Pq zR6o-7=R@&8Qn>98YMyhn6gvGKn09_jbbjI$j{F%kYQ}w3M>PRE1Kfn1;JBQyaXDt< zbB5w^(}~VAiOX=WS{AFquh^lE8?janw5*VJCABi-@CYT85bO?SxWG|<%|Mi1Gn5@x zX)aw&q-&8=!~j|~Qt7YH1og!A z@G6^#&csc{g=oqQTRdo+i*ou{(KjEn6#U#?SN~Ae-JG) zLr4aS=AYHji%jlY`=?1PQa&5?m6-*A2%qMzW*mh#4=`7pxb8?%+{CC1WvBjt*B?03 zV7YaOmc*S|aOP+mBANK zQx3I2r?^HMl_B*iY(RRK@>~{TE1(5Pcao98M0L6z`n{*3hSdZae|7bj786#P|VhZt=QD8~t397OoQ#b__QScVKh z@+^EaIeAnpLlP)i#y#lYM;ItcQ;B~cAggkY2ZuEFVJgI9S~@t&Z9MG_4mk15#s#Cl zLQDFux|LeN4*_~Dj)(rIWTGFahIo|FwCE&s4AU$c+2=s5f7S?N*rtVl?g^YS7nRiI z(4l4&$XUJYjD?&K`Y#I~&r0LJ-x>Q;g>yA*1Z&Tw647id>9-I)b~H()xE79H0aDT7 zn(X7tMT(Y=J=tjbyknWbX$H_Ba+DcTlD;H%@nUHeUL$Fj{9(}+$h2>?$WYS^ z_$+4?8J{ev>OV^!ao0chrxA1N-(8sZ$47my7ZhsW{d@FcyYJ&d9=yMG(V~*RgK(S6 zK#d4Gt>L3GZ3|><0Vwwu)A_&}g&;@|WmKkBe#JB|8W(1bPnbRTrjOK)aAUAB2Q+$> z-%vx>oMU;1W;kkk`w#_|`$i$dc2C8CyV>eLtY!Le!#pNew8g5MBN`0Eh(=}Cn0!GI zm(M0Q?l3hD6!^-dceTZe8>hB|WImo#z$6<8z$675xs#j-P_)Nc!8KX>+d(L4bbln1 zklZ)@RxR}nx=Xs9by%@V={U#LI_V8V4c0HILl3L`IrT%#LWr|ap>I?ly3qX^7q zr3^N>#$;PE&UTRUt?PJ=S2wVBTEI{MvdZvjHxz+ugcrAuH6}u>{Xjq+xYVwz=e53r zGdH_HNI6BSXMLVv`$E=vL0|7Wi@yrWR5%{*031V`>HmdfFT9>BpupY5pA{P|ZL3&f z>w|Hg@rIAF8`wglWTk+<@UcIUlx z0_eosi*$AK;lHCT;yrUOE*GrJ{B%hrUMW7p6tDr#jZBA!04Vr+XZ7Xs0w_sxtglvC117&4Aa*CX%PP_&_rC1XZg2O2AdwiPL=Pj=`q9_mDVoruR&%ZJYAcI#fU;yZof z6dwB=Q>}Zj0n++JP2$&D`;qnJ7EfPd9^EUno!AAh_~b&mj(yg?+%lamJMjAv535Cm zvq#OW-!`!TR!IW509@zIgxjEiCzYaywYjqEcE{^uJHRC7=717$4R|Eu z0#^E5qw?A^-edbEa35TVLurd@IBSPN`B}={h#YYNwsaqw{#Q%q9+n&>=x~>hn*@E` z5YT@=WN1T@Hys|QeGB(AEdeDo-ca0py+&w;q24${3@r-8TQL`<5SxdhLziyKH^ zbhxzE=Ku0;frpjl$Df1Th(BB2zz6GI4e3>3c~Ka_$(xBR8pwc)NC&s}695SF?`G2U zTVc5ILC#+WVLxIKq&rK9(# zhqf>t#%PS!RreYV&P46-O@+vpRdGXagO-m#E4OX|(?M@<=VUihIfu^`uQOT!A=bi< z-6C6erWQjOV1p|tP=(e~N%=TyMO z4enH!pw|?SET(b}&k{YJeYLUs4<2lG4+?QE!hujDE34wa5D!VyADCyUq^jh3=Er#* zU;4eXSf$o>VZ~8*?reo9^XkDSCwt@&1{i2P%F+a|0cK7LY4%#I0lv!)Fjkb)O!|+j ztXpH>WwxXuwJ{PzA*@z>v|A04)CZ6gpat6hMJwYGHQHCn^h2Xglnm4xxM!U$(NOfb zN9i8=EaUsRblJvID||&$5>7P&-oz08oAu{MfyC{8_(QUdqjM^WZ>$vNiSdn%vdKl$7LGc(@&BI`BPR}{*}%lt zpbchkm_jGh8k87V=CL47yahyD?0%vy+7Yc-BxdHh@kh{nPcAHs7Bd=i1QcpQRkNlj zQ^jeQD5M%-A`he-?wCLwECMdDs5g*E@3qDOxvx3E6;QjWgdTIGF0D4?sdOVRCTxzN zV7j=l-~o>}ASej7lEFCH4Qi|n))*$WZo%TazWB8YLy)Mj`c9(kPS*_y_3@Tr%TaHt z0X)aMHBIf%gkbXT|AdFyGUA=R-V+0NbB0TI{K!Dv#%DMCzov)RyZ*>;uXntrOoYhb z?wI{-E(Ylumg#wyOL1$IPi<=$hXq zeV=_KV03~=!G)92iZc778kb}kkHHqA+MDpV6kfeXsaU}((yf{mn@`nMle zAo{KdpStslt=UST)-*?LL&Y+8;h38q-QxiC&oXm7Ekcs!J< z*W3+X&=YATWRF1735mKPCIK#D<%1=NOhxGkb|MwZ21ffvkcWgJ=)^cG@~_+~IN5(E zs+E)w;;A>BUAlQ7QFRv-0i|G z)AUn~Rq@Q6cA+uXC+Sc}Dzuk2Z87FQQBPdXBtN}Od$aX{Vq+w_f8!_^0}S5A6`(T} zRgrizdnL&Qjt)S{S-r5q-baoW%3Sz4claNSa6YDL0ToVJcMR{v-e|B{Tf-tE*F=nA z5a_9Ix=VXFjk>OE$XE<>MJEYB8fvOHvor|v!r$;_!5On9$6kj-4c`7;rnOeJPzsU? zNnH6LmOL<8vEz}-Xcpn03U)0q34MoIBqD{F&Eg!OF@_p$lO0X6jEz}AU61Vnh~i6^5Qy9Se`!<=+>T^syY>X zQKKq~^~S|XjFk?<$tZ0hq{a^=$EY(PD-6wKmn@bG*zyb2QT=m6>(B!X%wWp&!_~}R z*gvOz`e=_bBfW5MT)aYj-bI} zIu*6fn)v#(SH`q`RTlcGa4C02G^OTVumLN5C;)Y!1Sh6quS9RYF-hq%70#P{0&V9N zi&u+Mtjv*pfTd;y!UgKAclm!RKRcSoq4kL*6T{1GwnBn)$j~mX=GFNK;%r8YwjXa7 zi>>LxROS0W16W(h05A>$qum|*fS7)b*dfr_DGj(Rzy-ZZJJ%F%HK+xJCm{GtKz5Br zoarc;``;wQG(|w9n1#a51EBl~(NTwz!zb%+yMZ?>3Aatk_ByYVtSLqn1|6H=04U*= zL!{&<3^;+_6*5+*zX_#0*x8z_V~%Hs9K?_C>x9SZ~gjq)x)y&jd*Pc2E?Ou#5Om zjpQ10{O^LGe+o+8fyHL|(+%*@i{u(mLffhhZHEU$YRtR*n2n4qpArU4beG@60^2GM zB*TNFHQ$a5Fw%t$%ZTm&*d?>6klKj)+Vkmnbf9R{`c{Nep5R1i{3%;$*#qR1&; z{>BTj{1eXJ?bt|yKw`u9?FvF%ib7Y4LNl=&>^ziYd~)1jOAI+HTiMhrsDX;{FV(h^rtdr{33IXSiMEcjxTp;Cb<&Uxya+ zb;hdUG9T__iP4q3Jn249x`RqCi*tUK7g88hTSyEQHp1NNQ+%1>hgyPGrVt2mw!#sG_`u*g8^Iv^r1VRI(K;fR*qb?!C@dqwq-bfJbLc^z zn@>~}#Djzs%ufm6cQ#KIJ(A?MOQkkM@};Ag-8ee^w`_g4PwUpX%@Wp(TGi{CJ909E z16D#%UVk8})L^Sr!a<=yQy>b}M<65k8C58AgXy7UR5-EZ!Js#&ag>65XdAmqB|t7^^xzjZzi=RH0wPIhxEu1X6l+Xs?Sl=fmor;E4Kv zWRTi(+?09IW~}hX)b$ruo6hgTl9v?p#iBxyt&zWnjx==Wa{Wicezf(%AwJm1H0(Pn z(0`Pd#Elxzf1pe5Bp3;3YS|wS1cbab;~^`vVeum&1Uxv^PErXn?(Y)r?*%Ld!p&mA zh5Lgvq%Xlbi;ETKUU1|1&lGC>raao&j$ z^-z_Gk;Oh@?o1@#kglxE@j0Oit8}@}1+st!!u&_d6vEULGQp7F2O1WPm zZkoYkCq+6C8?n;HsXG;LXhEC84uyA)7!icwgA2v%?+o{d`SALsozn(%H9@B%{v)ff zxe72xt!x)a#u}|Uy8x3R@Q}Tif&?#`B}-S|pT%jaBZc6`&w-k0t%=seqR#0W%aWFB z_;`n>#Cl0^<17b0NFi3{b-?xWP*p||3SBqj!hp{=C{tq_mk=nKw9J)90?S^9MpVM+ zr*kQm_`+tW%_T>3fuz}Jjh4zmZI32EeRoCbxZmC1KlNH}9zp@s&CUtb=$ras$G^Qj z8c)p*CxyHq9v|G58boYL#9i2(7W|jV(#36yJ*YoapdYK;-`;s4UFZ)TKpA}uU303= z-UA?|XJ~|co)F84o4i?Ht^jD}y=iFStq|5cPIx>cpl-Z)($p&+T?2JNGTasgD(Lt; zO)9rv>%{y5;&K1^#Mb-Jc$*5|Dd7^x9uY59NJNX3nV@o;%u1Z%Vh=dYVDpX4Fw2Qs zvWOkNU23AS>0}-waNQwrq%B&4)s^x1iDi|Lt`-N}+RdV;6Keu_>1nlff#j^bmWWc( z%9*-zW({O2oH+bOHITf@0}fND*^(L=k@q_+7;JHOt6mAaJ<^3)e;GdM0JIUA!9#2<_ zg;;WY)HvDviQ3o(hI>MED*!iwkZ;H|=tr5$gMsdXrzqxT5sVN;Ver_1<;dvmXt zh>yV!g+xa~4l*vh(VO(KcoEsW4Mf>7y!=!~xb_8Ud;!LYJ71#VqCF3zM=>J=E5u3KFnuV51X5>OM^r0ue_t>DkVgp|!S<7{CTIRLf6;iAQ0#umkB zMi;9^itSj%e8wna$zzQO@<1PS0PZg&QD_h8xkaMa6k&;I7?7ga(kaCqx-BuTD8mxa zF*J7$eC5sf)*}_GX))AVKG>~&u^LjeAl1*vB;<8K4UK)V7)1Ai7)q_?mJH^$M(_Yb zM_UDhJx$xHc7YqaPuqO^MylP!Vf1Avz6LgovAX+rTL`4_z5003*L|o;{qA;U1Ah3y zi>s6*Ug~)=FKWTuKyw>b4!hbJ=oFu94`^e4iVE6<@Lgm?Tk5Q9x7pM-o;vW zjYD2P2~oEffzAVu8gb?DHm{-Bz6ZvlS1{4ER4WuNM2;ltEQKw8Wi_;e;DVTv#`E^t=GOa(n14-i2~E0f2F2h}YQH zhTSc)Ru`KG*HB)o8&Ww3#-qtZYo42}*BA&d+mfB$m*_pbuHa(J4m^B6P4CI|A6C{a zL9c%0nTt=&k4&RC2%aVA1-C*9<5>Cjb-!WsO?J#ISTQR!S>W+dtL<6|S23l~60i0; z_t0a=2Fr`A!YBYzK&`(3qr=m1u0sm@E4k|KwO@$FQP8#QHmPcCgKp`}?1Hf00``w~ z7sg!8NGoZe&>I*W#eDN_dwV#ta;ys1>Q=t8H@`~wVxjc^3JO}smz3)REZdqEuMaMd zP#FI<+3j~(uaXNU48hpNzSyo3bq=VRgv1$zu~z%X5L>8GPuF@gUQ7(#4@RpR;i|;Z zSTqaCg3utw+Ct#83;|H5pnCuYBI5Az!DP0v51u-23M9 z&IiW=9_hyYrc21@;~i}}5p>;i7}B=35i5eCIF{_27J zt8Y(3ufe7i87m9I$mh;aIk+0bek)cYoEpT{~Tpp0k0St;J#^X-d(QCnHwZ#KXRP}8b zCAu;^VP}YNFdKvhSD8!}w+-KBkSbvSA-v`bIioY&+sq1;zf3G(+Svkb2B;r5URu)U z801)tAI`bA>M_i@D^RB$er~aaapx`R3YwD<=RexOrpjJg>>%y8d%;Jvx8pfJ`&2fEZ0g)J?9vj<;~PhXYke8%?f zJ6iwuynnCyYHR%-whq1t-rmJ@lSwxeQVU%IRJxJreJ-h&bhzVTDb`Lv60XTiIx}*z zUjvEQIGFqlPUeIW4#V8)>G46OzV0-O^W0s4ZYa`ucfTq>RNABHgB;9Kl7o?u;)Xrhnx(coF6t*#-gUg&khs;}vm3pxIjn%lBS$P;JcM3>$aLWWV zrHhY1V5D-cwI1olmSv(kHDUEdt4Bry^s_n<-Mlc_$9lWC%WSjZQHv$g`JH*Ii-H_f znu3Fu0J#0zdpyz7WeIgI|BDsv+-bSaG}j{8yX2moH==&@<<0g{u#KcbXh5M54U|SQ z#8pBsW?=^6&XZ*;(!^iQDht;KrFLUASJgpJ$=6@C4SJnbs$J0fN>b|en zS)NZER^Bq1EGE1I*fk$ZLw&CJVIvBd=2C_TQdx@uGQ=b%=vjb5qF`$g*CpMBCVqf?k0r{#Ip;al7uGGvR6Lalr1Y_6o2uhI)HfixZv@0 z-m&Tpp@NGO;d`4E#(5MCW%$RDc5xv?60$TOOjW$a_kr}aq#KJihK~vzSCIqjXl>|C z+!Q-)49mY79lzV(jAxhN_aKf6E`e9PFt=&1(b6kbrV6-mV*$uD%Fx$Ap@1Rc>y1=A z0WRTJILQ_ZO1)TU!3$YKVbMi!^a=>Vhj8$~yj5hV8oZvPw~j4ER+!n=;U+};ZYVPx zGJZxks`))EII6B}4k!ivRf?;H3u6&NfrwlyklcKTC|s@Jmn}A!dmXx)#yq-FgL@6) z;5UmTMu$>EdlAqm2hZq*)Yj*q4_*xh1ZOjEpj~HG^WP~zKi-Q#4C~>(D=|~7q}K=7 zvy?%P-jO?5Z|Sq?oul)Vk)cx5Q|o)9O+Kv{b|D-2z@L5~OoWXNLCjw@98RjxQ%}@4 z^p^s50fO&|D1R{9KnHmx0~u{*d}S;QVboKYZ1A@$6Kq$D0zdm~do&I5PIbXBZ%2b| zG;nJki{Mx++n@z8*;mrNHcQ_akS{_R-|4*$t2Wyipnn#f>9UrupI$2tgo1?%yGAk0 z-kbE8Nw1RZU(%q@?9r8OW0m=iu;6>Kz}{`xb`*$|V}JXWZo&+a;ttCAaNiIIvjtV6 zr!&)vJt#P{U*iPdS9P01aEVMU#*dAZNhhU|s5{Y5P8WOBePLUqW>kOwa^9=$yk^-i zU7jU23BI%53gO{FLmR=)bsuYCgP%0kgwf{j0gdegWBxth>}vb& zrUV23$p^!$iFEy1M9ZV-W}ykXgm;7jEUw}L?KR`kq~_nm5zv-XI>x&CN{Iblvt3J7 zA0y%ACRwz}RhQLV#=Bf_;qT#&?!lWE_<-~rKz(-c6jZw=ukjRG8X?37))pfvM{p)FisA<`u><8WcnBnHb-Ec;QH?m}g^Di=mU*%+kpY}3C zY{Fd)=OvOBb28{$hwrQa@_v&P7Jq9bF1Qm2Xn!*#H$nTo_8B40iDHKYGjYDy1C^OV z-~8Di@A5K2U(jNPlrnq&MT!z|%uwQ0u|em)cK z-sZo>k`f;aBo|$Vo*W+(M3hihl)7C7ph{toq5@|0RA~%6)h$z2RW$9YFU#K$#-68N zNN^}B9K1BkU4;I1S$W~Z&3z`rQ%kN`Uhv`XH%qRlR)#GJy+br23l_g!tkn6Dh*|ke z(8Vc`Aeh8Cz!7R$QU!}cY8)~kcV+c7w2f(T6ieyqHgr_t1{Dqih3Hgbm<4ZfKJf5H z3Jh*`Y>?BT4K=9%s1oPvP}YQ-N23{#)F{VGBR$dtx+9#$`@v@t2IXnG;Yf=7 z**|UQJnsL6Dj5TH1(`1Ey4y&%BUxXUI8+TrRbH=HS?=^62VpKao?t}idd2o@$=N3KwJHcbwNeyI@*@)Qx5&GYcSdTj0{mVCpWSCdtay~;zg_=~De+QJL zr0vA!n>HH?EyU+H;YNqdBu#h5GwYwRqrlq(37oO0u;2z@+Ooz8>qN1RSouiB`>Q>` zrpNwZMjWwf6W!l{D6s|6z8E@h%Iewrb?`@y=DFyyoh%)n$^d@wff-$~y+FvbdgYGF z!o+s}&_4EqJDzAJL-5@F;pxEe&+54be3znK7vToZ+P9sBI#pgoAIx_!;%3qdZsH%0 z0_An-b>EjN@Y>wh4xDK>chBpvvUVl+z6;1#mnl(n65cPrp`_T-$IMkI^s!}Kt!jIr ztAk#$uP0}rVd4e=-er&hDC5M#Vrd_>Z+Qi)add*!ztML6t9!y~-nxvw@jQ|SJ!;|0UY4%<=K%ZZS90d(EB}FWF zd*P5+UiBKygn{)L-DbngOJkA2&?Pcw&<6rq1ex>#_YDG6J)zLU5`4<$3r)kbq^K`? ztkGidQkU8nf4yfQ-HrLc72AF`Y4WDC5kS%cn#W2_F z8nvaVNF_l8#L&~Wsnn;4YlFqSZIli3$E$(qn61IY%56j4VfzflO-(=Bs@op`UW0|) zK+fg2BxP{KWOBQx9-cR?1JYA@1JYM|9+-3%&{Ar(l=Cf`wWru+cipgFHvhH?Q`zl; zmEZs}W_Xf; zu(MSEZ()r=tvfU#R792Z)SC~pOBjaq0^*ZQ#KJ|?07TM&;W4OI)DC=!dpdU2RHLfn z5T^TGsFSg%NB}68>Yzbl(BA9;!s+(n2aZC-0j^9O)lDbcoNG(3iJ}DlpQs+)R6PR_ zQ9o&FSD~t`UWA@Gf)@Pwq$Kp~(3SQxh;Bb@(M3hI?-(Ill3+C$#jbGpS}3+)?od}W z60n1NtW=7xKsR_rz1O>_*{^y zXBa#H)NZezINJUpGt1ldA)8sF_=NN#++pb}9^*1MrTtG|XwmpRf1~L{ZRTIdlc(&0 zqIak^i3;+^#114;&Am-z2($XX;xMTES0fgFp*XY#6g)r;fQ&;HKCQlHp|mlxfeUcW zS%KWjEV|8dk!A4iN0jIlqTE@;Z^1+LKHKOaQ7DH8jdF*L1;6Iv%maDEIw2PF5C?7a z3XyLYfB|wX*I)p}qTkBE0ThdURsalQE$OfTMWWwbfC4cV^$-9`b9VX+dM(9(2E-?D&tE;SbUj12xc7W^0>1Kw)`0SJqEyZ{RkZ##ek4vTh}03%Uvp}-|F zsJ9ipHh4H1ETmjFw-L;;ZX5H9!cD__g7A=V-=ZEIRMD&|ANYzRUg!-0x_{(!YqB)& zAW^JS;MZeb2X*c8hhzR3@2G9i!#3j;v6Z*C&}!LMQ+I7 zApLw{;cy7_jAKBO^KTVfeF&kz&uX9B`qw~74OP&jhuG;sNdZXlqSl)m#r9;5j(xI5 zW1}DFY4tvE#ac+l6rL@E4Yp$nk}>~54qB2is5&7eV^9L5xe|aEB#deR#iWdC0E$T% z)B%i17}Nn4k};?PFzCa#trg4LF~_8gT{-dOnFNuEOl~zKVo(BT#+VE;NW`WB5hP+z z0>qJtKp1q9i9ivlBNnW<7$bnA6NWMULO($kP{24 zakP(Q-SjhSp|7Hih);oh6);=y62l4=IKv*|8QNiRkG4ZS6&bZG_OdWpcB3)H69!&{ zu07DpH;|-a+#(iLo(*mkJ`Yo2Zti4X4aI&vcPX2;oF@oO1e*f4upy&hKbTXOLhAzeC|UO#f+NGpWa!I>hj!;P1@xg><7?`Q&!4}TV!0x=H+^mrP(NTX zE@frg+CrnwMYzP;ZZ_;>qY5c56#0-{f1(S$Jn^=Qs#Zb6P`p&0cDys8 zY;Oy56JRQ;3|`BR9M8_lTk|^Mrt?r$pPEIu#Y}9^t~<#qr4znf2e25mXok(*CraQZ54wus#zj*MM^r)Ll(;K`Gbn152i^2BoGbp!KoCe3D zo(%LoRR(U{GkA6o?As=hYE>+kh9*(IjqHqKmWJiVc2lE4vZf0$f7jG_`J<4vWom27 z;NZh?{?yb!6&qx2G-k%*6UVp)^atf^dTyXb<2zjHuO`0Lh4`4aA#3SD;Kyvk;EQyw z6i|2}Qyqo=b+<%4BeDIL?hUPMR<%t!=xTAiG}EDD%*Z#|@X1u(+@`O77_`sz{)j5~ z$87yx_wZHj*|4kMU!473_vEj7N-4@I)&X&!IY&IcigJE>ggodNP_UrS&(2U#p`@ai zp3aCilZ_Y`-5WN8_n(-Z&wvdg`T6Q93HjO)xmQ6)I#@ZT4CW`Mgb)Ltqh&Wd!h}Px zo?$@CL?3MDD5#iF7EXqKj)8jv;@V6IY2psPj)1lN^&G_POYVw-a$tVu7q6p0vGXPF zJ!pQ!jUL+B^l|D#_C1)e^atZ}Q;b-q(E2IyG$D&%$eJL|VWJD>&%3jj(3jlQ!!hPa zGM%599VAULZ0uOhFD+aB0M+ zpPnyyfGKkfm=Jb!Y{!e2-2}w*CI!dzNKJ-=HV3&Z_;mH?Pqbk?KI`Xa=vW62U!Oq$ zG>j-9bh+8XlEOrw`a z`N`ty>}O~64JH?kGstECB?8_iF1Z{*tx0Ba&R ze1PQlb|lLS`A%(pmY^YGb2_Z+}WvdmaeK5a!S8By{eTadI zwPTG)4|N}7t;e~ZkgvV8&mm!v7zbQN1)wG}2*z86uxnm;Tbv!{Zo0>5k_Mq3h!8fz z<393slDu;@_@qtv0~o#YH?6;FWQJW@Jh32Q$MZ$wU&Kq7W}p!(Pc%rA!(qAi#c)Tn z`vi?&{6f@JY?Ep}5gWP=b!NBGr6Tr&`1W#pr?Sw(8m|s>dUz6>nN?qhF5!c|Dxx^ISSJ?f4lG%{ zAB>JGw9YI$ZCpj@avmEAnQ=snQlU@*K10cJRF6!rpU109o7EL-vMSj>F3ViXy_{MCXbk!^-;} z;w*ZbK}Cyu0i(`sM>Oz=N^?aQa=f7B-?>CxC_mt${&;91l~*ohZVE9gZQp_g*edNI z0AA0KG>~g|e4sgJ#Y05yILATGh@j+gAmf@l{thl38h|x264YaT@Zbtj!p{v$d zEc=1!&E_Ugp_^vHA!r-&aSAV7P1h9VSK1kRiuI&0nGlhNiQFqCBR6kLGJ0KvXm4re z!4rFW#nb)P=E57aGUfhe3K^VdMgC^u0q!`#~~BPM}Aep8X2FX|llKb%qPzw{GF zt{CN|qlAXUx#9{_0@%GrTJb@neAuVYo0<})A+Lot)qLAsMdzCVW?N9%hJ^KX0K|F^y8^KX9*2kr0J z${oG$drj|ogx>XdE$^s>O}+lg*e&nr{3BarlTPFHg#TV&kw{PLgpsUmk42 zm{ntig3>eLZh{uWMJa`b94r==9}9Bje2K4lDdBL#h5tviZ^2rmswvubT9G zdcI@1tFQD=tNp^&{QlmqlLp4I$y_P)l(vciaDJwaKYg!PYG?od4^e8OHsN9t{| z{1qfgu!9HBJCOgA$6%=nO^b5ARNteK0o8j_-Y-totydtef7w53)Av2cz;r$*3DDwI zy{)okT2azm5jE(tLjigca<2=N8528O)Ci0lXS|D0(sZdS!F4`)DJEgI_$?h!ntaEnu?3@`L_)r&N&R|2#<&25EU~z!dkBP3>i})X|8r`^+BeT5S z8$l{x-(qs5sDj77Y>SZ7KR2$SIo!` zN|drn$0TmvNYFA{p~-w8+dID)GDjeiDo2*BGA|fUdAjYYMbN1h3F8N#jjHRv@Ib3A z_K#|~n(tjGnQmZlgU0c50F&(1oRgHp7*Zs3T(OllI9$``i5TxjKD;a)!Yu*uOMukZo)QN1}36 zNY8OMb!0r>VeY|X*VhdhDktys|C=GafwZIyaNOk7!?H?TXNmYbd;FcYBrjM3<02QkQixND8dF1 zAk1c=qOcXm( z-$ER=)XnJd?ndEik3J{{{+&MyYubJT7|qf82lsAN%!@33HLmiXI*?n z6io=F>q$q)WGc}CF$e8{B_44gzbBF2UYUE3ArP$$+vmI8iI@3zANYynWg#@qV5z%! z;ES}Onv74La4D-86tR|p=<1q!wBaU|Nv$=Whqnm6m<(TCq(gNabyle;Ya!5o&h6Ah z%EI<4lWjW0PSc%8?n5_sd;)CCb94#uqBEe^id-|pa8g~u@7N0dq|DrqMp(baC7an?x(s{?upFdRFZqw zcQ>$={&YL~)Iw+ZvcEay{>-m_=d!$^3*x|Y;Wj<|CczP*>tG#1ZLxa^wXni%jlc*9 zJi6xgB@u+$)#N7Dx4>ZuwqRfy{n|lvsWy;ZK_=1*r~+m^r#=-xW9`v0pM&lx3dF0( zRu}nbW5E~(Uf`Gv-rDt#2&tz5e+s>Zr}ivZC(>%O!o(iOr@(W|6|MPV0z!F=1ER&Y ze0W%`1hH4D5F1abF;|%?tDQG~AU4w;Zdt+=XW_uDrqyMThv2gQa9SKLFgnV+z>v(M>|bpQuV#A%_6}LPQoHsqpH94&d+mM{S-L_! z>QKAQnP_g5UFOH^-&`*B>OJ(Y6FJiGy_8}sSBCmgkLmm_9oQ}$IpL~=thNHPKJKUQ z_VZmX4)1OyUZZB}vT-f_{L1-lQ<7tUO-!ao;Xb@t)kv8g_nucaZ?2ZNPx;J`ihOZ0 zKIQ2#{Um0(zG$9C_NZW!99!@HOq96%I+YS0iP!*>U2r< zFLRbXN)DIS4Ksqa?XELS9H;5E^jPB^?vklPFdYx!121pks1>OFg0un^tq`ToCd`j6 zS!I9A0k}<1Y0Dm1)Hz@_?tn*Tsz;Uup1%AQZVr|O#*cVUQn0_#>>5jN&!{aQei}V$ zWh0|49=2TlHC6FQmlBcN|L8d{`Ylg$f2rQgBj?Xc=~GUxdKsIkPm z)bm5B-~&_QW>F;$UEXhWIj7o&Z(Q#hWO2SB##vHTaDAR&SM!HO#7$uN!5@G&0iVlL zaHcvjMK!fGSWyR<+KQO<-rehM%wMTH7nWJcPAfHk#Xnvb=}*_6P7yhdeWPE@ax4Uc zrqriFhUWfYtD3D_iGr~=SAkI>N!+G?NUqvP$e-KVIImqt*mL5baaZU%tqS%@z*RHCa)k@->Y9K# z_F#ojblOBz5$88BWI?s$h<(*j#66G)vBf(<%#Bsh^9fQEs?5(9E|qP_HC;FK@ss2Lb^?u_s(v?9r4v}yfJTOw1BUdFQx+n@M&hgOuKYp1V=(PM2s%@$Nn&YIh4cg@{4gQ5`={bd z=7+!GgMySaI0UoQ+ZPxg?n8Qh&+!z?gQoLLr8}qSI(+-^^(#@}&tFHW97kLVlz9bz z`*CT)4xg>PP2K!r1cA$$Bet;(By}-M9qf+Otox+Z&ILFU} z#CSQox`J-|Z%muN2Fv9Xz-eUQU6|}Bel1yYtjgRZFjx|(UgA>u*pv2Mi4))q4 z=l+Z?SHI_OWVw2g$f;H80sfE!{1zfQs%thlP7C}9VKtMx9umu%{1_pvbx=Wwj1@`X z!Y6`0m_hVB%{Wgo3_!5s-VH1EmKW#LaB7tgJ|@!lJW=P#Rx)h?2cu~CFac9P>m<$6 zhu*|K=0op*A76v3>79LcvlC+9uap~UZ`!^Z_a=05cO#S54Pa`=OP&tWlxWta* z>zU^%U^zHp$!KR>E|8GUr}N=;CBpY3wS9kx@V(2P7t_7rf8iW0(?s9t3C-c({h(!L zE#C^G9BmlmKklzyRqzU!mhOtf82|%lON@&_f6#rx5Z+g^Ed}Iy;h@;Mq0lVPz^2fA ztfa11G|w%s-%$H8s`6$v22jSBS^{}_RN4oD=TQ%U_1v@(?Ly4zs;yAhhlMGdZqN8! zD2@=YdOZX2BZhnlPWV3NHL_;&!|LBxo%iDmcp(4q{b@6Jq5tc>WMlCCXCQe%^O_I3 zaQnFrsvK%~XX1b|{m$1yrE4xqsnt@j=!dV^gJG{sbQM%c)Z&LkMUCYKucVy$%rm80dL-*G-IC`iRXQwkBHD*u*LF zf-#DAF$6;vm*W|!YPI`LJvOPf#U-^OH}lGlt1KbRvq z=VLw54A|cihjvbxRmGn-uW<^D9Xv@1@9)ay{;DiaBj*&F%MvlY-*lS?dbDxy1H=A; zgU+`6F16TRNdG_j0KfJtRmn~`YP)!9JgQPG8xj#I zm2(OllH@{$F+ED<@^PzB!Zua51i_YTY#FWJvs+@#ZIG~^#@BxnbX*ZW30D+h;+EAE zj>av&nw<5RSFzLaI?7JJVlcc7${QQe^|l~BE6KB|A*>=un8HU4+^L?h&^$ua3U9?? zyZ^fJ)tW`m5Xk`c1248#^d2B0%V!?~3=(G_1vC+k%`=Y*SPfang)NIlarl74wG2Lm z!FkeakxJm3h23j}y!F1HKFr_lRQR69@KoPl1gW5o8IM`|mCCn;bFq7Mn~DGNQ}s62 zrA`wHf~N;dr8V-xx+?gqcVxf2{tCb1cVPW(NVGuph1xA z*9IMWYd7J%m9hR_(JJZU35YG}_INY5Hb&l;LD z#<_$07B*yThH#9Ml-zoeFOS#sAmqwmFB@t{cc27tWljji)L$;icGFp85aSO5S~Zi&2&;y+-7UC zA(6=ph`Q(dQDtqrXAv~MLHQg(g;nqhdf{`0@)B0<$D|f9;{Abwyep;mRjN>Z^S;F< z4)z4*j`5_I&fEE}_6;xY>5XFG4n8AV2I_H26HDBajmyGuxdL&R`$~lLVhN-3ADpxy zCW5g*O<Bw<-0NWl*}@%x=W0cTRd}IW|P}RR26`A zAFJa;AJUqyje&ft3=9Q)dUz4=FOi%@mU#XT)o0VwfR_t#8jA z?#>n!Dl;yr|7=rdlR@DlXF9Smt}#}~h*Jf_>^(bz9=ZHdKp-5p^Agi)4^*rFir^;KcF_^_29 zrd&|&F+h(JS-#{^>z4ZsVjovKNAP30RXg`KYB9H2zZyDCv5;pW^v;KR=nAAg{I>I3XpeaVO3$Ue#k+|YeqA7_K_fSBDNeP$ng zp!-ms9<)B4wQ#^LP)D8yz`X58&To2Nc0=a7;V(M@^WWH)p5%P?7DeZ=A3HCQyvjnT zADF!LL+4MyFEM06@;^Cw(iAdwW9P*15B6FYgz@XRMc};sC8>C3j;rl22}AXVFAm80 z+j8*9pVj+|!Yuxm6udfv?l|S){ZD}87lttF`6b~BeTOK#FlXg*%fa>35%r)!D=qIl zz-CKetN7*z_R@mp(t){-(d0O)tZ4Rv*kF<`RxN>#9&d6S-!qv`R+g=sm~l&}#3x2{`{A^~dWMbLfvtT}z$4MeTOpt7<&X=$z7hoj~)3 znwM4EUUI*m|9q|^_vLbrIbYQ8mB1G(`n3-^Ti6lun`H{w9(T5saD4a@ogpim$(aYR z4#s}`!_)J}m|N_TWo72D=8`-J=+dDHb1ex{`<8?CKMEq0V;84XaDyeE~;Eo85)Ht!uzSIT7D4+o?3z-voMavDH7!B7FdK9yd_ z<0>!v{sICA1ECCfko(mK-oQS{2i3v%G9P=e``-uF0rd48#M_?xcB6Cd({6kX;%(33 zed)J9tKz2I{Y}bk&$RqgZhj}5e%$>=+*_ZI)4OhXLft74`_38~H))Il z7{$8K#)~gs!Vm_)ypUlTan!MdTs(;9e0)AI7a4d!mWE)@5)7 zoSlm~J4SMCS;^TmleK3ic5-&ZDj1kP&)rbL*Dbs;L0??8yWsd;Yc+Lc#_1J;`yQJC z$_t5wg@#MY93-@`;J99QE0(z`?%gf$cr#mYBO$|&$)MvmKO?>gp}yj%8Wg4j7H2?E zNbf`ZcA=QvZO~FsK7EB_-*V9 zJeu;h*#6C(;&tTB;srzdSCt*DYGy;Wo>UX&MT{Fow};PuLs02EZ(H)ITMVH55bS#0 zz<_Zl)J9^&;@6fZZlWy~CsSZpi&P%Qr>If%id6?7ZldUcx-s+j`Gx0(P)h;@Q{GV8FTTll&3U(ndcDLsOZpEzKAz;}Bq|@ok3d(O#I7@91+GFZP za4j{JDWbeuoJKLFGA}WYAW9cfD$styj3|EUM;)Tu6X~@BL@vgw(h_0A)DDqi=SUaj zxbycqJrhewGd(aT{<~oURd)q;-a((0*cz{R<}-#>WqW#6J&U_32hAw z{R+1?C)La_S35a8y<6Ln>UrkV^XP;xJwHOdTJg|mmCaAFo|#uUJg#bTb$&d=uxkZi z@*DwfQ|uPl2m6XFDC0CaNz|1%+If) zA+`Dm$|e}|DQW$%pFpj0N0(E)P_(6lu&e@ifePtz^dL$N_43=5NQr5^1Ast!ieCLz zz&+1XrzgGx!IGqG4P*wvzNq?Vn0XEd=Zcgvienf#AmqD;ZbI=xV;bw5T0tZcxRmg68F1MK76^r4a#m|^Y zdVsOp*aVo`%O7-cO1gc@T+O~LI?o@~MRa2U%4?&^nE5{!jNjA}+NK0h;8wc8{zHMe zb%D?h0KbyC{F)>^KNRDqfGCC?Tou!B^AK~whng0&ObDB=PyPb>Sf|(D+X~wAX*4|7 z#y`!MUL-)wF--`Uh-bz0D6;3y0`NFJU(h#1ZJPfOJ8^AV!SSsoE02nh0qKE6f)gfH zYLbQ{xrR$Gl1nbA^3?7DPXAW?XDh4W|BhpF;#mYX{SbNhkR!x?5PjkQ;63`2uOgbq z1Xd4E&L=yX5gqCx|BCl8e>+3Hc6GuX^z&i1Rm`Cd;NGF$sxO$`L#r2|O#%>gUlhkz zp?ZPvdKai4c}AKCj}q9|IFJDaR;oxjA^P3Z@tzo(aUVUk8i&u>4-hpbVTk7%o|l@N-_N6?Q3iB0Vp#BWpjiC$_y-tOiT}Fw z>v5It4`nMc;T}67J&He{6bnn0&kH7JC%e^i%h-4m^gZ&qnT8V>{C+()Vf2FBIm9;x zVP1Y>c5-D})!96<*-{8i`6zHXA>2w3&EgXH^KKB902sJ`Kf6K_;U5G4fC>|l_dA@XqmE3oTd4k@k!EHx` z<#!@CF3}s&>bZzRF0Y)1Twr8z{~lfX?rgv4B2s5H2&IwmltnCWgeNAa#siZ|pBDcj zuRAX1jNBI)54tXWhY$W-A7UqUN7@P58a-e{yq5$?yZ*p6mN5vJw=<*THz^a3+7F3H zq_liV$K7^~(-VBn=)vg{JT10vv6oIdGv#H#V!Qnvzmqkt`b^t@eHi$F_sE04ByOj^| zapu|p+&;`O@;O6T@nj8i>PQ+h$B#B>1ohe|^F=?$n{!7VX5QR^uDlrYXcb4Aj6U3K zWDOD323Tl!KnEj*k2S8!K-&-ZAZkoBd8NZs*am!$g&t*I7<;jg2b%_utdKR{-aybx zqs>=cAZ2^$16o)}8(JRv;QKBd?gzAwG(c{0TnPhW{D|{wbOF1bK-U!k+WipY?PLu{ zu8=ce`!8`IZJ>9!@B1KSp9F!SEyGU^4+d_S2@7JQ>w%D=pJPFkpU{7Mx1Rk-QV$9x z*a<0)?R@X|RO{2JfpzJSf_3SUgbzp4Kjj!tcAcCldEi6NHe!3cUpo$7@B!~4zIKBa z{4|^(LLDh->BbaF+-79hu%B4`E8zhxm&~o1oM8~BthoBbqt;4Dvf`BWEVuJvO*$QG z1s^{{o{b2T7%#$`P4I>RaTwXz&hx&*n_XijXdwaY*Z3=_SJ6>n%~m)`@sz<=f5c%A z4=gM+sB*~Z%<}o_DarZjAHRx&=^u#;K51)UZM=Lq1wyya!URXo!t?g%i#3pxQ^g=IAOhAm&xBsLPQv>l3%W^= zm-DJXTv!FtaD&~_Lni8Nsyjn)xYvwu9kn`7_}~Hg}Mi! zWGriv(2Xk`qqv{y2_N$77KVd}B-~gU`OLyl&CQQ;96L$jfECgg(5pl<3$( z&bm`MS?S9;PILH1j&;hJ(MQh)ayl-Sk{qMX9GxapI)CMn78q(vZ!I!1DItmO2Jc-%2Fl}CgVzc69-Am965tTL{Irn$S3yz$cKOc0c5EJkpeoj`w&ti&S@svX}!Y;W$G_Q+onTJn~2p)#<$OlDa=ue;7j>-E?*~XP+cd(4e<-wcb*C!(v@2- zp4gt(FY!EkTo1;Nc`gK*xS{uyA7X#}_P_jlUIZN_5%Ilrm0Fk?b@Wr768J+LFfb#4 zx?*y9gdw#`d&bVs(J#XrXdd`6_l{pg!iImrg*T=0$(sl`GIQ)`m&Z@|6WC)b`I7}K zIcf+~K(%%YCqJKGhcqRUZvM&lj3+bU!`}?B)&s<4drZJO%yN>e6VCwa1W+9gyTC`! z=fNRNZ7?%Mm2JvRLNN+_Xs5qyHBp)D%7^WBbtZ6Ay1tTZKf_cUCGpcq4ZX(gBbF*$ z%X;0G`MWCy=WXus+og2Va4( zzC(H%uYvw3 z_aHhBa7c||=!5*{D-_Z-a^$06k2l8+n!%)?dMZDM=!d7mS1-Uv8Jhu$}+9h+W zw%s7C@560nQ(`N~#vqMcJEK=6y5qNLx)V~-g2+)dw&PR%C}AFDR|#h~3BkpzsI!|_ z!ObjzsI!cVvxwnx+NxL{%7fb^UeU`SL*5FZEfDgylJJ&&^dnf6mU!+K_Rcmdg}XnY z+XIW+S@+7?&a8q)Hb;f^A4E9E5XsewoQBVaGdSgth!25sAD9sKvW3vnl35Oy$P~F5 z`d|3X?(=sW*7(n6F~GCj3%y!w$c^p?fC(KA3Dtrkq4C?uBWa6&vK0kuNw_7dgQcxP zD&YVjHNG1pXi7$lTCQlwbmhT%>2czHa-MdSXAEhx9Cs`B8XwWvgWU-+0Ta^l#{gJB zr@tp0x+$Esm73cjL(oPp7Vm?byQoXc86t7ZvM%z~@V>4NZM8r?s`WH%^a{fbvJ#%p zK^0Js6Sb5Dnm|FJ9>|$tM`~df9EI0$w@$q=WcK=F~d*GK(&@rHsUp&O7_h2cx@ykA8MSa4|6sAuR08GR7W zBJYItIJZFAY5A4%OZ(N~YeCj5l;rn(j8%@YWkP0TV#GS%GLs$WeKH$lN_=Pg#X9D_ zr2_$)TO#*?WFp89peziW%*gZw`V5g`VO%P@vkm0WNy+1j?W#&L{-Spe4_8Ae_=DHb{ggrSIJp0dn^$6EiQv z1RelIXn(xhuTH1>n+{0n1c+xBOi;{csIaEH`fp*g!-YThu$w{~QTDrr*9v2Ok73rS z`rbp0zxwZ?#y{bG4m2sJZf~Kq!x}S=@*S)(qOOy{3K*gx+G4WChP}vgC~Q~?UY9h*HUcSokf5jXG-pSaG&|EM7GW;@ho;f*f~mNpFru)ny2H4GRxD`s9egKDu3@p_c;SYn;xu*wAz^p-9p%7a#fbe*M*4roxu!n!zNcJBU+H zQJ7_si#DuK68U-&On}Py5^0-mq`#vg&cqZ_230u`a0a-52Pd}&CD6v2m%EKBXPf!> z(so<}fN^(9ByCk5oQ-83U-RLFbTw?_V2Ak#rEvU|NI+o?2s3(NvDrx$M^w%>6->_X zvkTJ+F~YWqT?|>xP}*|N|Mw)8SroEhSfWgGEX7_^qk82^o}&|sXUcuA18MDt$8A^Uo<4%xoE3D@iy>ZnOK?nt)i&M>y*A!nG1O>y>Czt)U)&FGsmBZ%OjQLT zI?CtA=M!;>{FU(^s1S_%8*>$jR1Aoujg-sc>~3Yorz6hv%@1_k@(Oa`=l z+hc-O6|hT^S`=aa5MVG@+=p-F(xQj9WMz(UnCa20t!kYbzkQ)mtL~K)&;H~~ljbx^ zc*+ZA8c;52MzK(|t2v$I=Xp7U=e+JSeC#fE7ch2Op;4p*XcrI>=fNT~4mTt2eygVA zyU7Obm&=(x{+{VEAQ4LFMAJ(8>OzhYI#$6&&sZ**Wfo>1(7Z)l1~+O=1YwxMJH0z) ziRKSV`(ewac$nu3DfUP=Z+qWszGVCF!A@QGyF~)OcN}L|hAD$iP=%z{xt7Tk)i#L# zK|msV98NjgnuX7rVQ&b3^$686g6{#Pc$73avL6XAQ6yvQv*CEWY*wbaw<&WIctz^- zbo0&0sKs5H3Qv~j(oj7EU9`L<@6+T%b3`b-W9z#JkpdVmB{3w%D2 z_!ZUKW%9{0YYxArF{MdKkXY9DU{Hdff#824DSLjI#Zy6~|Jw+`^&cS8fZ22dNg}7m zQj_lZJW|UlOArFyIHFf*sVqo&;wjXm>8=p9MM}&(Txx8qeI&TeGD`(L&lc-j%{bQQ zgTx8MT2iYO2W~&z><4y^Sr#mA5B^A?ZjxCTS>aGX`_upnU7^GO93T8x07!rY5ddqD z0U{X+!~Y~7^?(4lfCFLDBRz0q#0UOVKk*@-E~f#TMtrzq#Rva1AN-3+Rgjx?NKmU} zl3RBd5DowjeX8tEfx)Z9>pN=Tn(^1E^LLjmP*pKZP z@Z46r6LnOYu?~cq$Of)WPX-gFesNkS<0bEeF20anFF$j)<+o|XbT;y8QS+q3V! zrsZ@LEiqgMk0Qsh99_@W3Tt98lbQ1MVtq{Nj6*%NVIe%nHOjDhw(g$C3L7}-YURe% zpS9eB+U`NHqjMiR5kiekA>qod99*_04+J7}Xs5BQ7z-@a#hlsko6^;>#^*tYWrcwY z*fm(N9Y1aY0knm){E&NWpAR`Z$Zy2!lF=6@$p7rSBZfv`sm1q#~sH9a5mzbRShAd{SzbIw%Np9l+5OHYC_M95BzNV8QGO{ z)9e+^P6ZjR?KxWm)^&QfR_xvdg#xY_4EBo@hQkYE zl4L-~fT4e6clIL*pL5cKkhcVgOmH-tf^Km_ndN>%A&Gm}GT5QLpY0#*nm@_7BWhK* zQLMJY!RYhAnC;e6KK=4$?45n6b@yH$X8#ADdI0;;2i~AQ2Jbb`?M_4l$v?I+W zOt`6A9+<9~QUC_Y_NJUa$M5sJgwl4pkU-x9q;A^|Rmf3fubQ$b+>JvF20h7kNf^cVrd z(*_y{?hS?!#E!m4^BXdXA|5n9;Ylfk{RmFPu4ZzIf_7uUS3fkbI>vjvDhaCR=asOV zUN?nt=o9|mxSZ(I26!NxeCai%-oevrjO7#I6GZYxjHfhMa7as6$Yk3A2cwKa6l1uu zW{?lLko%zzzDRwUxkujkJkpba2!g{w#lo1@_%SQWVE;TAVDilC1i(hE_-^oX0Zl^R z;4 zEECZR;?ZcBRWPB{)$eSjoE)=|vuB&RXPdZZn>(vI!q$909Y(XMXFL4*YFW-gWwNVW zxb@yb8u`_R>d&fd5_Gfc?!)@x0)6jz4ex9X6tjz{4H+1ggNYW5Nw|>ONCs$aXSbkK z-YKHng~?$F$oW~?tS}Nyi|P80dyE_X#NJ3l;@*d!oF3k^L(UTv)e3E&=I+6_vezyq zf5?P5NA%T+w0g}6ggv>XJ!P>ycCyhAUFmsE+o(fy`oMm%10^kV&rm@iTLZ-8)34J& zw&b^NNhe9T7K*+xgeX*N57$A067h)%cBPU1!xMRd6l+G^{Ksxvbj_CNbd{}{vfd+7 z^aU5{NMu^<2}Q3S*_@^0H^(xtCbG=I=)BOw@-t0hM zNzob2s1ApYFAh0e{y+T9i^H|uu)H}tW3VV=Seg}T<>GTaYO?nip2UN;2HCi=OKvN9 zrWHL)e9M*&VHPpzS?5DtBanx1`>aVzWw-_lis0r#3yO;5xiFy1LdiifA%ZdkiUO+6 z%P7Jurlw?;!s%G#xbe$PmUW@6j_qG9t8IHVx~o(upxZM#tk_u3TVr>ByMTJ@D1B`z(A#rwWbn2{z)%N zphwsElT0xWtTCqo-*fg!3gZV;e|$^R-3#P-@mb)u_q#g&;1H;&JK(8Tq`u~&j|wd5 z+$TfpLF!M(afs5n$#z83%q936;^!rdVC&sHOm;%eUDCn}6yh~DMGF<4UI13y;;?Qb z(-b;4xzI&MXn0C9LeP438EtrUkR%`>y*b|sc&yhpPm}R6Fv}n0>gsp{>rqS;T{0AF z7=GKsY9)gsfy1FtEUq+Wz$ob(_-uj_`=IgrdxS>i`p_b1M#qG*)g8LV_$0{pT!c|E zt~6NgD(taY9>(!0K@Q{brqsU$B(228lTv0-bFnUac%_s-l%Z5qaeYH*EnAe@4Mm3X z&d4ebL>scG*p`kjDSy|f^lYXM58qN*DB|v#=V&cB2t#HDRR{nLqM-Al4hjum8x5cq(QCX4DPY+VaR9!> zqNJ@G@EYyGgE{=`?S-S}hz!fNwnDK*G0Xq0Eq1vq1;9x=5d|I4?DSJ-)epyyscJ(~ zKLtvrPjCcf&2&4O_;HZxf(xDmW@HU73@_B}2%R(fQ7WP(=#B;ovI^r;ZjT%a(L9LO!-nt4mBBY2_h>EBILH4YsJ#)Z(m;gF) zeRn;zlo6B;$kEwh?H-IxQP`Awu(S=6)tg3iUIwubrPXi>&{Mxqpv)MkGr>Ck$L&$=jy@_We7OY zd#`jXlN1m{yinp3()nIc9&><MtNqtUtgVe?2JT1L}uq`O9& z$0<%zJDyH~oG#9sBRJH#?&ELw(&Ifb7-c2qhChGN>tt@b-{9N-*Lyz!3vOxDHF$-R zu%#uAtv8$$=u*{>^Ryf)dUnzQ{RdD^hSo{MLc&WmI=Wm#;QYyS@7SkK7GR_|^`%WQd?`#q(;dJ<)}m& zXY&;z7C~IpKBI=f01Rd$CD$4}<5_@Z!S>KT*MR8sCzpup(Z@%nOM*mca3RUw3roYH z>^vf-9G21Y?Z39ryarZnzw2kK+kei_hVX`!hB+lC1`Ya7!lmoD#)v?!@sB^1ajeFx zt#Q8|{N%A|y$wyEfYh7-RLIM|9Zo8Jf3i>zW6;|Q7)XBLA#kt^%K*x$^t_rLIHKH# z4Lkr2r)eGnWn?zOktypW9!{zDp`@69$MY-#(g%YSUeX-TdGw`I`{0L5(HAv@_p$kS zwxJ92x%qa$fFboir9ydjlsq$oQ*1A0k82Co`cV60r3=x7gVOBD2c_BwW?&jUDr0Q% zgm8S%=B+$DCny#-gPcjEd4%kIxvXO6c02)N4Sv8{39&9GQd~|m$U<$iXKRDzecaOB zD1GNNuI7N~N&fzj7cM%$Ly)w9`ahX$c@tk^`JXfDW;IAQmHTiqYG7H_B{L6$B26ae z|0Q`%FT{!=TWFvcf-uAJ-GkyFi}&}-CsV1%uq1t?VusjxQ=XOWhSs*DpA74c!)sZO zhS;@5;{PG`qII*_t{`O}YD2?}9t32mSgG#%o^`cQJZHv8!ameYtCHqh8??p*BxOhy z+&Ys;jIhCRPu9oVBA`9k-Ho6`-c`s*177ElS5A}$G0TP^f;sm^yVutXb?=+7Kcfc` zbsE%GI9{7YW5Ol?f+nn~M65L6T8$c!oUrGHw9JgL8OE+{6g)XKCkNq-e;n;~m{QzYAU>G5B5mzh zr%>h@-a%!M&{bPxon=tAsqV86QCM{>4U7@)*R&T|?vFS>EK$RyA>0mm2^NwV!O&gC zm$KHMpeiZHHp;1IMsiSt|C)D4IZid=^7`7*v z-le!1k7+A#IbhBu1jO_%<@*YNIdF#gbvod62iV2Ix^p?mMvpOlM!T86OUv;tst&gM z85l#$s6L`)%=wSwOvB4CiqIGA4!PRf1ZTHq$ZfViXLKw)ML1%_Cprb(=98wrX&rUxTwPLXznSI#z%n2 z;POz&l;I5{6@V8)8gnBJ|;m2MaX7gFMo1xPoB|XYxg%Y#GVO4l3qOf0eJxBO3odPLI z-SP29jqI$4&mLoJ97=4rN^Zve>Qr+aW|gB#!40Oo@LVh!j_nYQqTrr%o8iQp&+nAF z0+r;2IDuw%l?B|xh$UZgth5lkyE>gC#;$k6gop~3C8_SpV5(nc;2j#xv%s67$!%8M z@Xd>FoHTUU%t~7EP(?R~i-jeA9wb=5Zg2D{LVV__+6@)!6et{xuNlo}OibQH_m|6+BgPqBo8e-Gp&6O2szeUyoxV6Q@W zjH%vp&va6H9Ha=yBzd$aJlK(_h9vjxJ-s{$SaZUIOivNS@ZEhFji28Yr$u}lz2Fa# z4z2RkudV=Gg7UitS-TM=qB+%Li6jqaJ+jbWlqQ!x(*pm!$WdNF(Xy>7pHaoW(?zHT zoueA3`P3UnI^(#;zK=s_S-i^PVXQ2uF;G2( zNb=!Bt>4N`VAEdidAk@=&6z9UVMb5JE;XE9>GOP;M^?BX6RtOMFt;~ow12`b_AQOq z>jr`Ic0e=D3dPR+-KpJ#JD%h&O(CC-bos}*C0OTz$vL{{GXnJ9kad(?Mb*iRriMJ! zIzr6X`E)$maM1GFR5FX3Bdl7EMJR}HSzza;0L*|iVmiht2k(SD2a9BeHPx-2FOWl( zA;?38AzE!#%btp}vCt1-=WIu7Ez~aiA=4<_Y9(4MaUvZ=9u?z}s@oB&KEdqwK}?Jh z3_7=i%L?qiA>?z5_HBlkHc~Lz%^*_N4ea>z-scz$$3lD_<`^87kYs&Ssbmx?RzW4q zp%YgZ(1RPM5(2S1bxU%uHXBYEqA0%jX(F0tfuk8jnP?Jio1PCgdJ;J8&bBN9umIEX z`%&z#mz@r1BLPY184{CFM-r0IE)^u8UP?zm#8ipnUT@u_?gK{=MNwcs%;&)*4ZVdb zz~DJo(68NAn#?CrD($S69UJHmN0Pj#+YCACQSOjfOyk0(?F9bJ680Oq;Lj*=qJ^MV zk)I_=h3mlN49B%{JQ8zAl!=O!p-X==7=fo9eGE2xFdWuNDTGkl&5Xd|C3|4lf?I@- z#THQ!nqiDZY_Q9`$+8n|BO*Qi=vZk@thr?nUII@+>L-*%Wl#=U2eow$NC`!KBFxh zewhMw*G8W;GbH)or_tnLL*EKaq0eqINRJqd6G+V5zCLP9q?)M@P2S~R2~fOVl?vu3SDz-LoI6X50-3f& zo3Ys3Be4v*4Z1u2vS)p+U4y0KcjgXv?+hJRTpaJ?m0R@d-Iy+yf{J{IKp0@Z4fRQm zt3n96T#!H!T5k8%xJ2IOU~S*o5DzQ>AwgxkD(XKd2&0B2_xM4J=O7s1W&lJlT6i?+ za4#neS)B=HO}i@KKcg^{3)Rc}Ql&hf2=G${{y$RSZ%K_6e~lGou%^Dwm9^5*sWM{< zuXig7x&1Ll&d1rx9G`O>B>`apH9FyMSO%v#*o|Clt5F2wJv-mkMO{=J)+Ei6PFqI2&!TSesSC)ELdruJD2YV6N`O zE4!~ok#b$4{V<9$22NxHgndP!3Kf$v&!~bFciP~jLRp*;W^d@yMWvbTgE9;ZkmCg( zzrQ&a6HaTQ!WOVv6Xdj^k}W(KhHy0G1}>=&gqX@5XR>;!T1sPt;7_s=6c{HW@e1>D z|48=ZvZ*Zb^-1pBHBCzE27{VE+zum{UGYo!vKta9Gyp`Vgo?>2TS0t~PS0oi>JZe%YR~z*DLtZFhZ+^IA zd8sLTs!932PXS6LGXX@V?u@ws2Cue5jG#JU>6Q3He+w?0wAK{PgHK%6fxPbLArF{{Q_VFwpxA?@mO~tU_m|5 z;UT&n%@JHrmIvAcRuK4NIK9#z6o)7l{2`~P=cCTr4+glrIKQ49g>;J?h%`Q#&38@D z(-BKZnY?6_C@t6wGoHA?WnLGlf+-7`e(n7bOg=D6D19q2k{3%ikWY)#|DG?*{CxCI zi*kB#MYayVQCQj%WegDgE>xqTx-mlE@{L?#FQ``u{+2^&^AIZq0b|eDD}@5tj`Ynh zNfbC_X#4Z-(ZCqhyP%0bXh)B`Tb?&3@CUabJ6<(nlLffF)$VHwctDa%j{Y2OpOO=0 zJidTL@gA!2iYGur%`Q_~ru+-NTXVk~UC%~*HYuRqjaxzps%zC4-f90CAJ~>g|GE@{ zt~aClK_IrrNGw0#7{6Gal>J*mPjjl{4e?z_cU-tZvI32 zjlRf$*s8J%EXdl)5?Rh#TVGdb>)Xn|%71+;;|$$z_Zb)22*mbiBkBgNDgy?oiH0w7 zrYBNU;y210_IcL{O&V?Rc_&L_Bluz#T_^8pfmwA%;85R=O&5$$qol}+k!0d}JM8R2 z!4{VTS$I={)wW3*FLi4Ikt3Uwa*ic$!U45c3F`2=m_}oS_`?WhfVQL)1K$-9;s4re!1%_$XtW`2M2(; z2j3p*Y(k*RVc9m5sI!JM*x^Z%0WBteL9xllhClRiRj{9@_KP-9o7xMRM_0*ofV6x5 zyft3GM>rR6_IAj-Yi=b;?Ran}T7fb`!uXn3|>f9Io<72egYK|qprzd?U4ZH-&rDGe2<{M(^4x;)Ilhj zf|8)AS*6eR6(ry$s(XG|p|tR#IB}mJ1#F0VA>%e3d8MtX{YgYMU@bP$!q2_A&(5cx znkR|$QqPjQ_KN4iI`y@B5m#!(&53CcS-EYXzRO^p^U9U9H#Tm_3av0{vFOT5G0prnxe7#5n>3*4Gdpo#QQ1i(A=K4J$`Hk5k?)P z*Y@|c+T7kOVjm($U1@5MJN6R5iVxINNraX@j3sBgUIenNK_tkH?1Ix9$;)&jNe`ma ztw~VGmX1_aryP!Hcq(V!j4i6g7+X=Tc|l}@nX;!R^xA~I)<|t8iVTWGHj`w-y$E)b zY(hM-aM^H6;B%!G%L{}(f4@dZR?E-E3fUcOe$qE3g;0&8=WeMRBdO{0)FW*F_(sbs zY0v^TCow`cN(8AJj{8X8+N7BzJ!R|WXRn5q;F9sayDEO>a&DK`+O|u`Nii|*)o9u#iq(_l~bTvJCoN0qKIMs2y=^=v; zT)ZUM4QM0?Z2l^M@`eOy@`vbE-`OTdI~C-Px1TdPF&-GaMl zYBi?H9=FVY-Mi=h?cc{scl2=MyW`Khk6Jt%d=aJZ?>n5}yPV;>oZ=y7mhR1@BLHvH z=363do_5etb!_py9N;578au@Cw*lhqt)&|2<9<@|fk%6uH;g0rdV2jQm20hlgdICu zK=HN%)F$+x6>T)b^^GR$Czgo93pT^`jd>p};LXH`6bO8*@DTi8h$KD@&Lc8}w9{%e zlxq#5&5rM6Jkz6yxkFvKYHlFArCNhqA(IdHX9iD&+1of*_U~g;=prj#PRm;qP_`OZ z`U-+^pEcttx;~bg=6!E_3~&*P4FRf$3!eM1vufdNM+%1IS_x6E&4VPxAzn~&LxpQO z)~LQ}_3Y(|mftMVZ27Mx?BR_D_8xB<@>?4Zpei3UP@8+i|F+)oKg(}Wa|xj{V9=T6 zp|%_3k~~aXmfvqF_zb5h&tBE#Gpcf$Zt*Tst5W!X_SC)~`D$PG{aBx#pzy4>0XoMynOj`Tyx3}2^}J2)?gimgI)`7?Y8v0SWz|f@dT*}BnVNQxBV7` zt=>lvu1*p%8|v9cQYH4*hZQOY&K(HXd}^p z7K;UITX`W6Y!R)ZKE615qTtkPD5kL^+if?Z;^SmPSw+R5TsvYH4%efsT=A`mtSUq; zjovAGn5+^h|1ZG^^L@;#86R)2q7)?`(6Q+Dqclc+N4^s4wL95elLyfjIpA(>tc+sBs zK~x>+b^?R2P2AxG=KKu>tjY|-7c+W$LZ81DC-TtVhAeSEp{3FH8x-SE&UaO$p=Wx| zGreb7-h~51ILdfFgxh_%%_s5$Yby42!`yVc-hw9nUmdb4RECxWJ9gKI3==f(f72RF zA>$pS>7(aQ;-^+N((f;eH@X~9^Ijpfx*)(0-mj*Jvf8gWB{o@ewx$r>*ajd^bSskk zUtyr;)d;*e3wuLikZ8xfg(fIj^~(XA&_XmC^1-u$SFxYOT3Ne%AKKqkntk!uh#yJt ze|R3RGwZO>J*u#4Wc9<>x(FZb&GUQ}_6=Y?oO@xQvZ{Z3IGYUw0KxNK(7=0;ZW}|^ zrWVF3+~vc>|B&|d)~V$qXPVz=Y3IJ8V_~4<7WLj(r^6oWU?fn6Ko59$AmAkxz)n3j ziX>rJHJ{KF&wD;~qB4(l%gtgwxQ=kVP;xVuSsZBOU>dM+e>sCA05U$f`usuagbdTh zyLQNXbYK-jZzgN+t+j!mE|8`pn7l^%IihsJdt1p z;}on0JdxuOkVYo@x}3;ia zs6ihNXk@tNi1@9Mgwjz_b^-T4rtm0fSF0 zML74K0xNmgQR2`_fu1l&LkvFjYbS>_Ba4LA&R>}}u+6-3x@$piyId=uIV@Cp)Un3V z4}4m$D+mEyfZ^p*Y=-o*+zVJyKS^TGAIIgyi6#7u(~0*=KRp!cpE?d+niRb z1acfSD}0N-CY9^QxoW!~aJjNqtZaR-rUa9X(glGIQJ))iWXE_3T_=F=L1>17iVhdV zbY@+2X|E_s?x%Bp6|=e)D1BtffhV8FMiD$>B=fmK;V5!~s}pt8P4N>!S3fyNfdoN$ zG|H~X4@6HS5KDWB9rI(PxJCbOb~ch7F|=YfI_zl2x^c5$G%r#ybFx2_f8nJmD2X@SHb)RR}3n-ZkI!<4W{UgHIrb?>pH1gAQgg&@ZdI}QD-OR@p zu)i+l`sYZv{Xy$rEW}c2;JMb^*sw^n%g{M+Z^_O<7f9ThG=wF7vaXAQdAV?|b++*i z84c7r^LbK&jbNw{T-Gx;?FSvHIKBZWQ=ToXLN|sv%6}DXGlk{DBL{{*!}V}a7WkvP zPt=RN4aoW>r%pWChkVc$YPPAVLOayN>g82jHj@Q@4Y?1ccJodB)6@jxy{3{VTb zJp#gEnoUP``N^x|rlCW1VzdUzG|J-UK`RBfyA%G_=D1G$;+$*=$gaXeO&H%?Qnr zy;8#1^)Rr#r@=#!A2*`!sC5k5=`_vtTCsuL4d2Lb$aYj_q(K1h z-KayWnglO5h#osA**?;AX)<}i=~1r7tZ#o0O@QF|*SOhJi`S66fyL?47c6mfLF`C? zu<-N4oes{_Qil7ol2TrD>A~#Qi>I@IxViz8NUrBf>+2Y6_Q9P^bv`p#{Gc+t-@jly z^jifloHVXLrptLVB5e>%mLR;q1ny@XK3q`p^r4&HE2eSq&(?>^!3(<(u;LdWL2?RQ zZ1F;;YK}=f2&j7@x*q91Ws%b=iry6Kxd|h!&*Ujj-e3~5l9V8RCkK)fDxQ^7!SZ(T z>3rCi$%p20(cI(*Z!Cw-f(lSTV!Krw*6Ibo@GkILG76pvA=utQ0sN5+4#zizh8dV3 zQA-9%;b_GdWx2ht7(D%(BEuy!zL}X!qLMnBx8_=>jF<6*s`Xa=(DD&dpGZpQl0Lmf z27Req_X#i?&`I(4D^^M4q3vy+Os;n8mL4_ExuNqA^T{7TTlT@5Hk(*F^^e`JMgQww zdVP8?{~Gn|wdcRrUMO>htWx==>|e%|V-Nc6*t6yR?{^eGQ4V-u&4*8^@KW+fp+D|4 z>S$R^vyOK8XwaV)Wx5l{r23+3!kpj41#8LV|6TT7&)B)g4NeD*ns1taPjtd8ce~YL z5Xfk6TQm_L=5DbtI9*&wukp3xiI2L(vaRakV+RwS%|c_gI8iLRS=ia}1fZum2Sk1l z`=<&X?4=^|BLP0W^yK1Be{qVE+8#HJa>=xzSECz*0-bprijGH$;fl0gf$cH;KzmN7 zz*4pBYM4Q!3&;tdepet>r!57d6JRjd93`4*ncqIODkDB#-s0-?s%EhwkxI zB3B1tVNcCYf- zKBX(-6jhgPB8BV{i<1=l)uAA-+RD5_O->17Gq@k@)Z{zW-{U!AmU24-{hC;Xa#Ky+ zvo`d0X5KEDn$ljqtQCi4vJ?9TT}>$#uyW2Ucf*r&_Fh~>xwu;0s6?q*YUI%Lx3Jo4 z0hX}(u|!a3uQutPyiu_)!xnmTe)f7rIQ1O;A<8F0HNLYvpmmw$7A9AHnCmmkan@!- z5ybvn$620GdfJ`zaXtQG6Fjfdg3m5$jN<+gqRuNL`g~EMnE$PSCOhk@o@uj=?hZWX zaH>b!q4DnTW1-_e7$l2ZeeEC&G%YMK01u$Ml2cwiiPv#(j{5=rGR(s*h2Jy(1KK$LcUq&AK!N_UAb#JL9lzEO{vdz< zK>u7Dek4EDq<4wZwU>r8F)y+-uDNHriT0|m!pbSB9xjYI)gmDAh=qUI)q~}RMxJS zx17^zRJ`vLO_LW0t>lA*a=KLA+`s(qbAIr5 ze8Ril@3~KV2A*P5PMqdHd&KTfspdHrsPBC8XKlHu_?D=@QXFjLp7zNsEP&yC1hBcT zA>Lp}_=Q6-`8O9^&+3B?s5PJZxSbBT_?nUi8g}bvY_4dVsrh+pI)sNFrU1`xmZPu~{EwwU#$I3z{{_0&7#6Xkyi{fVNkskgpZ_{`bnu->3`mIZSUaL_`q{5;< z1OxLfH553^o{E--N&Rqh(odYhiPlnsATScst1+Sf+z0+xKl7pg--r8v|F4G^`&YvX zTR)gj)K!)LYM-dZF8)5g9w5C*)OaMtld6}e>MniVLm^wAO8=dTSN!Z%l%3ynq{*qW z@>s0?7%c*mQOn7CepT|zN~Zke1gddj1Jq_}@r1@65~)83U(SPotWN?%nNJxmg#Ybm zmZB`Ynaeo(0;b}}6L6{2P!))FNK{m;8&|<-=E*wMK=#}`yq87f<%mMe0g9NN1&Ul@ zEl1`bY72L5mZ)?pd!nE0*!BW+J4@0`Fc?unkiKq#&j!#dSS?X9X(f=EOS#OSxL3@d zw#~F$@_nMz7PK^#!1ng|&`WUj(^Cg(G8Eu1ylA>Z{i*uk?Vj5q(bAJ{0AZcXt#iR& zpbhS{X#J?CGRRA%x67rs%dHb;5S7T&6$UK(6VPS-U4nEOaCniR%jaaufp2e#g+Z6E z#GZmro^g0wOezeqDGT(DE*}!D23x8O?sz=3kdKz`bDF9XbY<0if@kLy(>eLHRQ%+% zgI|)$*k> zHPKYDNU9l9sbX@d$lEpNDv4=-NAyJ>`LG#eYW^ozyZhgvUhh|vh27vx9as4!CN~}? zT5V|aB#ZjS$EiCl7-Pql+ywXhu{PTdORBTB=+qjB|% z4={=V-T(j~GaKfBK#h@X1q-zig>1^27Bqk$o;8r;Z$ph-JidDOW{${ZxFg5*W*KpDIlyMj!gNP&V+E;fxILm7pGSTAQSEHoDN zLB|_dHMf1O<%gFn6LPt&kXD;8Qhc!u)Xy}9GI;F<_QklF)b=a!Y3=fX1f?S}s(-;9;zuqPasdJZvAnN6gee6nQ%O0ZfAo!KTK2^7^F zJ7j=F*#sfYjMp1x4J&~q$DpE=EXQf2cZU}!Fm>u&%2Io76Gc8wj9^=9V%qNSZx&0A zZ=G;3!Ks@Almq?)V|e)MG+kCV#v#fIU3rQ^gPMSCp8TZSX7Pb=;j#xm9s zf(g$%?Q>m4GS!YSAloTMuv~S<@BQT(?rZkoE;fbV)(*aFo@m8hXv1bG798L$4-}<5 z-B9qsa9(X~*GM-haKl~8LpHkXKe^TGpX-e-xsgGyGyrnW6L4^tbM|hJOYQ8?-88#1 z2U?VV_b+ujQrh)7h)uG$!58F zZj@gu5ETEOP;y1r`T4=6E6Jj=%L+vCuB-dvFCs6EMFfSt-jvt7U`zBGz0#o+x^8u6 zuMTd_e?eX)V0{?$F<2D3yx?pqZ`S?(~us8>J9^Sl0?ub5(>R&ntxr2FOulk{tvxao_1mL5G5>IxYd087Y z<) z;BvsR5(%aJ0Z0#WA`)0kZdRur6Q8kVJjg>MTx^J8gK1b4^?v*h()H5toCI@?58I+7Cx)(f3%5L64m z-?-MmSi{G5v02UjPS`C|v^}%b=siq$sdC;jcfG0>ij)7KNt<>DWA6nf#Pg+F>3@nB zJSzz)Pn$B{I)>Iuj_#yQx@qN*+uYjzohh9g8-0r_U-sgjN)61;o)#TkIEx6N&<9Xlq~ghJ@`>K?oV@%Hiy=SNFZshG!SjlO7i9n?S{gr^wA#&7`)}@Rz?T^ zULXCCf652^(0|Ye{;C)Md>`n1VI!?D#isTCfW1E?F?u#HPX-*lCCk%W5MG_BdTrL1 zrYOA}#FwOTdSPz`=)k=(i;L18N%p<-h@phTA7z*dGhxq44b#U51t@Rehg>S&{#$5J z)z=NASi!3)g>zYOKX`$x9U}g13(3388pVLmp6W^S{^1M&5sf|Uw;XWAb$K(nafQwP z9A3kDHmYP;r3Bs_K&ei-dGK^4gV(-qs!buMvM~z+u0Tn1Ae%Ws%J$k|sn0RFXodjX zRe_`=BpoAIZrc7c4!Nx9jbv5zbmwT6!u%BXfkkiVMGza(i1KCkDA`unQ922+3k4Ip z{*a<^5$xzi#D!=3k~*BnRFU<S0sXqCvr$9TAYw)q3%fp z#!VtYFqt6jJ5pVxY{C1kFfkRp=?iPF>;C=E z&&=I-I4m`q-IYfuG;mL^uI0#7Ykwq!B=AP;&EyZC>!5Af<8jt8hj`&HK@ zPJg<&B7MBU$eheI$rHzST~a57$bV8MO)KB`>JdG)#nBTX*B9tSPt?quiQsMoiQpjr z?1}#A?y3XEiUZ+^O4jQ8Nul-a-{*sxSD(A(!@K2>ytakHN$A^~q6<4MazSzO=OD7n zE=VpeSdl^(weM{bR^RuaVge$ABE-!_MNLe@4NQ*cP{1icBypBjm4Jan4Tfb63l)Jz zKUnRlZM3s3Hs)rgRiPJ(C_>cK%JSK`cEv?ryTYJMhbbrT@Be-K?94!CcQ@Ny?z_%% zrq;Lkd*BPY*MDDp1NXsKd>wba?bbOPZLC3M*C4R?Rmd-9?1H0Q{&OfGu;7B|e)~m9 zMY+4B7EALunk7|n4awtiJc3K_%OsN8+mR)-w*8d8uOIm_Pwz#a2aHqHL%l)kf=q}e z8$ckFEJiuJQb@;06BXeYz4jcG9#^X6Ao4Wrw8OG7-P_zC@-w=AVefeMvFYz0cNn|F zud?I36*IofyKgCh>vhhoahkqm9do7~bECQIh_EZIOK)!qZ~$H}ujKSzyZiK13%Zwg z(S2Su$3;eT#q6r__N3nw8Th|vvq$keNn<}x+B`GswF7M~R9Kx;TQmSlK()W>l!SQ` zf?r>I+6X`vL=`W#Dd^A#whF7m&XcigNj|81#F-xZ_a<7t;p8^QRJ0qdSG1{BSw?qh zMt7$d;VV!(RrF9gR}f42^BP`CTB3!%BgJ<^SojU9s_^*5afgol()Jj@4U94n(}(jT z6@(=>lC{bi_C{i?83g{n(^+OzXEe(u@AdfRz?i8?p^JKTvnG|T@KQ|o_Sy`h!k z557qIsULM?@2EbWkTw0pQR#!|9CWAn3-!jyr3_7#$a=~h7m?9}C$aa|qyl3`(n|fm5uGVhyiF~2FL-rpXqOJ60 zmM=sf#0C*omQzvVjw;gJCn8)Cqx+DY3*JhZs9%J1cM^wER7nz!vxQ$5-BW&lOF%?n z4cg@g%JPHrx(-BteW@iX*T{Aj#FVY<-b}Yw$eCVSAl9>hr@~CaZ66a6x{ry8H`@E7 znI0Gzil9azKGH{MO$QvQ8)M>P1{J?rmPI%w0o_iEqV2+|O2D>;iBeV#u(7u?q^vB+ z@PSfSm>;NBC2zy^3^A|ejSnauj5mQ~xPGEX0|Fy^nI14MFX+mT0;$V}cb5*jA#uHB zRV-K;RawNqm(ul#FIbZM$!iMY@tX&X@ag?==QI&QlMH5X+@7Vf7vQzejyd_QR!&gT z$o$P~hvJ~53QGdDfm0&tn$}>DnJbn4k!exN`&>lb3`FenIE=hUb(fr*mx!Hdo6Jm5 zVADO`@nrDc6<{Fbipr9I?+>E2B>M4wmvAz@s7^*tA2d`_ zkY)$Td5DSJzHCimjQ)gY$`&7Smz^VTm>x6Jv#Fa*P4hO)O~W#=zjCxSZbeztSeM9l z&e=}4Psi+ePpa1I%bOKa%G2nu#SAl(>ORCbmH;etjseCMyql!h!_q#W{9jUjJ=&S^ zu%B=C5wmf6TD=55P#&oq2m3#NDW7;&@f#PcEXwx8OB|oM;t?#Evg8uVztENcj{hIq zyo4=1e`D6Cuhlt6UxIHV5_dL(Y?o3-B1xUvNuCAAWbd}?9}(Mn<@;_>Y3KLQlrAD& zg6`4_d|VccfqfJLlkbaT2=nqRG7J;$y zDAzIFsu$KeA~B7-OhS^;C82DvsD*2&2%Q}e-Z~`ofx!rPI$;6A5Tu)x+?DVik6fy< z7}lPnvSZ+7kW5o@5@yVav~Tu$>_(ys$)~S(DsDuzt2X0y3v;5dYuVxD~w~Y3S*$p!TRkL%&=1X zZXg>@dA4Y6)Av$D*cv!3Os#1{+9G^g#q(%YVN~kMy2D!53V!ArfG^Zl2u&$E^EAFG z>?wU9m`_`nQXBZ6oCv1Z*nw-hfooe6i)q2yL7;T2RiJiUpgrm$Hviyv;Id3p~_~<9;OPNuZ;y9!sTP6% z)RzWpRSxrkUQx%f{v zWROZV(|ZYo>Cot_b)mj(Q`WlxC8<498`#qzwsslbbU|k)hvZ%2UJDScezn6uG=p86 zUrj>R3L4?B4>4_aYOWUi^A~Ue>gAN@Ai!}b{#$h&E;|h*&gwd8Ucm?kTtA-A$7XR4 zjM!oyT0?H5vfciUIY1FP^l`oN2sCQJ0EW_cxsxCd+4;K-Py_h3*R3%D{r!gOI&hTy z06w(pN1-FlerguKH5J0#S9Nw>z>pfT&3+;$N_Gugs($=t&+?UM3SjRaQjqbvEEg{MXV;{cjh(SPm&%fWND6 zQ3EhDCWC;Kv!=GsMitzd(3#b-@k+!y&yrt1n;Lmnvp*0RMK^svy5Au9UeUlwS{SLK z4OWK=pW8=6O{qlatwH=z?)wg`v_rNuIG05Mw6UY_a7<|ae=#wkGzWjZkn)9&@|g|N zM*Bh|RMQV!_8O7MN!&5v!?*)WzjQD@gKZP{OoAj*3Jc#p5-mzJV5bSi-a)SEfSaYK z!taoHa}Rk2Q5=J;`JK!7T#T6hr#MOHpXSdpsXxTMDc?}0ICywUUm%9|qTTxS^W}EJ z7Wys0CfsTJ;)U^b2keoJcB(^N%OiL+JG5x-hwTg7@K3uvX^M}a#PbGa} zNb&(ah#Xn4>UC*bUbASy5%3(i?&X7dCJpfx%2Cw9w(FYi7z`X+PpJ;ScVA!fxf{{O zGtxk`h(&c88DQ4`fcmX#z78TE-=AyWs;Oy@G{5^>?kz6eZ7w-FT;{UpOP^ayLJOhl z%%-)S$sn#0UAI1_?~CuX;lEIJXFfQsEnQs(TGFIioAlGT_=pnDGd#ha+A}=@()v(6 zRi7?IWtF>m2!r?>J4D(+_Z^{6tK5a#q0-sv> zvRUe%N9MCeof@LfzNz{>GQn{j4*fphH zM6QtOmC`9Px?xw9(+sC?1}^o|?2Dqm6u#<5FdwLyl_Q`_QNXDk3O`Y*M?(+Pc*ch; zX)5{1n1S{eg~PATn@T)mN7$k3M-!IPiHCB^dk4RS_pi;GyLK@r2oEegry^%KTaW4Y zSKy*}TY_gl`^&B}V@K{Ne&fgQ3R33D7ET#Vo&a-7Y*{M2j0$^%LVJWt{lfyD;ToRd z9=~w?xyE0Q`tya24p^`~lEBC}1{87XI@(y8LbiA`+Bm;vqN;2($EFomJNm-L%B@3? znQlt0(O~+im92@2y=bV1UR6C`s2~gR%(&^B<04oJn7gC-R>;0NgxEef>K)>56N!Kr zko=3H|IHAQQ&myEicpn#F4biRUZr_duxt|r6)btI)47+!Kku}KMA{o(f3xQfBTUDg zXSh^IH8@hCgMilypvGy|IDpi%3(Wlv-Ibem5r@TK_=u;ET6m>PiL|gK7#STX$Z*Bj zVZxhVh%QXxgyCKRHw>tdSpl1FItF*`*;s&EKA?eYLzGAt;W&Rma2D7NbG2cJ%_8Ok zXMNs=!j)xRSIkP?=6pe0zEz@~(7e7kzHG|Hvnw{ktfRi@Cmr6)uPDTBr}gG>ymjtS zTtx=GwEtxkn%&73>B^|0C*q;)wsNhS9<_~?;CEnwda<=1osB^!M3sk=9IO8N>0crz zj(>0>y`Z=#0u-_APnsf;UCHP-c|kCCMSwyd+`16aVib{&6b27W3ZqCwV>cK-0rs{w zoT|~4r<<~SF;LRP-4mhoR3h;e1jb%pIT0~MH$u*Z zY0b{Dmw078EZ_bNr-3K`lPTxgp-Ck_10lN`G28X;OorFx{fvMqoX__p*ryLkHpezZ znPNSK`ACmmzpce$N3@0Ug)#s5Bk5Z*c!CJkr0V2qwTh9A4e){@5sdejCz;>UAXz4)U}3$f5gHIf9UGef0bCVdBZ0HIoBNXX0Lmmoco;Yw!Z0zQ824$R-+`PQR z=DIjYdb|ly+xdT*GN*gU1AZ`RCfwmxTO@+l9L_Y0D zoRANV@FWeC0(!p&K+#ue18r#J4Z$B==Ohh8!a&qx?Y z$pcbz18?#en_4sEyU7DE?_>>;X&_^dI^ny{Vx$cRDl-3z6FJ668b8vMHmG~*$K19w zZeVW$Hu+qXfv_4018S(G4Wb$zx5Q#;@%G4l-M3hnxO%Jh@GYvZvQVoAw>dG4p>4L61+}EurYtjlyE!OfDG}Mo&{nEac9qU}-SWpK_ z1mMtRv4LwbQ`AB~axm~07=&tYy(<%94D9G(4NFkO*)W$TfRHodO{qXSXfs{0Gn0MH z?ze8l!X>q1K|0`%rJnqWIiN8!y~Nb@1qp`^g?%!m^?d}tccVe#S~H%Gp3TqBOf#6? zd#p{Ed@{3*o^23=@d#)vRL6BOIL2SOn4ygTg5r9(7l4TGP^$uVBBzA~hy<7bnr7EL z%Jyrz0WouPvgM>pz0w!^%q^s2S~HlSqLIZKe09GJAXcvUp0*|y3x#%$o}8Yb$JH@2 zG4CJN+-($)#=J*QPSCTU%gxTSM}PB%)sN1Ebk4{-1-^|Hoa9`5;4D4h(M#(3D16$t z<3UHzW&4=sloT`66q{xy%76^9jmPA5K4j1&2__wATRf=F6a={bA5|div%{JJjP74C zIWaCkF@VD1f+=zgPc&=O8YXiSvhx!1(-VPtrTB5?@W4er!cya`U($mtW#-w~h1#b8 zRU0ROQKRwAqzIS#9~p`?(B^glQEd5#o#Oyz5);#`>3zl~r375Qub`3~^M-)zb8`jM zVS%Kl8MN;}NEe+z44`Q_bso5ITw~s%T1Px<*JC=)W4WNq&Phy7_cKiK;31dRuq4AvppK-_SlQV8#NssDeajOZ zb3>Zs5-9+IYUAi9r`do@Fac+D34~k|8{JG$YO2G2M%52>w{=Fl<7ZgT%aA#7DxsfM zbO#n)b%^Iw1OhBOtGl`Z!kPR4(M_|m+%Yw9%&xis>dR)u%x5F#ySdyj<@N(U!srjI zE?xlTXeKCVOGr2XJ2rBUdfK_=@s9t++)_ktdL z==-bvV54WJNPFX4C)n3OO%B|BzAPf0AIM%WEYJ>&}!kNc$1yF9iGI&`;@s zMSc)V@YShSh;W+_3y}nd_m6iI0?*WcOMo!&>3>KJ`fttyKA-%+XM*LxXVh}wGr{uUGwOd>4C22y4Dg@z0iRX+ zz-JfBfX@s0z-QI|&>8igv<7`|>j9n`>H|InA}Fil!RU_5(9AwA?p^4|yff}Glil3K z0b~z0Q}gNbcIzQK{!_ns0~vp6JO`fiW6wT5h~h%5f6Wnn9n21R3AQHHd0+1Xn>`=? z;B)T(NF3wyX@SozLWCxF|^GSivL@@2g zW30?E6tMt!*!N&P$#C!oPy*>j-wWLX*Ek@X@#Pkx6C0+KHuFj#k;li-3Rl7Ud5PrF z3nKRcb&N)T4Ei9~c>_mEZ^{IV#l#5{MJff<2@rQMBoH*%0-L#HAc92z#J%L2-;@pa zu3Qc9oVXj|e^?vue7GC=kNKi0eEpzJhFS#Jp%3nm5xB1=QtAmf0)aF>|MGyI{PF^S z$_D;tkpq9}MBDO!r<(tW3UB|M1w7rv1wV`S@E^1G`On$=eD5v$eE0c&+(+vDzJK(7 z-$D96Z=rVmvTE0q5K;!^1q2chE4CZ*fA>Xj|LAd|L)}07qx~QK(tdCL!2g&3biB9! zblkW9bo__^BW@jI0{i&D+OriuC ztCh$zUNQ6;dDw zU6s8c!zeT0eJK}HY)5;K`Q%L#?ns&!hBWcP?&iV*Lg=4x?c8?nr1%2$ zD(*swz<#~m5K@+F2jZfZ?seD^?7(oWUMZtCbJMVB_JfYg&i4}&iNb|O6cm)ii}A4)Qig37WFTGm;fw`MOKd?NP#_+9|^eQRY=;iTFp zz^_Q<5rYIURIR12X9#xyN?-V0i0ieigHp6>!tT3T!^>nM_sy9du)p(MS9!j+>)qy4 zVU`=yc2-JNmZcs!_mNXu z@~zn%4NlVWMef6?Cg-PxHP82eh=MOr})UFU#cLezf-Ri*b}_@!>li+xFc5B-SBzQxy;ZVjdEWw3Xb?u@lB z)dK1kBO4^-q07;IB;s9;fVYdSxdPY(P`mbRe0_gRZ znQeGH9t^#T{2pY<|5+28F}G7I0!GK&{tnHJT8ypFfg%FQ%8$qE@0>y7W;|s=JE+CU z=&LOiYU%clEP7H=K4IE)&Dgq?*}kvUh!100MFq>uL;QmU##98Ji*P(;fGtVJ>UM*k zH0Dbqx7;97rO{)5Vg-k5opNT7MVX2(coyZq@yA$b=~j+aX=bHbQ}fL(C_#_ybFPfe z@}=++pOE&d#yX?XJ3Jf@;75YZB2e3cJHJ&()!cUIJKK^a$R^~RnMH}m_bC1SX8>?O zp5Du5{1M{Wy@EeBDEyp$NovTfe*Y12v6*~7W%ODq3z=i%9pl#1ePBHXSasP_DS4Ak zU5QPRlPcbs8ixG+AsIw^RMUau@khFd_dSU3(x>XadqPA!0!9w}M#FaBMqYr1+0`tF z99_Mlw47|c4gtQ5xq^@9rtJVqeJf9bAbb0L9fETIu0XQv6PF8ATnM|As*mldh=SJB zR}anMzKp#h{hEytajk9qg*Yh`uiL#=Iboa@Dpdcw=OX<)7^dUvcbh~rQ?JyKay5rW8S1$XeE{L)QD{cInMQPaE*0KBW z^{ja2BLd!<)dlFeMZe5NRivAJ9jZEdl5UTxcu=g8NwG*I)=BO>J+S5-6MY%em*lc6 zv!^fIEW5Z~YP0M9^$w`MgpAE_|eHk}|{3~lI~k(Fu9%MVX59hEn2cyFpdCx5gE zy5lC60&XD^zggO(5Ua^zg_G6{XBXngmq6%P#4la3B*4X#s!Ixah1gSf9tFc(KUTmP zxsUaC%upYMF{x^T-VZ%Kj?q))basm|^L|_ec-Ec2`WHh#6K+k)e?RsgxZc(?deZba z*l|cm^MC=w_yYHq0^JYT0ncCt9?@()fnoIf-pCkSEm#kYQ+^4Dkd3~`hVMn(Y>uYi zk=8lQ$~V62Zh{R4zT@|8QH|T98$AX*tTaQO`D5@lsU+iO!+K&!Hji>%{q|IQ#Uq!e z-b@8$V7P?wyioGfmV=eiBUpbL43kJz9ri3pz;S(6E@-_~>lbJyoVjIb`H{n^I|B|s zcq8oO{Kp|+EObP$4v+EmE0)Jc!WP+Q;}SSXvxZ@H}<+2C+HOYkGPXt$YG4KA6 z_V9H@^46D^+pRAxad~}3<-er)EysS49LAQvJWY>NT!-Hx6uTrc;!fRm zSNonjwbBfWQH&0LH;qol%C(J~>ujr<)-JCBE71dWMTiPKUG$Wm+yp5bZlxw5Zo(k= zb!D*+9tq=-(ziXH%?|(A1Dj{aYTNlxWue2wbW|v6e$0p|F}ty8_V#kw1)YDZ(mY#> zbs<&pYl#RjpAkEQix+IAYgb(NcES_QW5tAPi6bFe!!J(9j2`))WyU^NXiw?0sj3<& z;)zdK*`6b8PQ&%MNI~{C^pze_NNCdWpJT>814d1v;|O{x+PZ&)@V=r&_?mCw{ACT@ zX%qL+9&U%&ap#5~aympqm^SKpSIW~q2#}kxu|Iel*;81IyB}5b@t#R9jfhSo$BrnV zU%}Jq$n6(`N&yq+8RkvdSQiVo;)dg~up-Oip!>%JW63z}hJOUJ=)Tg=;G;bV8PKCY zuNn2lpS3{!ax>6`FUZg5Mt=aa^vKWPBRvRh@`n>-q#E(>@RZuFJJ%Tci0HfotlWh` z6)PmR@2;pLwS3ouwZdHOTs+SUWDfhp`0%vAhCQ)l_`ueTt{i zh7n5V(56RhJo{We_7a!fDbT{3H0Hn(Rb{WVs#Yvm>o*O#0BsU;VM|7o14#&RelLE! zd-O!KjcTG3j-yl;h*fdW(nEZdjcmotU9)*NLFVbo!zKdg4-~ zv*N8vqL411$1bg()1#TzkuJazc5lM!`9Reag0)i0Q=@M7S-{2Dw(==RE81+n93yW1 z7(3NB2h;fWs^seBkuNV_zqVB-0JRkIag8E1RJ1*T38(UkMEgBJF}v(tIKWAeGXq z;%?&i!KoStLP0lpu@XbT^*ARYTzrxIo)B)c!L8ckOW}oKeq`sT-uwS{arv(JDp4oCgcY$iF_H^xcPwlg(nu&oiE<~B8LUNa0o;_hd&1-lM~W9e1HbDd6NGK5)8ciSm8QoKB7SS~_{|9Di zQ^x#(oO{rdxvsU!tA=%}1`{(Tson-(7Yys(hCwVCOxc>yybSsNHG?m2LqDuaLkXPI zT1SDKHNz}=$AOyVg9)B~UN8I6^d76s(7IOy_y1fv{(X^qEX%^e?( z#>tO-b|y_|#<+noJ+MkQM`1U`5!Z%4MtbC~i-HXiGklct6m3v2`5*Xswfq-MdkcazfFcKZyK0?mcFFMLD+c$2_+9V)GUl#_Or zF{O-M_M?>b#IZK4@~{bPqqWv{LVO)UNKap`A`^(#5eX(Fp@sH}d^D8}&{OX8l^O!@ zW)R$U?%^>jqGql8lzFZJ1Uvt}ejvoFM~;R=h^pMLzpT_IbNcq)QFxN0w?q#LUuirj z(;rE*Ca*G@ved8A!lp5|Zr@Oe?YzlCP#jx;A52&++mPK!Imq|5K-Ty=c>`TkyKaCg zzh*rWHzUas$SWe2_$DeFE4x0>P0i7*#Z7f|`nWWk&XnK6lkoL;uux z-_1!*ri{2HP~ZPR6ThY2eX29dlAq-C%7)9{&EKLi?|3Q8jtESoqsc;sQnhs0KAGH` z_&2bv;P7iguUwjOmDh|(z`$s2pi{i?40Nxkv$ zb>bz&VId>1hA8=XE!fy>;s%<0AW|gKK(j?pM9?1*QXkvblxm#U0?}J$HgC|HI-ra+ z{sAFy_k3U9K#04n59MoU?D!rH0+TWZi#rqQN!6-6TLAJ#YCOw63lCnRgS>< zB9wo7ig%NeKb}!T-pPl>7Lo&C{WMUSJ_}q%#uGuNMMHN-+Wq#3t+vrdPO1^sw$a12 zS<_oH%oQ=!J>JD?jBbxAHEL?{LNHV^Kv&V~6ktx2_ftJ&{=E!?{5kWK^XGdGQEi2$ zodLQ_kk?3$_Ta|DNj76*9cx|TVns@QIZ5PlIa+6DC^zg@Mu5R2<7iP0+?mOu8e4Ty zTL`peE3tId^nGM@>5Y*)9lV`#Bz`(zQ)OI^9ih14#m-e@Ws7OPc9?!{sHe|4{7pF} ze?9z(gO2knQJA_b@S*KM6~CMSzp-%6%i-dR4Z^ZZD-zn)jFs5rC!9=nu1y8MpV3WO z#7MvWJrdgX9(Um)`^yaPAd9ZRCHmxHwtBItseLEx1`>EZBgg*h)&(x#v)b|ja?e40 zHGxRdZ1^02Tt7(V?Qk&b!((Mw%1C2zk?e8F!-E)c*vxFR81?Z}k9jP1SnP8dOnbb9 z!$;G22!@U`?nG{7hSrg34irp>7|29Jd{dFkwc2@zYTf8Z{M4aKSH>t`mv9?e%7vq^ z+P2En6n0h@5!rbjd&umtD2~d^OyE}TWs^v$$V*JX< z?0eP^%v|J;lr2e>QAfRIf3J2d>Pgf*=je|ql|y+wsXsbI&nBsRx~8vauk{{-*1sS6lq_vsuRLX(BXXpg zOjJql$Bmq(f_7bl4WbIA2xNYn?zBZpCN}#x@v5Ip6qASj2*@=-kmy^BR*Q|NxmhSU zNE+uXRab}UpeYegLXyWabbUzS{68F)O;URsm8HY#i)jnx^=k^G;Nz)hhkPkIIKoJf z4*+DwI`6PWIShUnJ4;tu6qk43{AD{VCz}OA{UYK3QvZHbYLX9;j9j$c3L+A!d(Rrb zW>l+286+xU1*!W>u!NJh$scX3dn+av&?6UNQdEkMwe!%}W9WSHGI|Y2;-4zhnq07r z3def-?YR)0r)bT&RHO2DJ;GxHKzxSj3nu(!;j=`g`ezB0zeK#G5u#HI)8BP0E5Iiym8BUmKi#QV=lT^yFSrjycwb05&_Vl$V`|JHUA=7~M=m0oamGn^|I#$0)=Me*- zAjc0Xt)e&bG`5aJrqx;Z`IfG)Ed`6S)Hy{I%?j2$f$H|u{$*;fCYg2cv72IS%Sa%k z-U)cP=p#1NuJB96#4Kjooq2xz8h4WYtw0a7O9U|5*O#u*A!V~Tr90UwO}1>6jid6J z=_FN&@yhZdp7P0IsQDF1^*`M)#d+NO4Qfx7HmJLET{_esGD~*#=10T%FJ?!=SUi~@ zuFCOM)L9J@ogBfxk4TvuEhxgVBdXN88K=%_trx#-;yE0fbc)U7iiwq6k{uIA#{Cw_ znqw#Q6w&9$-QCRbdGdb=o(yQyJV~;P%&UL-3(XFRoNwi6jV@_~N0KXwu<_na4~(#P zG(M-uv|gB*E?+R=b^9sB7RRWg^nxjP#n%s#3_=l6@5HDJQ!lUN6VojT!}2cew=GukLPCxM)O>cO2aMzjtLax7z+WAQkwV;)os z?4>bsnBLM-L$Mi%m2QNGu+;GPLxbs_7>)x?{vb z_#Z*NC~n~?Wsrh3HI*T|;g{9aoM;a239rlFLV3PHA(adS%8*kxc|Ig-UCZtv{iS*r zY>^oFj_^&7#?B@(MXTVGnO$mpGI3$1RE>|B5JHy$-|MaYAQs|D4R_z&NCrFx%4iGs_n!g}nuhkvv~Fe$q?#B}>=LglfoAz?js zJWhoY$wE@T47+4`!n2@nO`%2SWJ^Zcnw=M(yfof=r%mUqN2*eV+l{paUF2rPF)=~p zRuy(6$OOVt@uwV!`^0Qn@1rBO)g}rM6!!zm& z+bCYzQugOd+Hk#!jN3Ru_M!VXKbz{ycKDF{v}qP}+Az{T9^G51L!Il-Kg8zP3QCU7{U+&ludO zz#rL44jsOw7kV#=WO9v25b*hKDy|{LFdz}AGEmJqJbv78^!ZO|ZIu!T>mEoWtwe%4 zx7Vd_xYwe>@=9$oCBN|Etjr4M)K$+cBMC3i>Pc|(Lk2XJyCvF+Bo z7nxc0gjF+}2X`n?PTQ)x!lN*#s)^MPDE}}*gPAnfn47bH=I@FqO6hl&mk{#2Hx9`S zCc!U2kMf9)V!w;J=#L}YSnb{RF3#TNvJ4pBu|k+HW1SKCS2{gncvcHK2l4U zX7dx<1Fd_wJvctu>+<1tFHL23n7Dqw$98KMi5{tGc^YCHPHDriiD!Jzu!*NftH6HOCsw^+bRb8- zfAtG4&zWw&wd+fDt7uZlzfPy|l3jM*1Q;CW@hd+XU?MwSQfMh1EfL@aw!7w(E@tLiycdorAL zILe}-XJPbO6)NtGUq=|d7Z{f|xXmNd3dLp3t3FI*xWTq*y{%)wycGv0y8qWc2fcgm z&^Nye-=|-GgT46M+&fm>k+(Hw+kM8*1$}V7GK965L(9POLY?hDbM&HLz2?1}Dk89X zLuOu1;Tq#I>3Lws`;^5^wz^TyKxd%?qbUxJ2@b`2pv_R5cIP^pQi5 z8C=M{!|b3F%9B?>B6(QlPHg&vlzPhBTsL`=%YLoJcG(+ z!=iL<-{1sqs?<@cA@w>fOe=MLWFj7Wv)`EHRdfa+mfJ9foVq_$a$r+zEzgFMQE!qQ z@5zr^LlF`I_9AXNe~52fDbn93XM=La`rUs;7Q861R9P9p*?QoVg-lYjtBQNT#XJtO zEEquBemHWw{m)9Cyt&cCo_Vlkd0|5!87Z@=3{&p=hs7$du}{1>r7Z{6ojVkdnr#OY zo!+z#dB4o(E}!rYXZFGH-czr!KKB&YOzX>V9u6?)zAq{KdIt&a^129~^$n4)g5G-X zvO0(C|<1@6z1BD&jIqdrBz z+Q=hnI(Z%}JT}obV~Q)wkVtLjC>Df4gQ<#ZnM2PL(?%9&L1 zrUvVkw%>{wP@{FsDiBwfS2Q_NDEqIIK_sOn8F*jou0Kg4A7xEUwx<-{->VXQCYAxNU4bu-6$~Z~>s^hm+Bd!?R-MwVYJ8Y|9=uuyu;RxnsZT>KdU`dsWxz z9B3p$q%&-gt_i|DNLupwL58fFL<`o)Y8(~k%jz!kX)e}%%d$UTuHZ#?EDO69m~l!2 zxEnKW zz@xr|PaH5}5a?6r0a@l3O2?#*1?)XT2bo{U_75NO|15Hpf(hRE8i4aa<^&witp8 zFmC%mLv8rSuk;swzXUZ!Vf{A7u^CP{+`iZG8Xv~7+ueL7awym6%vGM1HjPEF#9}0p z-eB0Ed0|WP?he;+NIE?ki|XWeGJNh<*PdueYpP?(MeL7#odkJ=pEfCdg8U!il^z#K zQMXAJTSl*8&ao5_Lwqn%m%03d#AkIcEfUw@)ZZ9nDeFzZFp;B_mbczZ^i5LZl$OX` zAKYX6Xl^4BlsIbN*4!O*IQ1ViLSRsT;qg<_1k^IL^}VUQBo7aMy%S|Z$iIx8Ec@Y# z<L?L(|k;bBxI?;8jD`voi?;sci7-1x`c$|%$KiBGFa5W=(Q%%3zhs-xcu}y;GqdK4--jpxf$1E#^rWNVgU{l3vS+_Qrd(IP z0uZh*fPb-JcyBktrt>2Ml)BG6RulwR^S%0jL%Pv{drtUAKMaR$t-=$OB6l9heBGh; zH^T-b`oB$Rxk(-)lV97yJd^ln{tTTwg!Or{!RjPTi1QW~ce<4!e4wRpbkWkeg;6i+TX{Y0g3B1jx-L0D; z9Fa|#)tqqPHTiBK39dPa;6#YDAp#0UR;EsD`w7cb)0=90V-)V~KJFdtt)5_OL*Q!$ z4fuFC8o>A%NQ?396u{0*oU`m;XD=`}G{rX^j1A3sfvwC^@351%Or{&vr?@dxN4fTu zRP3%EFTOJr<9*J$`{Q_1@))K^uv79pDfvuOrR)^^uQHKLQ?2(p`AA1Lrx!vFzuqu! zRwX;%apu2+!Z4va*i<7{K7YZ;Yz^nKk%ic8h6#n)eLbn7$EVl7qoQRB1kNly!MAoH zfOTu5BjHYm3uX9Vc-;M`xN6wU8nGO zyhhu)<3mwTDFT(#aP7c$(NjJvYQ8E^;fGX(Pq^g0+Dk--7b}+tVv{P7VBdfJ%Cawt zr5HD?{^ehN@l>k@{D1CM8<%?!UN9mHi7<$KwrW3Nj7&#vA`>#kFqBFn$Kwxk{4sL;t zvN}cOYq>gE%1QL47Z^6!F{RV7qGTjS2ZRt{hM|z7p`)dEPnw+5_{jn=F^Gayj-ibd z>k2w*22>PuL{kHtIm>Us_;eGjr_2pvfaIxXHB4tyyblVXdAbT}4K)iFxL-lvW_7d_ z(sZ;FuL1a-P-BYaXegM>GS?_}m^aw{FlWLfQwgx6prT~)bn`^SI!R05eO)IxJqP(Q zd!+L;45(PiQQsB9z7L%Z0Vnki^$&a>HAh1__Zg0Wy+dG!NezM>Br=Ko%_|wnDhe7G z+D`a8?Nc_>&S{v?(_igA9YFImvy@cSla!&w*Q>LO%+k`)>nW36!zdl+8ALo72a%j* zIU_*xh~ehPPRfp!fsHbRb1ZdKiII$adMCJ!T48j+V0F_BX=o>s4mFMNG`v%6DOk@j z3}2^7Hg0={k%?V1)4bIU1s9D$MW`d>eGa-`R>qc@_YCta*-?&BXGrr0$WhTxP*Uoo zSkSR##qA0CZ2Zx@)f=Dl%%5o63R*fwG_1ADm(I{KOGd=bW{#0g>%QhV_uf&B2BLkF z%(p1Ua&?U?#U%{`A)r3q3GJO^q}aN0r2*w6!nOQkjE(1<0 zoEb2pfW^dbEYoZYdLkZ4b(HFgSn^95Ubvu=qf6Hm5>K-0iU}pQ{c%AgZujjJX(2d& zZag%Pc71%V5;k|8DM{K^E@%>66F#5zPCOCy&D$%=?okkCI32 zJ5oK37hN=X^BH}qq~pNb^~Rn%P4{059y*Hb1-Np6D%DMA#xs{;2QZH>G46;Z99wsI zB1SPmV8Y8_61v&y#A6Z>IV=$)7=VeC!4thnjM^*_BN$+bq`(s$(5jZSzl-yfY^Z|! zK#a!BI`eB>dA90a8!D1%)Kt%m`Z1lrrhO}CyBhW|z9;;Q2)}s$@-QOrbJ!Sq-_+-c zWVi&XL|yGUJw#s{QZWv6ynE=9{-+}nU7LY)iEnj-5?iwSn!zdl0#orRT(kT{kNzS@ z{}Cg;i68qz_x++H|Lj5OL>=i{rw++^pDHMqwkjyDss{3X zo!HUFiw51e9Z)ST@XVk`INN{@3~)IVvsc3{L}egRhj2QiT&3{JKxhMOmly^b_$Dg& zVA+{%PA4Og3)KChF}60q?Ow~(N-S+YCtc8uw*jr01|YH%@1E>T&p9)%9++t9?b*Yiu_}Q*Sb_}FJ~RhLnpfjb3Dt)NbXh)L5vW? zIJ|s%SGoiQWypdeL8Xe;ojfZ#<8A=P?hz3%Zm;1CYZvgRjY5%C!)v2ixK>`6IE>zq zK9Q~KkCGYnW%!g29{l(}wjsxP1^`?@qrWzgiD`p;ehPNn=L`n!hUwvaK*Y=th~Sso z9KKXb{9!L16Q3Tr3k!H9?oMB9CHZHCc(dJho*ri1y0MORW9p*3Ck_|vwZusu6upG4IAZeLSOFO|ybZ=ZkaTZ`}Q57yrX zkVtzyP4(_h!|lhVdAcn!zf`W8C5!@fD=sm{l7 zX_AclnVh2Wq-ZBKPnpgj-!Z()HZ)p+WP)bwC@C1eHx-_Kjh>=@iH$WkRieU9auhz6V**l;!5%nYdFsmG;ZZ(8H-8!BP3 zU2(R?8;$FYw=mqlTy4RIu)!NXlzMZ$Q85Z~-$-zU<#?mZDcwc)H7Wif=B3+#yF6L_ zP>|-e54oxT?rD!E_?V zVJp@>A3tUqH&4@kX8#?`Ojo*JQ<~}Jat-0oMf3Dy!Pv$(+&``O&BOA-c)~Ia!$0kz z;|RRNDa9dY9kZ64prVqarBiI*LXUw9-~Z67n{oJwZa)xrA6xSEw;zb!tOA$C)ehtF z6Wo3D$=NU)kD>Wf+O8ZsqV((kJ8NE5eBu z3JrapGR1>?%mC_bHkjcH$|A7hva;txO_sdpb?T9fBtSB2HXGYF|gb*+m7I= z?ZPlQd#v#k#u1<*zn$oV=`LMp>(H)g-w5aG`fv{W^~X5=?2`Mm54T~kvYOd4Zu|_< zHUFkenE&;YB}(}6ZvDA3SZ1TiZXf%Q2aVdv5nt<*CC39YO$X|eCg4B!zMPpYVWf$} z1Gugb1IcEIY4k~w@AOHMKV>9M5E<{bl0?VA$rFjMk|VG7lO^W5NSf7BMAwJ?*8)tD zxiA(8JHR89!^slggCq{0s3NCd=;n5`w40E93K8aie%B(@KH zF#E`{oYS(P2IMh^C7=YtoFy|VT0L|*HMc1N&N0_W(d#IoW<|UsDL{lmxOQ$1{2=Z1 zUb;-0LP5z=3xk4e%DIWOF3{u$XlH2UNLX|)Q9;XH;i$)Qkgpr3bNmhsbtY&xoyU>dGVfY^ z(2(0aSU~vG=7)ya<^#i>m^ZI-%Usju&YWL68Z#O`NHojriLuV~7pqjtBKSmiwAE(H zP2H#M%Qvx_O<^cF@CPuSZ-pa*eFo?M7twZ(+Gu&>ANgIP+dyf2h6BI@=6Z<%bEQ_7+Rk2%^L0EC z5CHF^{oSKK6bNSHJ)HB0;R!|goueJ?CFs085oYLLGaisAAO$~-cxYr!RU<=sEe}pw z_fBAPKuXfV-!3jQb<1CP=N9+fBBuMtXrZ(>f2FR1d6MIQHR?NPoT2j48@FSX_a3Ny z1cQd&3X1K1ay_c@jc2=nVVDOq(xt8v!~UCxXw^$wh^wT9TcoZ0fGEsMr38$UGR0?F z9-r~*nM=tWgqx(jzvwSuyDyJ2HRbM$K{78(=!4s?N}(su{RQn7=Z&+cI3zyyhWca| zl$PdbHB4!jXISeOXXy1)lwbH`IP0Vv&W|*8gofJig(n$NFd9MR2ma7M>VyAqAN!#H z{NexlgZ&r3`~d%~^g!O{@z!pK>6Kv8PPx@qZ%68Sv9SGkwV#}Rv=xzIz`LCDV{~#p zHKV0k&%z4}075wr|A0UKK>zu}{_s;3Vr$&id1Lj8tn&xzBC~KmP_>?L{XqmK!90~k zcE=2aNugDT^9$hQx<+YO^TR84@&S1l&F#PR`o6F@GxC>9qLTr}SY-F)=*2A+T_CTori9nv#>+FkWvPx`Z@u;=GVW%Qgss2=h#AL0c6?*e=| zJy6mS?O_QAAkLRo$2TJFFIqiOrZ^2fek37vwN@c=!T;T zqCsYu>e$fa7Kfw>AdNGILLu*_Mk(*4bXmO>f$6>12ec6&b4;kE^O1)0gbz6hz^su& z8gFxy`#s!3#F|fmhgd}NXNxu3sgq?q0O%*JGI2x$}ZT<-oQel^p0UqAOm9ke$S$c7M>Tm z_G_RTazqD%GkTA(GC!f(-UT1(pmy#cx-B3!a%s{VLE|zM`Ehb6M1hnG+_LQLg4}Wu zEG$Ovm_Qn+YCO#OYRlb$r2hODD6@AzSRZwh|3Fs68K=wU_^AtRRu3yj9&z+452gY2 zl!5GoNQ5teq7QaYJ^QftpRjzJ)~I*jc(@CFdV=vnm!}_RARxB-90IMHg;!yZoJS6X zZ3jxrznTcSdvkl5C{Idjpo$)Oo}pr0uPN;Q`>(8BTIlYrmNds5+|o|1@jOK48xgCc zPv$S*?;ge`x;IYGO+lwz`e60ZxUnKU^!F1Jaom=(R}E&0)@tboBfOc8ihIdoy%JRb zW`@Nd#}&~t)@${MqnCbX4u_g-Xb*??og>cY9z6dr9vl#4wAea+*wP^bDReapuF!#% zH-+L7&YE+d_49d`3;+i;{@X`)@LTUSnK7^eRuSINKdqs(mP=Q97iWs&Ko~GAF^lxe zJcKU1J-9E$l$^Xq=lqa=6xL}_CE9US=GpKN;TwwfBM-fp;QK*=$7pUd8hthQ4k|?; zP2kWUXObLD$_PGS8OGI33@`h@$NM_wc%4ZBTUG^e+?vhUnS0t>#9BInWT-Sz`Awpd z=#J4`A85Tl5N|167h~cM)obPk@|M|pFKOfb;n)3Gz*$VVE#t1Dqhz{*iFD;KUNM~u zX6vZwLeyS3ik|Iz38`iSweSf8#f?9D8WuW<$`#a%^;C#jfE=6+6c;^ ziTGxKG)4i+Kw;tK)$w~ki3JO>9I?*@eRrb22u`z4xg3%kZ3iI4w~E+XvNnLi;btnw5Gis zP75>x(y;y*&=9-M)O0oY$tdn%#!2p_Q7}1~Zo;cL{P73LFO~<=8P;x0f?7QsN;os1 zvBp7L3JECSg3}}95%4B(=wEngS3$v!kvp-cj~+iMxtTw(cQV<)#r9ql*zRRh2eG67 zUCV1U?EHnT>8H7L^`=V0Z2K{q@h#Y-jCjWuBIQAmmDp-9V+F_YKI`4pO%(=)-5&%= z!_|G;O65hE3?Kh&37WVuYO>#iwYw@Z>Td+gh z9tfB7_~W&<;KPFW8=>#jun9jw>`PE#meo^Ng~aZS(n9xI0b{PlG-~DIPv;hr=ot1d z2T6N1cyCz=c79r#<;CfrT#V&7`L21II&P*%8`ALpoz&3mVI{+3J;b&!{aa~abTe~< zdoG&IU5!>9qqORhGr6}r_LUs#%`|r(>BekCL<|mj@@E z9xI__-YQKOSC~CikI0t&wf22QqnamU#T8y_dL6CL+?ON^+Z0i zJlprkF}9Z8+iI@)x;^k1Z>^Z{Ie!l`zTzpFAcH5rT;dR4zBXashGEV_R4xuF z)9gBL(A5&*&zmSN(Ao%-Mv$u>i{-m5gZo~{GuJNO*`D-t8$hCUD{X~v_y*&ji6-JQ3-}F9#AFxn+M9^TK{PA=zdat-#>sx*dK2sq6zgrw zN4S(~zh}%}vmQ?N`>t#sTR(bVDf9CF2R9YEMSkI>dbXBI^Q`OYm(#EebUQ^0^C;Ajxkb9zXPw`Q9MZ_wL+ zSULIqo_%Y58bzy%fX=1$yuo%fHAWa~NP+V#Abh|>RCNW%K;=5}%YBH0f?>9Q%-Ps< z5hymP;~$L$q|fu|j+HMnyx9i@0pj0)AHD03NbHx~4@S||sz<*FOi`p%jy<^TA1))M)!vw(nK8_v+iHirahTY0*Yv zmJk+oZj7@AB$1sFmow?-a*7avXY_DSq&?T0rblo(^}&2eKEo4gocX?0_;6n$Y_E>;D^sHJgFN^)n0I_224D) z;wT%^s-iSLOWNZ(>G^(m-g+g;;?K|#o$PRyF-#;7lq6Am_tZ1eW5CZ<_k-O*zXQRs z;x=FJbI#GVPkLBru3kr#_(nXVXp_Od>EqM$jup{yUy##sLmopUMv0rMB)mA)EY!TfW*A-*k%T%vidQ~ zESL(*#RZjDofeig`NJBZZ(7A+OPskdW8Q*ZTNj4j9Mb&1%bt(uM1n~YeF#oaKbHkU+)@8pi z=g4ioL^^np((407X_o`UO?{V6CU0DdF2l3W*$9Lb8VHESUeSXW;Mw_#)!?XveU*q90 zdp}Z_XX-#vchZOK{`7q}QitsQp!#`1==ZXFhvDp;Y5OPNI>s5OtizTp*ETzE(g!IlZ_mH->kWd)IjzDj?9^T#80vVr&O7 z>oGlGC%>Dw9$%ZTyF*PK`xS>wi~%CN*pYYo53w4at`nP@+PXB^WHg8t%JagoScHQTLXj5Gi1t+iy*Mpz+jk8Q3bA8 zFtnQF6VGiX_C%dpHf|GCp3&0MRKrV>5X8ZAF^(XYYevnf(rH?8&_ji%6D*!t@1X!| z1lcf9#FPX|u>~qc$<7aGa^^XeR-jI(H)3c}Jh(p=a35t@U zd3biy!b2y`1h4HH1s4l|G3iUb3zSSKJ;349sx`_6Nq2w)*nl;kdvjU$ybC__vLeQt z!`T7Bv+gKzKs-a)Z3g0C_Abk4wJ#K$ep$QFvRe{wNOUvun9D?jKroMK^FOtkbeTtv z_@nVk;~b_@ppj{E{?|tAYVjA)`#J`-A!1qp@l&&FVTLpN!tnDV$$k!4W`TUkcwoe` zR1{OIv$S)d$L(bUDf{s9v=m-4LC+W;h3XA-QQ}$=^X?HADfrWWQZ24Mb39s}%x;oO z19i5{7S#EpbpFOYYw*VBF*b)i2Q8QeJ*UbMmcZUNAj$H30Cnb$l{H%1f5sn0ru4FC zrk}J=Ps{AUbrCF!|5E*Bwlb=wuRt|mP9U=Ur3ng-6%{<;p+n7WdCwxAPi~+$v*p;q zKWQ{I^dl_mhMKSN-K|7>3Etg~5iF zF^LwRh<%axi(?s_XY$IQ&BdbG-kNP|&_E@!FUOS0NDv}wK%%Ao`%H|r>gkd|+E$L*lVJ*d*dtSJD@xU= z1vc=2QTI2XP={J#vG6@}7rJfR9=O_IW6+5brmy9!e(EE07lJfWAUC-uP+?;HWO=~+ z#jDN-{Sc2h9*z+dZg9^iTwg_>pNE$PtA!=96fQ13%w#yxOiPJh7RD|N0xc zG8!WJ4Fu2kg>UhN=WkGY^3`FDiya zj;fh-^&2`V)Tu{~it(`zAd9OA5EM#T;syo&hko(}`m;d4nbonSoYXNSwFMOhsh+5k z)0)$L=f&2*myw9Sf&StuT$xCja(-UO;s02Bu>TN0|I`ohBykj+59=5Pw2j${S~?R! z1pG)znawoB`xY#+1T+lLvifaH9Xlyn3T8n8>Z3r}h0TWbBm`iLR7fn-DlE+G>ce_M z2c(M{7A%;pH@p~oj0mw17s?EbQIr@_bsXIT9bh9O&IDaLkQK)RGeN3ilEN@u5=c=4 zF{cb~LzxgUiwF4&FKhZ@c=Z~pvbOnLp~s>a)!hU1KO32upTfN zr!HVvKn0qd)A+ywJisuZ0fgf^W+RsmnSczIuuP=`-C2lcDHySx3?bQsFzWkD=wZSa z982h2aU`zo<;jS?)#JlA*^+m)mm=4?$Y^8nB;SB+L(tMXY7+^?6C2x0k|F4sYB0qz zGWKI|dhIz9|WeWfchEroq6SF0# z1X}lP63T?eoie8Pr59c_1Hz}lV|-#sYt`2D;_~eXP!kV+Bz3p6CBJQcB29}S^;t8T zrK8qUF{K^{!V__#ktY&vMA47#{drPbeR2e4l3q=}!6HjKIRX}zM9kNNzBd+po-);P zT4RPhW&TZrwJ3edJ44?*W|TOU9Uo#{OKa64qu~7^5~ZdxZc(Sqs0Bk^^bs`r9q4!= zv>v#i!bSmvu4xUR^{}ww9Ab^_A;N$`pv3TWKAkTN=?>T&a3%tgM5YOLFS&SB(Gs1)e;Qs$Fd=L=W zzd%>aO|-DPL+L>{_6zdOKasRyyxJB5mK1(5(u}k+jJ#W&H2Uh|5`3K}|2tAg-f0*Y z2@ViuW$LA46(MR6e~qJXt!0d=k&ITrD~YB~gsfuJCSw*C^TPpp!v73FeL$9<3>#0% z1APeD2e4bDJX>=}bCCN23CJ;mfRWt=AWz^a0((xGHSw)81ZN6v0Q%d@)LOyZtv9Ep zK8wk~e!0T|IxO7DH0nSzaUETw7_5dfw7|pggK&+;UJnuwz zN(~5^QHkFrvZ&}oZT6$I%DAVIR}-lu@({Fu%03JQX1qR&@r7@Oj-c6T(1U1LI%sq| zG~_ts7h%r`kf8w|$}b1Wac25;Tu|UjTu$S z#POUbjQ(igO+0|_zh*E&nWrnMgX>PojOyw$Hxn>Pgw1+$3U69Un7x%pG8=FHgOw8C z9d}4L15B~CUlhh$KW)+}igkq6c^hhfoHIHxl@5dH`2U~a6+d{O$EAV)Bp>qO|DX@_ z&~lFuXnUpnLBlk};(9#<{LgK8uITSkx$OsuVR>LTM!dWc@PiKwUvP>hk<2CAbAchK zr<%W~ZUntAPV_0@YvO~;`UjF6bC87EmF4jPPozp>Kc(!gT<)Jh{EpqCmnG}LhhxJu z<9qheQa7+>{Mr|D$UjdsFMP`rJdYimYMn-eri%r~mKKICaSuX4fK7N>1=48vs)%_` z&mDbCvM7CuPgkD}q}$k=&$8w^MDd?72+xuV96$NJ@DCoX#h^D_%nN6kr`RG!d4w#2 zd(dssSa(3q7d1gbs%csa))#!s=?a~9gZw32i7Y?Ada8^)s^z`JamUi%y z=>kD+_-lSa?L*Jo+nuMljDWQF4~$8tz98F*58WsDn@NX_8UKb4OGAXE_uaH>m)RlwQW^VzU{E|Y z^W)A&pK-58ROC}>+)zTVrN8e%!7*Gz6$&OD(sXI1 zXpm{uY5+dKrNk6PRY^rLK|}~M6=*1&MsfMgirS{quE%BWyUts>Y~0=nJ3@pdO-9L9 z5L9g!FIYEhR7V#@`}_ajzRbWvx0~Mgyyt&A-y^;kd`|g1{Zn_lwUNmiZWqww;9^SU zP3uV&25pJ5T^1#Wk1!k9XtdD!!U2(0hgUf(2r7kFM%Ok@=K7C0)fEbO(+!DEudYo@$7;(aZ(kIgJxUFb`wYi1 zO0peqUl{t+L{^G~=F^Abt7)Eo6Q_M?*%hYvp)9>ST^@NqCv;IKmq{^yjl$V+3}FsN7DN*J(Mu4+7zVl<;A(+MjLn53fMVDk2Zg_O<`C%1-4B_&nI)h zIq~IZl%kU?44520{X1o6P1Yf&ndO*Ze@;>AT6GUvr!3<{+HQV%uH&mT%@KXeQST5_F&$LClVjP~ z7P)uO<#K=1rurJkzh3?uhlhNKar&qwQzwOq#PxA9ZKYgIXnA^D$M~Ovfr+x{BNKyv ziM}*daGT2%F$9lfo>VzYE8?KTsi07WOj_a`PNc4r@>n7(JXQhySQDn|u`N%_f(#;s z-ecCu-^eboKZc<(FiayMapnCDY!N7DvahDwX$2)u?DY3w>W^ZGbnUwJu_a_o&Sh4S zGt1_ZqvCkz1n}d~PQ_GcC~qy@aEpKN<&iV*1bG8B)UWcMuw^{H6XYwak^<~R);}+r zqIsu9#2v+wx*K;fj;U?K)_P6XgtO{hnR)K$6SlG%c*l z5A8h8YP(d2%LmIqt%KtH?uSH{gpP!ir$fnV)cyV?@)l(l`CI%ok>32il`c|Pe6NPW zxOa$C`Tt$o1}v2nus=)z)t7c6GEIT}=kb42r!04SFPrM5boXb#iG3xNL`&sn<#2MO zWd0^h89m=s-24ruKSD+*2nt4>_X7N;o znDm<>kG$3**(=9b*Mj``<-zw^lbyEAH>}0VM@}69VJLZ0M6u8Ne@`(>gr0oUPU@#u zc7qZKHTy9EH}&uh{u5~B+@)}ReHSrB8(dDq3-udbsM*_@msPPssqg&~x^(3$n&RT4 z*7k%&7dTw*-vgcQ{}(QBPlEf^ZLI)D;r18}7G3sb)9#f@Bo|~*4^De-#JZp4iXBh& zKI(Hr>q?;7t<9&H}CsW zCd;F3?)$p8NJAU~D#m|(kY?R?_t++F0~>F;w+z-4(DwvzyrlPex5r2-XRvBV;M9}B zsVerNKu=Dk6}PcNq9iig+^F@l{xgZwlM^TBZf{CSxIIN{^04dJD_v=E=(4O9MNqU@ zg+{GH&yNBs6GZ4}kdsO64)QDC!8f)26g;e}G<_f%gg`5UQ`XTVtYokj>ULD8~~e191D#Kx|QxDD*PNu=*Zw=Y1((#0^M#7AAxWiM6f&%*Go2s@~Y;0eB>DG zK2hY5=lk0==(CL(_1|Xp&lIRQU(MV)c8Az~&!7W~ZWppdq_nI%MWPy7IA?0%o2Lx! z95cM$OsGho;`YyxKC5ks@8jT*wapf`{Y~u2Ew}N_U#aPGKt#U7iHtRKp+s8vx|{qb zQUo0*%$Y?5YdL3dI(;jmV_AZ1?i{6gT?#dDsF9rwO&|j88q1oT4s8A+&hXESH z+%x33XL6s) zMgPu?`^)~Ei~Yh*lS$Fpg82yp6ngMozLMzYrUt}OD{5Uac4MRKXMed&o~W+#Z|>Nw z?i$)^>Z=IP7j8p3k4*nh7UiELpt#s47^akWFC>>El^LP^T$&dmSjRhLu6YVF1w#nW zlXjk!aa&rgeD7kfv+PKx&g&@|97a-JUztnAOr!&2sKIn+qp(bLTKM{>#yl#t)e(=p zeq-X#C@kk?eZi!YWULh# zQ4Om?43^e5-OD>NwdE{fHg9xJ&um6fVw)x}uIygq62j~!yiwqcQb|U3t*c6^lxpQx z8v*YdW?dtS^SVdqmc;v*z<-La9Cdf{uV=}GetR@gZx^N6QQxxY!ZQZ=4IRK!~GLoHG8~a z?x3d!5-N|&r%f+iO#+Gh2tE_WKRc~D}eurx8571~yp~MxX6ybLhwODUQxd}WimI&0I zQx}LYq%EFg45*XM3vZ-Uiqv3qJvL~%9`N$rd2|)&TB42K@Nx6L~}L6jNXW zsza)K?7I@txlXnnur=dbZS!W6i#$kT&uJ$`{xL zjv&6UGYMs9)F3Z)T9LItkxd53*Z{`HnhHXGdt*RmG3KWj6+RXWXhUNpC+FyP!b?`+ zr01#Zq-n8&$BvY^A4>%!Il`I_LW5sBLLbW*I}w4gz`@Jg6EKi$)`m)ii`A=6Pri}0 z&<0X{!~GmaD~>iUMW)rH`cs=0l#$>QUI8+%!3& zAkb1&GxRiiLCE=Wg5~^#y1K`%G#I~aw4kKYSEOd3Mo+ow?K*skv4IB^jcDfQs2ZcA z_#Uf{Q(4N)e=$}@K7%depFN02Da;F6-{FDMT0nZF$qo>a-387k6jbHX`bfkctz zHuwOs02lHa9Z*>ry?)PQM?%_yaRK|Uc_VIzAQ#u6`e*Y&^2kXqnn?VX+5!>YF+Bo0#@M!Q}#y1_pMrO6$GjA zqzw=-*l#lk6DnvT1V?!ehEjh6qKF@}G$g#;8%hSRN~D4{AR@CNgkrs+v5JHvfCv}$ z7XVXX7`|EXDH1sX>Ikp$7(lsmV$}sMp&(DtL`jATn0uyXCunxkpslxyMYKp!BoUlfcHwJkdiYFRUY9?%dI!)=xHW%_Bw&*vvA9 z?hOb4M?SRMwMQOG_9+`$G=8@YMm@=~GSm`tZD!X6`%a6=+%OE;v1))a2jS@q7Ki{* zVS;{AQ@H|5Yqmmsxodo>CVLM`=MjbLr_rvj_~{9$0$&ai7wPk;1PDHpqoJZ|0Udw` zcwm|5ppx5ApxgN~3F9hD;ptxKU`??Z4+6k0_-OU`dQZDHDq4Xm3CTJge$0U41^h-B zA9(Z(W(BtE#r=L59C>t_L!2nc2FzaB;ef~&H6^#6Yk9^<&V}QwFbNXLv+Xw$bUSJc z*xwf-{^tx1NVb>*m!oM(NLWF@0r0^j%SC`mnkvD=T5-bKd_EdT*x70ZZ6@g(QM4`{ zVla^nNlQ#VXJl+(2cd09(6pxTwZH*&h6^b86`c;%p<#CTZ^6Oc!mfaS2O8Q17R}!EYavAWs3`o^}A7 zPQG4G0g08BIYj_(8s(3R^py-}9H-y$j>f?j;lBOX!qy7PJ$wa#@Kx#d>);`Ls{07q z@{7JNSGTcteW;QQBA7cUw+GsH*UDLL!r=`8$lZmen3jXc-G!K%ArhKIc}P>$0V&TO z2)RAIiv;Y7E1s18TG&E+x{w@t;|koWf2RCm&^i0%H&*@}7^S8Fs1MUj=!$3A?50Y7 zu?bXHwPqp4lnG4adxg<)x5$kp@dujIcqt$d`t699PIUdF9IU283AXQJE!0=|a|5v0?qm#mg&nBj12_N)yq2g^m$sB! zL}tU|k7M4C-8cT7j7$<*mR?rrD(CCsS@x3QytYxyn~A zlPQ~MukJ?zUUuV$x)n6BzTJ1F0EfhK*Ehw@?_~Gswkt!!YgdZ2nc~vy&9| z9>to6|Ck{$UJyX;5S=o~UN}pWcECof9`OZM)?rbOh>8N8o0*8usg`5O;V?Sg>wvlhbztm=G&~n4z9-%nXFY4r>$3%>5ERct6fRbUOQ@*4II0aPQe_wkSrltfVuQUFIWjko4i=3 z`KEzus^c3v?=;K zp>5os_AOzLIm*MaSRc(=+pRzGD`->h*09K)yjTcuGW#Mo`+Ui2$>nb~C(t(ml4|M9 zV`e1@m={&tByD(+b$13UuNBK9Z3p7BcuhMA8WQ^@!a%Waz49>a%y%(Gxmp)>xg(kv zUIH$^XyDy3`Z0rtB%zP|yB>0z#JUAayC_H>PDzRQSusW6k-jZ#zy)&>PSCjXO5rC` zqn+*thIX<7Mr?^ltITtRHDqAkXb=ej6np~2K0+7P0e8h}s#)!X#-dH1ApaQC*~d+K z-eI-QU(Np3Zn|Y^Rif~WE!mi&;&ZAs|3D~E}MQ(#I zr6o*KGW`Z9#9FxND5fEFTZuTe_hnyjE2pH3UzW6S4HtbSFCPo#*T+C#I_vA@+{wkR zE^YbqJpsyEywVhv{83Z<`<`Nr>{zRy-)Il61hfNOaw;1=ajxKvc+pe=X=tGbU7KqH<#n^r;e{oGS*fRSwaX!sHOUd`6j zX;7e5reWNUZQe8L2(rT_Y`r>W8f`B1pHWz+5T8Brl=R9P7NgEYPzPw|h28HoN1Av0 ziddr!1@Ji6jp?2!*KScqtPhe3HyWR0w>sB!k2 z0-LKG_#3+b$+kG7a5mmq-dm|qr-u$w;ocxu7N|BcQUxM!UV?8e{vz8=;3TIy?wdx9 z^||UJO(cqyXkCRr+W|(suUpjj8uhn*Z9lJ0gikK4fxE@lKwaWvYwqA{AQQ7dgy&5} z5?AX`|6fJgyoWFpTfIP=5y#19&LP1WZoktOkd09o54dD@69iPn7f5Z_C&)zV zcm2!=IM*2ARw)sk=TOE`S@}<_){md$NmkVl~BD5Zr? zUqgiF+(f*wqNSycRV=N)^B&@YU?q0)h>x#J!IU&->6AmCet)|t`Om%hvncxO|6HOY z>*@bgp}e8@(*FrZ(e>gua)^(wY4=JQ-=``6So-fjY^PQ}z2#)5;U8Y-)s#1>`=t>d zUrsSU?;l;|T%oV{l8BG5Uu7t0uX0e=7IKfH>*>b3UL)<4eSHVRDEdCW-13IJsvED- z8hy}&rNWdm!S_#jC~sJAxj*y~YQ5=0G3AUrXm~RyIECRJ$)KcK&`W3U(N7d9$xYB} z+E199oirG)D$;(5b|9X)#mY$OX6WaNCJ9Wlfi^YmYC?GBf&np-k~#_oU#_M+mttoT)v$?c#ObL zoXw)nB~}!DEjKkuDQ4U>`>#=KYf6l35{zkeiZQCw|C2OhUBWS|J0JJPq03O>IZv`9 z_lo2nt?|a{bVPBpy%IRzzXDn1-^BXdKDfP4BG8ljGLAhE#0gkhf;@Gy7aYfGSRr%n z%4yxZiKlKRuVZcIXMBAbam;MvkI0_>7zH@Ur@x3VeRF)|18j15=P=qd@ukP^be=_} z+$z=uy+ws;b%ahy@yo6^Z;{kbvrUQrZxEMjBlf)nBMT_yo#?KpI1wnFJ$xTA6PM<6kBNhJj*NcDR_z?a*$%@^ z)^{Xbw@n|&-NRxPlvwA&T;td-P#Bw-ZxR0`Cyhoy`SD?(4cQ(|boj{6@Ou}*yhTUg zP(O*wAhfWsSKR)t3eEltyet*K!BhR{>8m2uPK<&lvLb+-4s4x%eFa$6G_PNEkAEIe znr+H-xGBri)6b2h9hg_5h_0Noy2I(Kr!3Avant}UBiC>XJ^wKLR4!Q5TisU?;-B;dJ-_F8h%$vAunTOv`JVPEb-p|WEfGd?Ds8M*gh*_p z&Kvt(&rn5ZC#W`WZr=CZU7dkX)UM2qn?IZIJW*Dy%ecRmk^08?SSuSokd8Oy=f7Cr z2@|^G=5UrLtpetWWUB(=2xL!IFPH_HodzHE6CP37nzbZ6~=>@X-7QLk~Sj- ztacZOf}MTGqgAXv@rtM6FM=&@i{G8*=?+fXUi8k|`|tD|2=(d!Lb z`qwi0)rzYb(X^rxj0*&UHAh)a*ap*OnT1Y%g3``mwO@ikT!>Ze|EwEqo0e}X z*r4cyLPyHN?Fs4gYPDv`AKsT2oIWu9eqA15UX@pVWoXK z@~B=i&_!<_>DZNlc;j5aoAFwW7`#vB%{y6m6v@{@Y3ZZV{6mK&WzPOQh6y~ zWP9u3e`~Bqx}HdeoG@=6-!}Q{SCWNheP=A)1>@vL-nqXSbACGMR^N8Xdz7tZ$Ch=D zW_Sg%C1DJpLAA^u1fHoQkYDqDBZ{IW~9UookTeS^a+X;X`&Je%s&^^Rgq` zz%?q`5HMQgv*%}#3?IJFyiEXuKzzSRMD})n@;PP_MVLDf3(Os*3@*(t`ViYXt{=9EF5!Db}QS+z%MPKvZqCC+eAo>YTdWrDRz8^C71rfPPM#=e)6{!|g zIBall@z^)(pFX~y%U3^Qf1iFjCRL}&Q8eP}>G?iU9jY22aU+{X zir$-fBN=5Qo($I?*8F$sO>x+Nu)81oi_)wwWdQ?V^$YU}@5?3;8a@%gJ|8Qjq5AK! z*+K8>eH|eFH;MLYiKnr`T*1+jOPn%YZ6vwYN{d%4Z=&bX+V+;xOWjf~w(r-~TS+iQ z76OYDQDP{=6&{the+^aN>WUyT--ah`Ai2~Ph{5f(3#zT87rKvMZKxPDg9lOUEwuv% zk6!9kd#MIC+JS_}uyrcI)Pyy*q8VF}QX<A>Q#!PA3rYJR~9jn zvW8T77E9H#h*tzfkjlgpcUlOw;-eC%#nwwbG>yf!g9ZG$F76PmZMsgWV%S?m#noFb zi*I8MV7ALvHU!3%!#ngr;s!HkH1#tMQ3`YE`4P&}j-9A|FSn$6$MO+E1-EpXOjG#J_J?uYv%exEPBBd@ z1ZegLSy!b#S0FZFGiTxxAJ9;Fo%d*2aXt}&b&wYko78yP+ zcyJeD6+8GIUHNaz%HoUec%Er*%j>e=iP$R-{erQZ${9yUNWQmk>?*9?dz}PYlPFZpb?23_Wi^jmnt@S05F%8)@z{ilSZ~f!f)qOP^`vs&iExVeuTV#kMKbCb% z*+~f3tB|1b$?ca^+kYqZVrpuX7uojTIF|k)^pq-Ph&@#08Ij%vLb~)`J*S(Se@>PCH{GA->r1oV zDp{HbW!e3Y+Nox0H3V6NS#aX<45U$_2?SECr^RL>mM*xF?kfZWVW{^=)_Y$`6|kYB zAY=oPhs9z3(6-tascm&5Nt z?VaqGr^a&5)j61h#FUQ#F|{^q0|^zxEPYtBCL--tT%>UCJ7lgwr~JVmm@O#x-uFpP zA#9Qfh*R_Kj6pXacuK7?p!@Lz$Zx-)^@rI8WQkhw<6+M7av=@mJbABNw#$%d5uM zk#%xaE~&rfMb(}AA12?9ymlSis{S<4#5kftUu-?&Q7$u3SXFwJjG#T?beaFwNyoO&2( zx2CKX6@qegl2-!3g}pZbSa2LAb7Ym!uw!pczZM(!2_DHS!C?(=O}-Wz;MH}KSEH+} z_=KZ6*ye=_&6hCCZ>&CaE6G#VzlXM)%5QJ9z3$q;G2(u*!D% zp4T$>&TMf4JT1QXqkV`|+*b_i)jEPK&CbWF?V=gzO2x`m>4m26#o^;Wpd-e0>7`|& z#bDTaxq=q5hk|(sB8q?qPRY5n*hNBI_i-W~-I|kSpB?W@0|DmnC~Sb99YpQL0bEc%mX? z%-$dJjiiN!IYtH#6?j?KeA@ZTlH+mPz{$|nHUu1~vk zMoA1>LE70z^|Bd6C$R1KXHW(?s4j|EbU}ZjAdDHV(bzm{hoD zac-5u)(+EMQYCbtp09Gtx1l-K={ouPD(I<~VZ5^`Te)m1B+8vLw(&~Z@w`! z(fi3ZR>>V?sQ?$P0a+i__yJH_cfyQKg3SOSBdAQVVQmj=6*f>7V4?;qZK@C3hzkiG z+f=Ltgs!c%LHbm#ZNHPLCN|opB~8;imr_vH+MxhK2%-SK(py}}(GRM%i?))9dyGV& zVY0b;*c4T^sw%5l)n)v~n@FH3qGs5E^X`M5)9Trn{?BkwzRJ~Zg>hfHoa`CUdHY@2mZka{&qk% z?(gzY=3?U=JU3a$cQB&@ez7_7X)a9F@mKI{wlyRxWaIP6%dQA(RlL9L)ID;~XVk?ZkkkXm^80iE z7Qlt5?g=LC)n;|sOFs%2!e%t3qP@tcZ2Sa7+)kYg#7D*{MGZS}_RZt#Hz{1Ih+6xi zaDwIbq6}KE@FfBRgfqZ;SDb{eOo_wyqycg4^pvOD#t7RR$M&3oXc0YRe~;1W zC{qJyK*8f})Y|RU&>OOKoJ-OgnS*;9+kEs`Y)#Sn0yvtDoh%2w|4=(rM>kQmtCX%4 zg4v8lw77e%1i|CB^HfUpMt6|48eqVGFYYK#P1qxley7n~oU;>Ke*QbOdxKXU98U4< z1S=!+y@3)d60XmM-&Gl23=n{d^WzteS=o(RCS>bWZDx&xi?3W=Cr|zMU5Vh)vg}Y8 ztSB2Jr~bk9=lLYaKD?c+M*D^Oi+%ENH`v~LH3@#V=gj>mEzD{mjiY2WyZmluc&k*2 zO)e?n2OdkFU&XysQhGXT*Xq0TRo}<-KZzY4TG)<__2(17RigZ1Xg=HMARJY;1o9$g z7Zfhuz>URVD;@1Tjt%?R8#t%1JC;{nqSMmt95c1vOsK2x6YX#f)~81zW7Oq&z};>h z#?Ifz!4foPXJs0`cUHjsKF0k@y*N0RTGi`&U`ja`Tj%#oR`(1^ju%oLefpc(l8R3Y z5q>9%;2oyyj?xyPxphjg0Cw}CZNCRUnxwm#l7`(4&nejUvf`C7QnOCOQhxFruyY{r z!O8-H_sTT!fwxvXN500}IVoc|d;*`)D{F)Qr@lof*W>DywIfn1YeVWT5X?FBR|E+xK!?^ojYtn&Y505= zujk?V*fa3`Mx@ktS@FN0hwCDK9~4{SAoP<0AS90A5?KjtHKNxUuh-H{&{7MAlZ(YU zDjE73I59&=({9%m3;SI{izMs9-QKUj)0p)(w#FjH1sz$jSHwcbRE~MnKk2j<_M;WBS=yK|jiy_y_noF>eZN zY@Hnq6rB#*f=Y$815(lQ<0}bb>Tk0u=<>xFnhh!my>$CY$c+Svr$$wBJ2l=t{;|gy zb1E7JrIcTR!$5U)g+4skzV)k3q^n8ojO$vE$Y7q{Xk3j1{*~Js0!#`lLPZI_wjdSK>n4Rt> zX(yZ^UD^e9Ur)+Jq)mVpDW^1g48XxI!Ve>ca1&W4)Io%b95-Uso`vk-r z1v5n}+)$#)3w%3d5VM<=Wa!ak9LX+JITlC)!2_3M=@zm~_iiZ>mju5P%S_~xWKTP` zm8}gR5cv*TC(@e(Gepvgc(B64D+PULF2~anveJpla;p(rW6QAg=D&*$ih<4E^`W1N z$NaknB(iL?jTs?X0IFOH`;J|Ys3g2t+tN6tr7R%gz zVCHCnOLUG&Q!cISMvQE<(<|`L3_dZ0%YoAz%>?tA@^q%iSr}>Nc|Ba}O@B+Tm1wLz zEi&$ZMpyX94jfWah;2yB{Z9qU7j@7N@cSYtkAy=$QF!&xKfF5)P(X}XwSKE)PX+aF z$QxI`kRTZjZEc?oB+7JgZ%4)JpLelcF*Ej_yD8`dWBmT*7w`8y) z+Z5|7du>tvS>?8u5h;5o%4-B@(is+zd&~HdzbxzJKuF-B_3OqfJ$2o4Fqu`bkaF}( zVjrDCo7`@j>AT z{lC0Wcy_+fg5UZp2ZcERms(T$Sri{GqaE18Dbm)VQq4zetwN%+BTiee=bU%OVW+~q zN2d}_MU$w)(w!+z_nDhh`zZxYUQ3e}wwI=s$6G5&?zW=`1;JY~0L6r-UhCqV z?U$Y39ly(`@WjeL*d@C8Zt-o`*6Pb@e?v%aa5~nI^@#PR-XnVBwLBtD><`e69+dI* zfGHjk0SU@QvM#S9wfiG2cZzk600ipSTgHuh`CH$7i~ThEp5I)(jBAX=*J4|VdqTG1 z*7J()7@nDY6*c!GbEkKsiF(VcBP(C=#8#!0Q$JU zJ1y*&0tzRC!T>{Gnn0I9Emvu+14q4RCXaw88?!++c7v4i`ygjT0NKcNdt z)h2?3P-YxX(3iVfNz_x#P*8_}7~O!Jl465CS0i>#C}?Q(CN@wKzFzXqvy=3+6Q;@j zr&FcxnV+C?RU1zCl_Fhsrexb4M9HB$O*(_$Fc@PmqH2j2^uAkDV|>=Ak#A+dYP^ek z5k^uivGiJ^MZDLX)ZPgH@_hEI$hRTuHAIVce?wD1@|ypN7U24Ac`_~C)V1bFw{hyV zHrv!{i5Bxi6Z|AwgR^RATZX8SZnC|pnfonGZ(`MX7V|+nV>2v?7UnoDSCMZ-cBZ?i z3tx^A_u?Hrt5ZQA`Kz|3+lB5|mn$a8vijn+&H1?+1~noNh{w> zb|&}JAB?^9>oKF!FwwHqbdC`LE>e$0k4+X(a=~gWfTF*dh(UX)st?xVB$OghMtMf+ zkqAVZY(0Cd`Vy&C?hXp!E`|RED&spk>V?R}CK09>BGCaSRR(uQfHoA+2D0FS6Q7i% zaXRJ4IBAV!$)loJ(GqVuZ4jkpd!*>5=MAhYWKAqZE)?4lOM*t(qJs` z&2T9rRom3jW))W^bOaSmDI&N7XgQ{av-jmqjpte$Q_!?FyZFkQ5QRq{=jBWq#$8vy zeixGL1wM_byHPIYaW$q(9P`K-fQi~expeOrY%PJ_^_+-y4IwfbQMslCkZ$D1!{8n- zHhovM0S*V%mer}vALHT?g|~vHg%u&kIMmeF3YT^49oDdh+7qqn?5B9}njLtO1oNB% zXrJl*_pUNP>2Jh0czk2g4R<}fNohab0#++YiQW`AZ(X-6sRJx)Tjo+VIX`g_BcigJ zsz($(9Wn#5J7xa0(Mhh4=2t0CC5k}_qzCyyF^^WoXM191n-_YmiyQaYu_a=5T*^M5 z^AVBBrp6+exnO?g_L~}tV&<{iie*S&4$nn$RzUFE6v9}62oBd;50Xm2tyZS7&H}$w zh4ocynNbv~ptLV69v1Vx)gg3Bk@nRyh@|5`FCH7+QdO>AKhdhH;89}6L{s4Pg+P^p zUz2l=)b7xf^3*0fI6LgQtN#3rYM=6=DTgZ8xkf+XM_RRls#NGjmZOd4WjK{o+>Py( zlB$PKdq*Cak><0^6sIk!eXVjAoV)FAh>bQSq$A$ZdVd{yc(rNq+xntc@+_R-a$*sed{$1rr8l*-`#T!a z8ltb|F1hyA5MkD@1HU}>Bnj{DpigG>pilj~*pMf`L<#yQu^*>Ht(h~GCQYXwerB~a z`H}BWivOqS|GV`0LIbcvr{|Pe{Hng~yzLW;7)ak73TQ*Fupl!yUHr+gD0NK@9V?6} zjZevS%Oh=8us59m_~A`s->YEk98!me^Tx(_6DGqiiMFG4O5lJo!<$$tIi>0mevdSO zq{0>Xdqjb!#U2%VLcq3jW~UiZKR-W{&N-m&!W$a1q)L)3*}6$XYI})5=knp61Cv@@ zRaMmz%etbS5*^wqOr5|!`RixzTU@bQ{W(9+Ws zg6T7*q!+Hy*e_VUo&A^xSl7*uvt*8s1D#Oh@{eMyfC2~4_8^bLzCod<`74J)`PBM8 zkK!qWp05{Z{`~&XsC*3utv`_Sh#nnsrok5uqQIUcRQ|)lZ24wym{uu=E5$aKP{JwJ zXJ-5o1n(ggr)>EIGENIjH&*lVK}CGo`smX&(WN#BP)QpGT@k5hoz2aHO-rplRA5#P z@>rr1bjGlECcliXD4`rCrjixCxQkN{qTYw?OmD6f$;Z8S+v1ALJ&I2!(`9<@e6sAk zd(IA@o2o@VKfQamc1+Kc%DUm>f}a{10Hz7W8hUD%II{#e7gPzdgqIfQPqEkbP+MIrtmmfzN-s8<}jSYUIO| z-x0#juO%6`p`&uosb-3Dn|Yk;mSx%&3YeeI54^=48$9cc3pyYGC7e0(~t}=!VNs_serV@lT}E>`$$D_(JdjRj$AfE`r zkck&vW=S+EQ_7>l3IDWW`A$26c=Y7ySE8a7@81z(mxt;Co=48&5%+d}dt!pW_ak0z z2}pbmn?OQiO7i6GJ^(d?G$OJ;X&(e=OeA+@eF*^Fi>1H!LCvK43$Uk4y68%m;T<(o zV5~LUhhwe2@bJ5ezTlz}SVzeE$lv<1o*%UAkOdfH2oX_7<3877n;7<9C@|Us-&nNM zXLGwxU~GcN*uLGCp}wgvoy3Uv`nkgZP6Ue5%wErlkU0y^sE#?z; zKZBy;Ll9r5(;__zGJn^^Ul+xUT{WC-4-y$hz>iNGyccT6uIO<^vrk><2i<$Jgro}w z$x!0fJz|>Nb+lfQ2ytyV;TklNNj5FUUsH^O4;{Z8i1t61453e&M&hc%r#%XmfFpr> zmCOrXq+0tk`v1>{Nk=z;MqHRu?N#jZdPshM)PWAZ{TJFM5;|@yQ>erCfaTfE^l6e7 zctMJr7oK4G3CnlNA|5m}O)Z{2BEyjkqiPvvm^aI`E9wOMcC3}u+&H7t>DA>#pkjw< zT92zL4%VA2zGp+o4AcHt)hgFA$cf6)`DZq(Qp zs-6dKIZUF3$g|Sc@*)Lk(`*T-FpuN^p>(rl>=#QC(v^n~LPDcvDmsm}#S!S1+2%xh z9kzL!_ZN1vkVlR+`-9rfUQ`p^+Ca5wc>Zz;awh(O>R?*NTa20es1~!3DirsFm@#Q{ z2SaMX*ufvRfIOsK)G5y*faO8Y6##R`!WMf|6$tx~851RaSr1f(y&93>gvIv%9TquoEYtS$>;4a2_3a) z$SLYJyniLEwVb)AwP|wwwaI7=t4p`@hYJLAzeyH>v20efTng)l?XDlRyXD%+x1e>0 zoBckL!K4Dnw`7diG`A#dtsMxn=yKtySr(AA-Aa>?lx+hii{N*iA6)r|jfobw(mpXq zI;KJHiGrCIx<(G}m^(WRo3EHP-RRcqaDzQ!O*dfk7%l)*JFFx&kR7zQU?-*Pooqn9 zxmf3&5YQgkZ9PvT>yf7Sk7mZ zOSEoFMlV`egbY7cy4j_3_R*!GBY%q5Y+|+9D!Ktth?N)%+L;!v!*z2F&~a>nfznN+ zRKTd0f^`6BZJB8L1`UrL4Fp{PF4{k5TZsrZ3BquEKw^*Qx4$A25Se$w97a@<(ozi2FP>Ix1z!KUBo zYSP{Nr}n)KK-A9myrwdS+R8cRJp-fNyJ=zo{JHhS) zXN;~#cVyTgck$A3qML%oe`nXl19M(pzwQKc>hyADU2VHS^`5d~^ZlP*n(asYCxz?p zWpUMqY0?w5t*Ds4=qda}XzQ8#YAiHQUd>9`bU)&sT&w;miHg|m`TA!(h-KZ|R)>jh z#lyf1F-!q$mKxSaQBW|#^^H%dc`;KAqhq~|)L*ABGBc1g(Y^0lN=$aUJe?p_GS{|= z$95(+7B3HGhsoIv2-ly#bHs+-^sJP54#Orr6tTx}LZ9k!!5Sz80-HsdFl$_#zfmhC zAf~9Bj{7vq`RPRRHJ+S@jwmfSxmhMb<}Aa^S-;20CG3*2QX-x`dT{g+Q5#Smdm5|K zsc=IBszH0C$!0=#iEgG_AcWVC#`}dWijg6>B&`lG|5VPba+SS zRHwKeIoGpN3s{bdmTFVoqrym7peDtMz0(5B51Y_&A-k@}_Q(mHNB7Yqb&epD%P9vg z*L$({pO5NH17$yQiXb5!fs*OlK%! z$`Os?I!WjhVvU}B(c1o$d+yOkU{IyWjqa0vp++43RU7FaP^EqCPC+#+MNE}L<{QV% zDW5Q{Q&UqX7L0=)qIhp0_0QjO#PV)Zskvkx>3;m)M7axz71+z`kw+{j@mWXbrIUBri773@Aj7RbaK48z2?!r@L+=xPgE3AGkpI>UQEp2%j(Ko5^{hFGDA?zl z(d6#BRR)-ohWpy$lqMt9ped$eq~jp-h@>)7<}Dvr37!t*KMWSU{zch!1UzWsaksN) zBKO){ef5_JthidT<|SpyD=u$q4*p5qtmlJK6DBWxbwo?yd(+etk|xh;!kyi9<+eyh zY>ug)t*YchLq0zGy5D1v3-f>3pYeTUYXHC8^DJ=vg|Gj0TeM&7`!OXNxBHG|k9fWR z?yHnV{>QUFiZA5sdSx0vdeX2zP&}r+rmWQ4w2jLfVDmsWK(+GfHAD)|^%O6)QwZ~+ zBXLvnCm$wV8kE14Jouqq@TB+wG#l5BN)X*N2&Y-ASjmqlN_dOQ`F0BUcI<6@Z4mIN zwRm4o`Ud_|94|`5uev4jyID35{Id48LKq~>@rxR$y3ekKhh*ubl<<-2!%&;z%Bx!h zAtel5)`SLx7)zw`7eqs)Y$BO_R!8W>ZG3Gi zRbu*IlCj!|ED-iJJRMO+tfN@->ixnv+9eAk=j^y}?OJ#%=wq&EL9X?sN{uX@wAP%Rpc)rkSl(xyx-{IrU$)jCL$84j{9F21ek^bU zmtUDhc;LR>Y@J@3$7)c3LBjcTCDqSfOe4aj>&EEt+r4?1M~2nw%+fqI&t7KBnw}9{ zw-IP<`Tv*j;ltr+3QaP@F)Lx1#CTObd5uSg>FObwMm>;Q9?30_Nv)4cqaG{~Ee)_f zpt0!~veYVn{puCUH42~pcW%$^(khK{X%cYpyLO*#evuXSm)eA&-8yYHta$teS5q^8 zg8x#o|F>Cx+N{6rmS61FU+q7_|7pXAbwZ46%VTU7)wU~Y+-litC9>G{ve^Z)*%h+Z zYh|)X%S#sAFiu+@GSJP4t{0xNt(E`x2>;XG3MXg({t!-#ZDv@>1_TH-yNeLP#@i(( z_9DLz?-!=gNxvj|ZFnTZVsy*&F{pMrl94yqr$SzP%!(OS>5`rvF;*+&_u)Ij4;r#% zf&V7_u#O3O`&D$O=aa=zhLtp0dp z<-MvLwk>tYwbdfmx)TpWd`&VPxZ@OeKvc=}dwV=p%4q^&3F4_R4td#kJvG)n5=@jJq6y}N?oN*Shr}utSJXU%UWfe$ z%1D3NFCc)?_I$;I{v?bX4182q)V5o|iI$8;wDqLD*PiFn`}2Nx z@Xh!t=KaDmcph3otL|skHC;O+Zs~)zldfLV7Yd5W}2$bT6(2zMFHDnAV5A}I7 zANu&jG+Z2a25x`(`Gr~eC!X|c%{7uyy8;9dAo&N=c7ZPP=tQ!^#ac?df0{_5eH7QA zlO~pRa$=PIkEBFY*{@rwy^jzC5UhA$5;ZkN9uYpr=s*Q8)qQa30D_Ln*`<^HdLuOf zB?+d~-IRMTA;)X>;>o#1rnP%QBZ(kh?nnpZMjAh>)YR-z9q8<9L#qqJ=9VY;qrQ>Y z3moyM+xeszQluhtK|2J`0DRZA*B{hHuDg|Kx%6NN0xlP`Rv%g{%1zb_3FEyI&?|Mc z3Q}e{=3NtrUPEmDIp;o(%R)WI*&GAH7WpRB=If$;H@a8SL^8blpoq6W*_ONlZnKxX zh#nUU%tpYUEwU~PTKPr6W$QXbC0nYpYk~eRIEfjvKd6tpL;1-2w?5C#E6!? zIcn22Ne3ab^GxtPlROMcyb8pBzgLfM)Zwen*8X+(eW{k2SFdOFLq7bObpJfUX#dmQ zDbBOk`J>wVs3f;M#%TW9JfLT=Q%9{T`yT4Tcmc-&NIla_!Q;gYX&PzKPY}?N-k-oZ zD~rH=NYsgyX#L?wZGZZq=ZvSeIn$Dw9g6O_+%o4%=ySTp>Nkz-6mG0^QHHkUItO`ma%>1u;2(Q?pcugRl6ZNFO zc+BSzBDv_XuIC2(;b{oEW;iYEuYqQKblt1{ha0y^&{@8zMtbhYY+s>5*jj;aD*?fOWMdZAG>fuqj z<84|&0{IZ&S6C#}kmCdzBZx2h%8`>HmvAZpDK+Q*0qG->wEckOuTuktvxp+s(u4D( zya?k$90Lv12yU+JT0nl%3%ck;7ZD6v((zwJFxuSxulM7`-mD124`$S0z(vA&Y4K<- zS8yIJb@Fnr!uQ7cld8CHoj-r}A9>esV!O6)rt6m|XEa7$`B~C%4RKj(AST-*{W$la z^L(9z7>GWv&@LC(AN2WUp5%OpgfJ>7>c+?BC^O*IzPuXC*iq-_Xo{X~S%SSC& z(a3R@;9Vv13xQEv!v106cTh`^Zu*k0imm%uen<2-aY>wUMCE^cpLXJsce!wnamXWO zv^`AyBDVGjx6b!Qz4w%(rE<5qTiLgDpU^AsgC>Q!prN4sbFOG8=#fW)6m2uP+6?6b ziY(@j{IyRlp`CK(mL^BlPfqB|BZIb?HTUS>PGr}9h|o_-H2=tblLsaAO--`=*+Xf3 zwx-7Utxc?HCT*7isjIS*X1E{w5l4*G%NdWN)YmmRGiJQzrtnAqljpTHq;#>i;`brz z3Os&L)_+4&K=PWJPf;vv*tzX>QpU!{OB;2imNXwtsjoD0#?dgAHk5ze)U`GztQBJe zycRipEU~UVR;Jr}jZIC4mNsZ&dtqNM`sIwnNIl(47~{?k&8eYo8k#k{v8yZEnV+)M z*7hw;v>y9W|C$Ng8JS~ZMrSd>YH1yOv9_8ao1Lky>H^o}gnj!{X?Cqm1b^nP+M8|{ zxnGf~q`ju5Wx^PELGT9ohLDqAhMl(?%18K8QPA~e6P!`7If>rlYJJ0pJy|un_uujq z7;$F7%{io?qV8JKP)~Ja8cq1vKEif-f{m>u8?6UcQ9Lj;{!)H+k#>zK*XYX{rR<@ub2(FMEi$I3E+ybEt!2i_eH&ADroc-$MJbGdX~Wv9PdkGS z%=L>!)Rvz=b5tLDWA)nKwfOO=C}x4`Aw#P!s1G(<5$7(SIN#X{9^kq_i!Wd*RCb8$ z>8}ae5_sCPge3OAKNMr=sPNHH4*x6z!-Ahqu)PvyLQY(m;od{5M7@YTMEMSq@)#1X zCvDT&Vo&}Zod|DjHb9Oh1F&cqgdyQ5Hh3&NnAaigs2|K0RU1<)7e0A_xi0kDYmXn``8cEt#pi{e_u>zgrt)BSBTNn~2ejQ=CF;zj;V zBR|2p@5p)@3oZ`Am_N-yO}59vNY?NbWWXBluv&v$R%YI>O|~ z1?=5p*}CVmb}we^p3T{-1b3zTmxkTFd36dY))uJajrDcHr1gShi>Tz#S(OK;<03`X zFoi^>9>{#2YsnnDY=|-`n4`ZD;d@VRgjvkUZfnKnZI3~r3R%0~Uy*S~Qd{_tq4Mk` zPiDLL6a#`EOmH01$xni*5^(sJ@{QWbyXlyv@Dab$8-cW{*riIvCduVyo25j@Q}+Qp zzPG9G9zhH`_I*OiH}(pfgwsT7tXCMZ}BElZh)bX(CV18 z{82V>y42lrDJX>^5RCLoYK15a*r-~Mu0;%@GtNEyCM6H@(`@pSEK(CH=Ih~=cl5V9 zFkfv-C?%%qIY1EICpJ-u3lb73;k3T;wd z%T!-7awBO=or-FT0+I|1Vp6Euf*;UhM*}8|DZXp}YFl zlZPKvzNaDi3R6&zoQe)Bb%idsLM=kFn}M6=g_`XUs!FhnWtV2E0);SjPlNe!cm zttFFJ;4C5)Iz!tW$LgvO4TB)yG(n($k8Q;$AXW9qdMNdYZ-?UY?fu7~iw~<5ue}m( zA{Q~I`-}oRnVvUX>xxFYiFcotpElh6q2BcR)Q5U2IsME{TUC?4>K-w|-|^;(TtluN zH1_5oc+Z+ZZ?h;F0A-c!E^u$A?lIf?tpKo}zTuz&wJL~`DVLD+{ch&CS_IS+^xKpM zDBVl<-FD4z&>CpQ69q*`(C2lmCS6yNd^g#(zxd6hKJ41#lbb*P8MpHKOE!MKZTbHU z*%-XSad_>2nuD@$6W3S`z+|EN_l43Mv+BKANFyVelj#1Gqtzsjb?-Qud6ahAB0Xj> ziz31j;4jjQBFpZ=F{n%|*Gx5otg@YZuU_>o0v!PnJ9R`j^L9VrLyH)K99W&-ib5QI z|I9)he7Nh;4mvdNnef`e=Qoqzazr@HAvm!^aSycciTg)Bi63wepzw<0L{}SSyZiRd zwoRYudY-TH(wpxPzNJwM>Rz_ny=_#1tt+*YaMIUb%e=kkIsqlXe-Z?hc-%H55rGFw z8@yaPTGRag?;aksV0EY6dtf7}UE;wVHy$FFp|azZW&7g%0wIA=Dy{9;s${T4q!Snf z40jXHn@ArOr?LJh!hfy0KE5*g)n2ndR7|msd4nn)*>*2Fr->q&GNS%oJUeY!dOy=Z zAfABCA-B85%s9D0hX}BOXYHC+KW%dVKLP()JW3`V2&Peq1p+tUK=q}j?kOCyvM$(I zG_fwA4lRK*cL;HLMM;RWAZe^hjxB0DAftxr;v1`!dwTxo9v`U|k1v3E0kj{qxh$4h z+e;P>+F3A$+R@jUj^F1)p@oyx7ENv*eLAs0?F@fbhg_cgPSLGCcjYX~@FaQ=k=QhX zo~Z7JK>-b5tMAY0j)At_D~D+=ivf{F0~e*n2zBiDacH>JH&frri=eq*(Q>LvUw6lc zEe*AsuZVL8BGU3Z#@`B7V>O1-2_;(r?W6fgB%w-4U1WqtOrxORMdIxAx!j}KvE0Zn znr+ube6L8dExM?$_5R#(&gz!w+tpB7WLT!qACYt)W<9=< z?R7}30+VmgllLJ*NP2IZTfUpQO-cIx3?kxpdGL^%2dE(X++3%A6UfOlZ@MDm>< z4LkOh>xddr_GSN)IX9^HFGLgO%R)f6c#TPR`_ogC-w)HgF8EZX``)*HUFfbpufHox z!nFTO*Ykh4c67)N%$L1c zqxL((51);#h#xs&QB|z#IYE=`x3eaXAN@Y{H17-F{(~p~fXU*GPrX<&bwbdLGb3qh zZ-TMHn{~b9g{6iyFtA|Cf>p&R4PQnAkgfZIkmk)jTgwZp1(<6|JD{H`D5M1>rD1KJ z0`{D@O(92L<-3xkF@!03l^`klV@Q#D^ZRgNLs}3{kG&9rBdAMIvPB6-zq9f{*Hz>0 z5c}5QeZDm^EG=33m#C4F$-(R%a>`q^0vv$bRqDY2zg@hp%Q5@^_;vGTwa zo+YOyj;vABZ!ODb2o@AmXqbjWZ+x_chbj}n?Ykb=QS06HxOs6-eW_VC7l}Ee)5H*H zuv6*#OVQe)!jN3ZNd@Hrb}v&`m@FIf+i^($n$r^o;;%=yja7hb@iX*psVRDbr{snx zG-RW;D7DZTpJF!&8qamj2DjFq>+ZPF&)|206X4%)-^~*fcb_6<89tDylF^+2^6gRu znF0TU;xuHz)M5XCQ3ws<;M= z9FGtHOPnH`1Z45HP@&xe+#aM#RA3I^#%N|C$vl&;nKo#D&X4zl|2#kGNB)+%4qhSb z?z&;&w+$G&=m&?;CV?9zT7D-wJTPO!vX34Sc(dDViRw+)5hm9Gb$wQLxzi7g0 z$Ngac_y_%X|KN}NA^v~hK>(ll;Y;Q25WaX3<@5A_vj|3g#s8Bbnqf%rtQKpAd#uviwWhmW(Lvaly7z)O?&g3zR+B!hdWju9o*zbr#|PFd(5Hn{ z@~)m3{QS7_589ufN7=-aiNyCJu%9TbEUJddn0Jm+SM$V)suKdpdT>8nb4Qc6%qNktsSQ zF!Z2a>79*K`1P$JuLBCe=k@e+&K6@?I)R=hB#C`OwD@87oui~@G~$KEam$J3Wpq@u z{0g;YM9%agd5Q`p%h%>#%Cnb$DkZP+7-yf*IvBaH zXy$v0R}`JvXwfKrlA%AHP)a5^3wGdzA%U}giSi}H`eI}JTSyXQDYUrd<*}djnZ5$Y zV%~3VBG07lNC7Ziw0#9%%dt{}5D;!YKlzS}VZ!!*`Qm8_0mO+CO)q zVSaUp0TQ=Rh#M*SMT%XD06~O!!sEmHu8aQm4N5Es2Du!h0bKGNaiOjlRrN*4s7O7o zbvDu3ovHzto1e{Ir}wtsTw6qin>qBk(+*lDrW!lbn}L4cJ!xfZ(#dTfxTsQc^DOe) zOZp`-+(8-Yp@9Rhtyom6=zzZpe#pAd;|y_6#?>wX=aDv26jo1M3^QA=kjiYa8r zH2jgDBuNDC#p7;61k>x*TY`No)D|hw^L+y$kMz>&+PZ2hS)=^1DF6$vXI|^US zJfAR=QxCfR;aru}S{AB=6Er)M&+=;X8jCXQ=+_@sDHuBiaDFhBVkQp4xfnj{@WIhn znABA(gXgciku|_B|b1nqeV)e8j7sTTi&95IJg;CxY*aUiX z!yQ?5`jmAE_CJZUo+1?VwJZ$l8aZ&Rup=?rb-ajZo;jf83}}|036xU?qo@yY{p_Aq z)#Xf8*Hkq)fVb^_aVdP9h#w@eetAqeVoGK`Rw_1)0zo!pdhgT7hf@@>DrhAC{Go#6uI8(d@f#mVR@d>4eck) zT019Vo~j7HpB(iMh~|Kin}Uf)z&@A-2>4FGT6A-@;6jG)O$Pky6#4Nl1+Q0$dvnPJ zOyBzTLUbGWK_af05)>`*dR)m}d(6Eyo9Z*1v**$1wZY27zLg7i&zUBmi>h9!l1$}S zPIGgkQf$<%?2o=Bi7KZy;3}Gq%{q%1LBcI=>Pp-|59Fly#I0aM3hWOxmg7XRV5d6Cj^HOGqn2hIRzX zzSFYor#H+E5P!UO|1OWq#Ruwpt8$4kKfWRs`_h6vfMld|y|NtV2mdid!Y1`>JKj`J zo`bca%!NN??((91f9}kn@nk^Dl+>158NFDR5k6t4rqM8pj(Gf}t|zTK$VEqM{gfdW zi=hnfP>9q#Cxzzn(zze@O8#1IR8J7~9JH?XCyq*2;k!gv$L6V`CS=29Q#V+ZlKnqJ z|0!A{4hL7%zzN+tWn#%1Wyncai0>hA?n{Cz=ortCCW@?t84OI}^X z73{bozfOwt#G5e@M6WVn?9(4>inl$4$auoKe|s)0J;b>2L6%vbX%Q1v4ExrKUz_zv z(31daK$X9wXFP9sT+hL1$fgx5VmX`t5e1f^Go5nI`W?1%)Q&$>rxaPu97t+Pt&tcP zKmfX+?j1RxqoQX=onG!GWixjana31PSo9*jdZiI`wFo-ws=ik&BLfrV0I2EquU+oa$=IY0`aEdgR?OL<1rrYpgQ#Y?h-A zk0^Xz<_WW~18W&-18Xqa0`|Lot3hWQ`MLZhp>_+ao_mNQf&G_!A&?;LX3!LG8bC99 z-=C2V>k#jK$anp@m49F86>)_WJQXJ(lqfiH3J8a-^nFPYo74XfrWk~C=R`esXQ{OZ z0;fVex%6m7As9qA-(P*&q@C4|MdHIEgu=#Qu1*#zRumQ)cEIrT0zi0xDyq^U#RcF5 z9ODg!Ootrt_U+{~y25cir!Ht;XYxW)TCX9BXaFb8XKMdqnQV@5M2HyfJ@R zV4ELX;(fc_CbwEaG!r6$g+#4xIHD`E!Ft;YB znHpR1HN~aBX-zEFU_$KkUb_BkLhr~tF6FO2xKrpA-`&vH=O&?8Q|J%BydK3}{oPN& zddk9|Kz;qgdc$5fNZ;Rqu^WdgG39_dkzN(`H5)E={%-!g{OBN^MLsWrz`M@qW^M5Y zfGy#)LQ3$$50M_Q-`(2V`^fB8-`rseH|Oq=zrHE1GiATOAp67F-qN*F0W865Zs`yS z+1|h;V{^c7v{H-S!51ldntftNLf%t={LO;l;1C~Za{Yj#;dH-o4?4%@SGhO=bZ!X% zdAs$GMZ!7=_1}Fv_#tzDoA@Do9mss%i)-j1f7}nm2-vfwqt#F~Y0m4{+V-X~l*QVMQod>)Es`LI~K zBDEAguX{h{q+p=?y&&XwBLA`cqB|dvh2lFOy%!^7Q9$udY$ajR3D3}eCb*D(j$|K~ z+Pr;fK6@I90d#OUu0EdEbUM7_p1nT_xH`9|>lbSL4S~R!U@h^dwv?}_Y#P`_Njp-5 zfWq1t?Tx0wzjQECvaMrjLtpH9+9tvp;8mh<*T2uS5tM$Hw0bMyenBSZanhiupxzKe+)0=^lM7E+}_}B zsp-Bx;A>an?aNxGQ(9rv3af7^_~)Yw6`59c_!XRLwAbFZwSV;2)qm9WdD4xe<@?T4 z?;ixEYrx-y3beiU=*{8!Q_ou}Lq|<+D%(StX*oK1vP?9jqor(@`PaVk zWNX)ir4U~>(Or4^DcpX~KOZFP7I>Y^M%LMoqkI(yipgCyxaxUbRI1bl4U*KOV{M=x z&|E1$?Iy;?3G*8FV+KaX7ND(De9V^(roMLC{|LT@eslb6N5=b*T504Jy=-&aL~56;=i|>U$XWC+?|C=WM%6{0Ftt#D^L{ht z_9dp5$vnvbgryfbda&19*_Atf8{+bLo97C(eBJL2Dv}i|ekf`63^ZL7o->KU=6Q%$tY zXy<2J($b!rKp)kY+eGKDPs{4wW zGgF7COt&U^N-a}bKH&IkAGpUMl#10KklwK&xq+(aQ{@`;88Vs=JU7pOxY99Z$f}&G18(^s-`FaC zT4;tFsJldRe0A!X)_(V#DuFfG^{9`ss^;LE|1YMZPpnlEBqA8v7wXu&4(eIQ!BIq; zma!0CiwJ;;YakuU#6r57h+tj)ssk>xcG@Bnj#i(Pkn`O{R?;YKDko$XAa}ksO*Y*Ja!e2an|0+;oGjok_pHuF(-EQg<$j1 zK<>FcFz`qNh&VWH)Ren_B{lFPZk%Yr%?K58idk23m!{>BtEh)0_-I1NPW+Uu|~& z4N6Es5EB|f9c}y_&FDeaLz%Ya0Q?)`&z}X&=Y)m9^IuPQf)%CJE(U)TOL01kS!BGof~Tv}RpC3aGQ!UXe1pI}&AV&dTotD`D*{%F%fYqr|H#yhAJXg;D9w ztou+e9SmtQtXOZGS&f0@P;^c-ku?K%+jV8YaXos%U3c6BmB^0R)eT>KVTQpjVSXp6 z!Cx;Je`qfkh+aIo@Vp)s*bALcq)VRhb>u1vsycYtmJ2gp``uhNv4Z%)mkh`TKap_V?QnGXlQJD1l~;x`jnLZ+9W$GLN`I$43gwz zg}Lg?2Hy+FCf`q=S-0*j|LM1(jN+N?-S#S%0&ky>y#b%rhHV-PvMXB)bNx?gDlyzM443n-t1#dg@%kJYy$f+kl8V+ zGzBk6+oqFkjpXCS>ulMu#AC_EBhPwB$0wyOd!^^NFEv(MBiZFi=TrnzK$imOf)wh@rN!?(!|>(n3)rL1b8W6Kd_fI~1T2ry<&>HFIf-7t zDOntGGT!ddIE~KTfT08+=H--b^{IA=+NHE*6=2IY7(aWs=Dw->|8XYWA!PzUC4<%; zKz9mvL%4G{a*b=u`|E35^forTI(!nWr)h$9vx!^P&T)gO8by4O3W(F>#2l~>60 zMhR?0(KB4f$Du#>ut%Xkcw8sW;A*TS&RtbqPFA#wg_;Z6$#Wl6)5RqRSM&+9)e0&# zS8xrml~;I1`xS|kB4XaI);c9s6!2G6c0~h=eu42QL;bHvSSx@+Dm&f19qve}fI%wH zO?o=O4#l2TAKOYTLpIE;FZHf3;UR9B#v@E_d(kMZtxOC8+U(g|-r}9P&JVmv19OL zS0q)p4ha%Zle(&~VES6}4aKL<{{Ci@-xA!oM|~deRDPfOfl+x%F$(cVQd}A>G_pqS zIDEItP|*3;gaJsPxO!dQVm}6M}t+jqMgW= zF-I5<#WGe4K4RfMeBi%OE2d~E&09QpnZRSk>PW4chn3mG z-kbD;11oewz6or=%B@>5M=jT?7@QTR!nCO1)}d*^y4mfoMQ{jL0Sk@|WyTZxlH>Zk z+vUZUdJV-O;WC}e>1${=81Z}Px`%bTqv$^n=vCu6Q*KXI?r(mlq&uYd=E0VX*_k{g z)9oR(a2HGMGxPiiz4zZujZU%CjZUmG&)^$r-1mHU5hPiZ#!{|JcU<9)r+4&RZ`C0tNatNnb}#{&0J z0;k*;A5Lx1;V!tSMLywp`g?uRYp$|mI8{{m1rB8Gud%_ej@RK@1YA=?_$Am{Y*Q8Y z_gvT8#-uHttA~e4uS>N*qMNlG|dZzaFRS#N!WtGUmw3%b$}SAWJOccUCU4W=4lCsog~6>5FdsrOK)-8!Fbl>4Mp?W&)1>V3~C_o!3vOn%<;?0&zS*~F*@@4&PlaHeX+>r0l=zkj*J00O`AD|gDHXSKd?T-w zvY{l;JP=m15VwIS9UI#!Pe#jjMU+ZAPlAk7b6}qB7^d>UJ@PS4{epY~!nY`e3sHqI zJ{7?jSC~uDw<8Mv*^87yj@}K&q4YnU##fXeoxwMi+K3|+uQUCHQZdo_@zUa)^WdXQJSQ>4AhlLu$)X1$XIF*lZy2OBZM2DeT1FwALVSc9zyX_p)$yO~&Y!)Mw9K zRbMmaA)k8K4EfR7_sh+EePxv6*)T-baHZRw%67I1+hN@@j4kU}CSulInl+a+5!l}? zNw(e_;w`b8j9S7sQb|OKIG8sbx#rt=ZzKj`82!fk_fPpp{Tfi@p3T4I9+&^zpZ#l| z*+*Vc0=7}t=>A*RUr1i2fD3)BfqZrmXm#~qH@`SQeE=F3Eq7l@2ZP4md&R?Tp}#@FSuer*UAN$v10$7~Vy0{A8YYk{h+qYhB38=Eh&X%Uq3s zUAO%}K5zo>a?jhAqvZ|C*v)i;1=mKN(gy3PntygU?SBq-=P4g7oYHdy-9S8OZfxi& z8Zm$UhLE6~p=eE^cUG%Yrc3F8nKa}yze|^T((TLC-br+dHDe<9_HwWF$r%4!g&XLn zPjjv~9>T=HqRBN9ZqYcL9W1p^Zdbdi;Jufveo|PKtR`VW~ zVs2G308KB3ISK0v{!zcppB4#F({|UFtv7sLrqz_aO`HfaT^x%0jV#=U;xcQ#6Ns|fwajy0%Y(f>(HB-JtH@%(!e z!7kzr#X0%n-IaiB92qP|O&~=}&C62!JW3N$Tb;Vg?gy<|-W2{yoIrGX;#{99x@o|(Onpk%h zjrYN6ZtV*$77fOkMVDL&y$qrh?GRI{!S8GXc!~yU0|{-KOa}aUNBY`_=RKbNce7w< z5Usrs5tz^xMfc&{K5d6DXId5pjnN1d*E2i495qnyM-5yXxoz4QA?v6oyK|W2Y?a0M~oM<&T_!If17*vi{j@dtKOzjYubR^e3}(bFgVc z$%Hp@&wB;v6%Pa<=kuzrgi#bz*@_UweWH+v;MPQKhB5c}Arah+)-YsnVQ>MgHp8U!brK%=iY}U>_Mv2;al*m&Q2w2GO4NpP(D+ z4RGi+iUzC>YqUQf@N2mSzuP1YYS3y|IvlucOhUl=^}(nT8Ow@*5jvb3y}%ra2+E98 z#qmZdRxwHOiZU3deUdvyHeh-<$v=d*e|RA+R)|Y%W{$Zc{RJugE1n9{CTTQ|OF5aO zNXsiUA%WP-lrTK&?k9MJLjOH6At^5(G@8?^>%@)a=;yEGZ=%VvqobvsTn3E*5=-X6 zV(hu|pUfk-7ODJ7^a;#ON-|AYm7gb-prY3Q_a|2T-j-HBIGN(&fPIj``Nqsx==s29 zXEiMvvBXn80`W4)%(5={!<7(`dX6-w2 zjir(cQ5#DoDVQi^r!IlZc>7g|3NDX;Hmhznhl&b^!P%F_Z>~QUdxrH(N;|Al7oM0O z57$52N3Qs7qR8B~V`w($+lD7THjHl2wvFxmT)Xr0aq_a0S~Yfujp%I-Qi_4LeZ1pe zvy0yj2LFM3uU$upq`@;@jYn59c0md{1bU{)mr+wdg%d*)^>Vxp59C$B+#$i;ox!7( zaddumif>WThVi!n!CV{6m_9=;jstdY`FB~OWw>-0B4z~O9-+We5=>{mt!@H+=}K_T zb0zWndeUigc1JdiG@@u!b|)7 zC8mW{HYHaYUmhMsPJY`kA36be85jD2oFkWM@g5DXn{O`uq-Wum8it%I58R(&{Q~pA z|2W;QwRjHGUqNp}IMuKD7d1IW&Nn<0?N{gzYNnz5yc;+0OtLRicxAfdZ3>F1zotPD zOt%5Q5DnXa)!7b)rMs4au;w!LBfpz3RG>{a5BQ({fUB z>CCCsf2rtoUznqBtDmB2O-=T1k7s|rGOO(u>P^qI$Of~Po^y|NWbMVNQ5ZMJ*b*#{ zDzb$6u=x?FcsCk$C06u|yoiNNo>Y8{F(DWsww@=q2t6d~r8-A(HP9EJG^ zzMQL_jz?6y%Od9PdV=oWk=TzKj#qF!)Wm!th}Dco)%#+Yo!)i7@laI|3+514m5Zc$ z@Lx0p{(vWZxSrSv?7){lZT^jzKi&Ad@N{wyZRi)0sR9wCX$|YQ7G;LBcJF_Fnm8Wr zTyQ>d#-D;;BA?r+?30%qBZ9416jPTRLxQeY6l0ea=LKT0D2FaM#|2~oJKPLoh9*~A za7vlIKhj#2+*z*5DoP1P(v=lMe!O}aLOP46Iy?!iAul0vD={fhXV!r_;3p)woUjv! z0(98-?6L*>Eb|v-o%QnXaSg;~xn{$HPtO%IS z?BKVEV!OvU#Br*n3vqjjfXE8ilb-C8*8|ku_H=Gh zz94WYf$K*H@KWNP4M!z_)N)5^F-Kz&h-G$1YB8q;n^+Mw7~_JFSP^OZOyH$f1sdhU zGlH5}7H!Lo5y5GY3f;?%LH*~JB9L<8eBhd_2%T*q!8Sv!2?_W{R>Fl(3Hk%Ar(M?8 zl%b8^l@mjIU0SZU&-xY}uL5jHOUbUaXD3z+`(P);0%w;KtO8R4cKu&Rh8AsiTb1a# z(%=)us;6LAK5&4rdO(+;CwAf`4n89R$Ha5oe;BIN3bk+CmK5P&P8D}5fUIyFuNdtz z`O5KxtuNfK81K^g%yEwWFPy;whWi}FsB;Z>q0B_C<~p*L5xIp#xYC_cu4DQx<}HAp z#Du(tiCMpLWk@A}6N>_3R}=hzo&Xcg$3JrruiV9g?ql}!T)|O0u|t^e4(2RS<~C3Q z)hTo1cLRXsU{2*=j=RDkg;=WPVNMnq4gSSfD-Lk1Kv#Q!aEerPgryo!csF#w`?@0r zCiJ$Wcc1~RgGy2NuRF5bxC?h**YROk^o5ki?pR z`3L}NRAeik)~bIJvHm3I_m_$v0(o6Y3A|iShy=L;UiB~ZMGXH$U2^&& z>bg22E^bxm(HAHQ9)m<);rDlUczxaQuP^jUJ>0mhybtGzczqJrtD;)tg|ECmiEGu- zEs4VMmI_kBfJ2P72jvMZ3FWg11-^ZtTYeaIhlXMajWkULSP<7vc1Wmw#MZ zgyQ~Dx`3pp&Gp41V`s{a`L~$WTra-6h3tTxnF)Ej>y~YKz-NvETH|^3gIiWB#Fa+b z;v#+*NNtx&*q>%J@NXYDH0Qy*M6@e^2-AS|H=Q7TIBOla;32#2PTlU7Zu^tBec9H{ z<>Inr-yh$8h42hVInDrIEH`0%;4Z#v#nb7oz-dqI1@h>Z%_Z$(yn%W1>iB>8VTTJ1 zlz3Qn>MTCC%q%0+-peIc8pJF+Yz2pH|7#6+SZ((~VXR$Y{9@)^DN#l@oej@eaHv>R zE6##%0vT?7jJ>DNo?5Q`v!e^hf=1*>^5tD)cXLiOy=V2Xv?jiMPvUIyT*`Rt;&`!MLTwk3#~x4;aqXuB)ci={Fn zrw-$&9gs@`ig_3czX3Xy<)2ieKB&OYsyZ3;SN!MMljqed=hp(~N23xifAtFPCz13% z{}9XYm*$`Ox;)ePg+N>=G6OCDQrj?S6zEV}U??rQ>JJnClpf>qAB<}14_*`;AW&wp zil{op^uNjLM^!vv;~Uqlqpy@)YyLn>5GH+bC%Ql7fjC@a{VFkj!CkMVO_Tj9JC-u) z)hx=zUV`p^yDf^2%kHtBD70udip%| zUq=r8^gD4hhX&6BY;5l^IVQVzE6#M%rz2mI*%8UAM{1!QnaJ1V(}%s}(+CwGU{u!J zO)jYSqUGaQfm8n!c>$!?!1-V)QBbAVwR94EwM-wCD<(L@KP4s%1UXDd!7yV4nCZT$gej~W4vfG!PWKUq;7!66!8jez&0`L~ z=8u|`Z{m@qyp{%*@?7}e@Q>c7qpynLqHiz18YYTgMB2e~5j=S9{|FcqN~mOMy0f8x z0isqzA`pf#z(W}H5Xj%L47UhpUUV`cbTg1HJXVzxQ*?(zA=N`OX79EE3;+$f?A1dd zkcL9wA&|WUGdK1jkU1hlKQDX`$Ys#RVGQg78Qj6E4*cT#H0gkyL>Q(kl3PO1;Ln!C za8m+fmlJ{lc>qpI59+A6ripi58SC&}7vV5n=4Dmt5ew870`&#YUbsK-y&ig>pS=sz zBl&;*!78wpY;h{DR4d367zDJ$tpfgMwooshU2Dbz?}(_U8aRm_R4yj-Hah=-IUGtR z6LhyWJE#2E#9J||$NCSWv(5!p!sz!1?r@4+Bf34pJDft72<~7{*Gqsa&q!887be3^ z(~eBgb$&4kKPIjYNc@_h_I?TDlLCgY!vU-?y!vWKsfzQeNvoD%RF_aRPuWs$h&2n; zRtFUVyNdnd=%48-BWAjSRmFVYK#nEREv3@Ch`yw|piSwKGs{)mlaYW=0X{$za=4l> zC$s{8BoePKFVr>9wzeUY11c~v2+(cQfjXEg`39sJn{L~>m(f#-#<>ABw?)jr2nlpps1JtNp7s;YKgV40* zjYF0UYVx!A-W}yS_?F0FT5*MN3ku}pUT)VHssiJ{y2IqxN6EBC>W`BTQ+23O@$V~_ zHtbH4=#AEc><~WBociSF+GBe(;P`r&*>w-C*FL$-gY7YlE*|_t`2>uHt^@e z)ZP-O&^bkqyknng4dDaouzl+Ep!ml=o;2alhpDxSpJbOlr8)HRwSf6BeYfdW-iBOz z)t9@*YnaCZo}>xZ0W-^q$bm2bOFoyQTgTjArQffA4m#7^Tl@Q~$IesVyWCp@`91rn z=`(mIdX~q0w&6$nt-t}~@~mY7bLjgOimj2XD>L5k^23R za`Wc(0bhm+?;u9s*CDMr3sZ1G3!p>mf*Zxie-X%O4c&qo07F^`Vfz(`TO5V4nt~Z1 zL->IXZE_idkkgyA1UUdg*bwQLA&NN-L83tp3=qr$8imMlAcwyWeAqBa>=hRSWWgrw za!-3O2`a%Sur8AD!6XPI;x0*Ea!sHl;et)LB=-76?op3_SELM~b58IS>j0h@6LPqg z;|`gOH3%V-1V4-r!bL1YG6dxSoq!V*xSYrn3IxutpRgYDAf=k+Fkq+ODkFx>fiugA z`7+}_f;Ye}Hdullpb*urL+YG{5Z;g>{XmE0!i$xwkodc1U@h!w_JvV2x1o@>wyn{yAErr1fMrh z8ki)IT#YR0A(d2zc;tmm_cm>HxnN2qH&jc#*`L?o$XT4^v3RDH1zn&85$cM4Ch& zb%6SikDeu#ScfEX9Fd{{3*w<dZtavqfAF-E}x9zY?<9RlMW0*y1uP=Rre4oe_} zXz2g}Jn65`E#OUsKGl!3faarbI5E;|BTa<3aMN8g-|G|r3f$6{u}hBVG> z)d0&v48KzWa@BJUNz5aSqy#x|LskfQOOVGLhD_0*ho=NOmJ4hH20i8r-lt&sCfId$ z&+3wkX1)dUi=wY_V)B~-$NNd6(a$-ApLr0?E-$?TR1i5gY83o1LTY!UlxM$C8AHyr z`bX>rcqrOD!;gP>{^GAg!NoY-bNh=n9JkADdM;_$1(%181a z-py}!BiyWNpVFYcIKK9Ps2BUw|5s>P*IF?4Jk!H+Eu2xqfzNCK}4^adQMZX=^;TmLeP;0DidfZ+Np+@izf8C=8CIh zruLPfqf+o9z!zj?k z;bhZ~kYcC46u#N#v?xWy8wK zOXqL{opYI*kD8lZb7Rn4(W73)MHwUiRQ=#zhJKyiqU@T{(=?t(xVv>PM?|*L`cvrb z4lz{k9nj6?o3(90NY;S*9yvIQ>bir%t(~u%p^`s(Y^LTfUYK;0Vl%yT<)s7IzIy$m zdMVW-GK^J~8$}Ri$|U$>>MuPvFv$+FSWo7L*KeIz+JfGh_VbNs8*A^RxRvvJ`k|(- zlJMx3Jbmoa#{k^Y*%ld{1tU(zYI2KP^`{`d7-V_sS>oSral2h@@=~e}{EhwbvTx!RgPz(_CA^$74Vi}E>I3K|2$9i1CuU=$OLdE{%! z>6INVD@LfClEi1(9JHp2QeH`Ik@W{|eC9JOPvNT3>mwxO5`PYR=#kT2@hg^AYUtS8 zdRfceJ@dAAC$FBRoNm^Fb&S;o3rc3qDKE#XrWJP_+0xQX?!WwxWhR>}?2N*B{)qW#{SnB&$^3+TvpHEp ziRV0cfZWS!Iz+G8d2YILigl#-(q6~>k7Y(%w4y0<C@5_`KX&eLdNdqrX$%Vr@vEswL9qR6I^J=pSORp6QI>6_RxFNpAZr;#D7}Nhq)Ml1pfua$CPjNh%x6u3lp4df6w%;HvG43bwrqDd(2l!{tnGvDmw zQi{SzrNpR_O7F#zO6y-Dl{*O(stfkxgCvwrT!oegbVPD}G>TTD?#U$)>B%Jt?-m|N zJ`F2!WH)2C`dD;9zE*Qm(XHVDfJ+IU&gxrH5g~cunFos3INFJVT{2MFc4>67G<38q zsaj4pY11Wk035lIM-yAqrKlhfK!!ZHIhSD;g`n)iG_fmS$0viDnV_L=iB5vd5?gO( zK`Km2X*#YCFQn%X2jN+-l1sHq3nNSfmgL<%b;UPw;_$3=I;siDxfY)zW#`JD!Z%6EmCx~UHVdb1gjQ9=YVGJo2xPE-i@ihX(ZM?*rPi^YoNYOj%4Hw%A7wt$cU%4ll3<8O)mPaQVT<(~&D=RFe77S)-dt+B7K^lX zvpYDlAV%1F{NGl=Xb_g;P?HS&jjuYY|7cPj?KD`jWg{q(y@i*P4yt9UT%c!S!! zN+%FKt%tXh)LfnVPc4p{wDOSsH%NYri`c3(q48PRCiM@B#Ge(4ADKQYG(IG=MTvV| zxO`UXJ}7s;A|AF6%KDzS%jB%}pmR$-WppKD?Q-9Lv*Ppom-~l>_rFFUo{xw?&Edie zRPc}9-+|eOw{GxkfYSKD_Tpg!+ghno^cnNg>E882nVkC`65O-ZeEqtdC6yui-x)@j zj^ZBgecGg*-|xV1P6!Ax3Tkb+QEAeyRBJuUNTI+L1mb|rOE9Mt7)~7yc&njecnXh? z95UBkOytvA-L0mZP>Y;UU>bFbnZqSUv8(Y0jw&UVW?=c; zJJk@$-JAIhhx3f->=Zu8Sw^H~Hjp^u;SbwD{q%$P#t+({{n!WTvaOA|54yZacqZt& zM`_6CDcjc7_bdU{APp-3bjSl(z!`)AyI>As0CHWD;Bn{!M!+AgfIFrD!jKek*wZ^z zP&c8|1IfZB`Kk7kv(wG=;V|=n3W;BaBn@2E6G|z>oV1&9tDna%(K(sVlB)0tlKX6ZA{!{IGrYlT}~*F3$ojIy|#uVuSZBmOy#1`xp>DsI>pAT5ran%Pkh3 z4n}r)zJ7JMceDAT4ZQ&nWfid17sDHUmgvPv2{43L5O2n$`$H5s^ZXU?f$9WB2L&TU zt$cunPQCg5wx@SkPE4e<27-h@EY!};j5X=SPge{g=5rK?S5uCh+C^Q4GJiuA%m{Z_ z2=qdEA`rtHx<859Zxwc(*gG^K`4n91GV3DZ@Y{?^_G-l$ObJA@Mzy`e#VKnc>30Yg zg1~Yx#3M}{yh1TVUDGDj>U5D~hX%r&UBn%&zvgDdH68?T!%;bv4G6(}LYe57b1x6n z=pHDdPbWK^xVYBs7UUe^h3a=<4#gM-2&Cch0S?E3gLuSF@33h)JTl>nlQ#BO(U^7R zjJ!k*d`NM0e(DeBbbr>rX590DwhyUr3ZQ=g|q=k3sQi ziJLpc7Z0-jlph4ZKfTIGus`pJ$k(VB&D{ zfDa&mU9fpi50#2_{ju@VD;I zpHZL-t1VvU(zFjwz%)|)bvc+QX^%IA7@l4qLxdhZ?Sr=N4y*HOCHvapK_QT?Q>|}Ene05r1W+YFQ;S@gR9d(VgeB=TdL=>;+3ya#DC)+x>WjpWA#phLn>qR z^IY{6Oowsz>5wenM{D%;9Mu;Ds;G~+CoRa@d`m{Iml8NqmA)Xa`t`bp!1BE_=`a4+ z`XA-U2JGtHhM#n@bK*fUPlX|}{#P|l*y(v3);P~|9@v#rdZo~DUOEV6pIm2`9z3A* z_-J9|j4To*yzNE0>bM`;k72<3tLFpTM~i{|yb}%w-4lWGvKS5r#Yna`J*#6^H9&rV zeYEP`FBiFymQ}MGcrXvvaOyCtS}r8R(x6$c-Y`^FhkD)VR(C zb?PQ~1LH*#pbY{PFeS5b1?L7dGYS9kEFFswD5Bs6hcJaRVAVKpLjV*`>Lj`}PVKWG z0I>q1CxO} zm>D$yOq$#Ah4!c@W}Bf(MClqT%Vuif`|kLQtPleWBc;-N&d zctxCd#hFy(;a#=kClwGQ_2fT|fIc86g-$9YNB0Ci#{hm!+gjw}qQrk@L+h0uH2ES` z>MKC%D)(5CVR(iX4jy8|oWqbkoXEJ2x~y%S9|;65C^?@&UW$6+iOST4^s`GM6(HWeuOLb10D{|Vull{#z(dXB&vi}0)jWxI2n=`)Y*QaoOStBUI(REiZ2p6 zY~Sz#($+cb3FL*CO_pHwc)6+>3S;EQHq?e}sB`r>H|8C`>gI{#NPc!B1UuW74??)O zRpa&ag|@<}6(Mn(O8#<+@L2FBGd9D`_h9jaqN;^5crazGxX}^DKZAWjmNzypPW$7K zy)ILAjop*eB~ zwJm@fiLidoB@e8Y(rO#&T;^l|2*SAnY!O)y$i@ez2rOSCQA!2eupz|&NF!k-!a_## zWd2|Yj4X2sjdh=z3z`ACKt4YBK6zX6Kp!Mo#t~xqrt{eehugOypnd5Z1`t|R zOJBihh&LZV*wGKVFrd2W%_pI3Y&HiH5TCGUofBh4{~;yD-8r-XI}L%!1Uf9+P!ol| z-fD-K(XJjri%K|SVrGJUMRy4T!kW)UR;O11Fi86?Ku~v%)r2qN%e66`a;m`%lXY6kSub!M_D0<)>#Z9V0E4^+%?++|l&Jpq$8^NbWenUf z)<0Ijc_Qkt$Bu&v!kr>AU&KQn-q&bAVDmpQ-{>DM4k!e3d{pe+(+{vgt_-F=k`Wc_ zw7KQ&^12pXyYI-77>P7NPGQkthDr{-)0KKKybVdhFQ-3du8c4+hl9HgF0gAzI&Q(% zv63jljezEy*m#1N>v|Lsu?JIU1ZNGvW?E zPrw|d-d9u;OFE;fi!~qEcT2)}ClfcW<|^XTh8J=lz75|Z>!ApjsJ}*P14v)+o(>FO zF`#-K8}HyzKNu^CIs&O=^Ky`leuF@DR0SOdycf1I>_K{je9Y9uR-yxTg}%#oq6XGC z-T@dv3Q>JoF&I)fK^Tn4-B^e~jO^I@M6Kyl7*IvJJ_?IIubOdEgN?-O9m?LS2>o83 z^pqH(xIdf3=P7a5Ee-Kt@1f#Hp%iz2p%----$y^VE4u2}`_5gl1fT4eMcuA-=%<%A z;<{Gu(9tK2;^$HPi@D>+H2L?`Lm*M!H)BJCen@9t#Xc*r+z(%z!Mb|^4^3bi4}?hX z*-eFx2UZb@;sJA3S>P?&N=3t`>*j%uxQo7mk>En=@tRze;)K0E`t-!V%9u_`ZhPa z%zd$;@AfssE%w7-rXWI|3SFu?#R-n?R@q!;ElF_7ZJo6}Ui3S__TMegBuUDZpun(x zyM{O8uH9=PO|R=$3<&C~H{3)n5GthG)sbp+o3V|bHVs?_G!gkY1?s8?2T{JJm~^uj zWleIRVSr-)&-muwCEZ4S^}k&Q$SHx5ySjZUmlxKk>)(XN2_|K{CUYwtLW${tRp3UF<^A#FnU{{_nV-i8 zMupYMCPFuKDaA?M_JH$Hsl=~fsxFc-4;jF%?wiczH^oQyBx89=!7Ja;31NW_!l28( zUqMH5@7p;HL_Nk80KW3zu<`lCxW$>`mdx^~%+=QT=h%i6b47G?bv%?U#vkSZ0y_>A zm|`v=4Joh35~(|qj74PUaXq?nx32d)a&c-LP2E7e1x#yq3!F>ZEyhk=WgTH5vWp(% z3*w*26fq$`qrH(MrlIZA2yf}=5m|}(?a@|Z`1#_8T>e|<_adm<=6|9Q?z2L><+dxc z^6faZLALvaApkXjJ*MJi5M%U)3K3jn)7Zp+F@l7b9YT8^iV?w(#zZw!y9J7e%kD)>_H04;BuSykz|kxodfF%sfm!Dw7f**=B`}wWrm5Jp}^; zQdadZKK--n;!^;sF16RDhuX4!8vwuV*`aqb?9@&ebdJ&tLe`!LGV6XCHY6`auYdj6 zo?r34*pHh#(%6)7|M1yQ?XV<6Dh9z;|3<+{Ft`Y86R(-DSx`qq%{@b4wj|g8$LACH z%g~?uanzAAqqbl;V(eUUdmLl~>u>uP(C}=2cz8B9(C~cGnkTWzD}`E@u1)qZ#jpJf z=FIUf#aFjq4cAK7|MG0w(ngdt{I%7&H&~=(`R2f&&C}p919IGQ^@oc>qN2rHFqVA% zcRuM5qZbWoe>gQo@whziZFA5IkI6&~C^)CknlH0n=wDJMdCeW0>3hV1Eg7i2Y7-@By-Q51q_vF2SUp$AWa zjOljZOc+tgW7N;WsFm#FVAiSdG5sQYyYhRnKtj8_;0C%_++M)0C8 zB8kgM$*LxrM(yX?1q*#F<9WPs8H4X`WzJ(uEB<~rjcT40CL_6I17py%Wtms`SBP^AwiI+4nfr3Q`qVGAA?X+4u2 zQt7H}Ny)Wr!$Te(x1ObLQ)VynOAN4>F%!=8dFotYRt19)Ug!cuvtiM_{L>Ym_qW$= z_j5y8qwL$=FLvL0Rhh=xKvhvkqMvo})vPYE@uhrq-=4&03J_UKE$0 z3w>b2T!D(QoD7u=?A}5MDt_xG@9KWU8+rgB$N*eGZ-z5EFsSA}`Ea5?ssbpJd7woM zSPX>>)~-Fg^!6Cl+R!E-a;_4hZ!co@A;Xr_jdhc*aA>I1ISc_* zim|AVHip|aH+;ng;GYl*9jj6jMOu)R3E0&5;FFw|TQd8z#MFD1yUHd`tW>T3LN!oT zM7YoKwSb!7$xwxVB9iF_5n9JE7%X+==-q(g;KAz<{mc6XP`x>XmsURof9$$44Tj zuUjYTAh)dzkMT8T{O1&c@VV_)6w#DDv=CkgR1_^<5J7uNa@4r%!$e`1D^6a3^!Oi;j{Ti_PX zO4|)8R7+Fn!lJf5cK-K<%2xDZMEKL@D^J34e#hiylO!KK6n`y1d4VA$o18qHJumDG z2240=A7QW#m$&u9<0-(&fnK{DFhKGnYY(=Uy&4kDgGMJ6i5srIZNS95^*avK|DxvU zOMeWFa-wVZ1_=H}FK{>!C9&m*`t7j0@+qL7BuCE#`(7vA!5>E|eR3zmh1C>KaRhyG z2geJdLVeiWB0*q2%L(_`88EC5*8_g7@XTxcfXK1PswZ%IdEvn=g9NosD-<{WqQ z{bQ9+|J{EjAirIh4eMt9?^}+@&5Op7NdD|_Q3=k75f^$Wiw{fi z4MPlo#-u&o3n}|Sm03Xdb*{TLA66&|n^tXxg|#c9pg;t9_D8+m-l=c#l>98}`<*~* zPtEU#DtqR@!dw5o6XR}!3G%P7nX$rrFaqm^k{-<0bjym&h^>H@e$|wNJsrzXXmC0b zzndaY9x)(H-JVc2eZ->JggW?x-*`DIB*q%c{&3!B_+F^0>@r6`jxE+_KHgnkdnz$} zx^Q7NntJA7!sW63_FI;wQPC%8O@~j1r-Hc3QWxaWHR+)9v>{?~o{MMO9n0f;Piif^Iq`f#M$KgV6^-sn1 zmKK!ggW|7qK30+;d~S004I$}cz)IH+A@<#XsCRxklnOW=C`$SH$I^4n1E*-#;ghyy zfn}nRiFAKBk-MfH+KB6TfR@Sk`UGM-aKvr>Pz_gHjTcGc-)O%)*V-&<>$~sd&~w)o zi<4tT$baWW$QFx~Uq$3gMam-)fec3COmHbSZs~`us_larKj8O-k~svHyWk}279<|w zt7hN{9FZnf1e_owuyo1+X)P(yXJmRodan7xa_}V0B^&%Z@?CO!fiDT-;ZZv7Q!xsZ zDxo(5e4%0y&YrVNiZqgsXsnYfK(f75?MA8zw83Af@E?Dk6sJ!( zFU1S*@Fn$;!4&iR5s&EqgOzxrt|0QkwfJ-cbyPEGzw6+DuigkjU2!+!J6y^)m2m&S zej7#OA}REhAw1Z66_kmP^rhuF%#9u*!BeCh7EI>*PXdUW*~zff6Pm#IQ_jUQMgB5> z{H3xfrxpyw0~}yypWamj3sYvl7~i8Zv)@+=yrXjkov*L9=dk!miU-uz_co*1^Zv-b z5n5|S%VSlgr0bUYnkJgL*E5UJCx$Y#+3Qagn!QkBaR|msKy|iviYFg9d@np9<+11T zQ{V__4Yo=B7WB`x_HPE6bwNKp=(Us9Ch(6=dM;R~?udtlpAjf$juHI6z0mr%@_=Pd zGPtV^M=~nRH00j(!ZRR{2yh`c$#GDsiYEh;hS8}It0Abmo<-m`1Y}{WvkfAD6l8kX z;zvIkaM=`D=PT{*xO@Rw$Rwi%@(0gdwLQrXDx;SjKz3rF9mM*{!xeleow@1##8V`> z46>%MVR}I#nJXuByaLeVwpox^c@-sIrB849pWkf=kLSP)pJ9FgdOQKX z_V4%uApg?f2uuzD#Q)a-6@TF14WG9AfEs?E^56+S+`j;RQFfAJ2AjRXL5S;eDE+Gb zKPb|k3Qf5sV8`g~tiK(7wF;1Jt}nHJwzKcw|Lwoa?SI#8>TOrsUa`K7weDR1rrOhb z_lg$OM&CcfX!~tz`_KP%k0R6ly2rrx7TU|P=ZfT5^Ll&EP_fhF_7#~-Sn4}c3|PK~ z@aAL{ZyL;VV0kxnapNLOL2x89NjC{li;sq`JF4puuZ}(cFc%6%uist-X8ZD41m9%F z7ge7qOz}k#!E9w&KS%3cDRG4Er6VGG()XSZboYbExw>vvzY+RJMUiMo9bSCk4U)~J z@Vc(ajaz`C_BD^en*hxP5fx~wV>D%|?3qBN;~j6{I0Vf_}hZINzHIg&ZXqAF8h0j%OX( zqP3uJvTmKSw016O^hc+adJWu-^`>V#jaav9BR5ag*R|)F7oK3l$3i0 zPsv5G8NRTlYIqlOXWxn^gd0DwY%3emHp{MU_XyhW(6xU*W93~b;tf3E=(&Ar-4`42 z7MUdpdi;}ci1Dk{k+>kCkf>E0Y{5S$@{#eXc7@E32bH}p`t?pui2fHPsqFfhu*AZl zI#5;(Pw~ISHY$f<&-C#-`4CbI6&k&Dt`5ZfR~mu3`rg5)+JHCyvb{#r|CwG1FU3vq zYw)GG2`Z*-kNe|!Y(fRw1`HE@`X1}~UhgB~rV;X_?ses3D_PZP-uf|Bw1C?KN9G$>Hd0H%nD zLCz6Rdnvr7;=|K=BDyP7^ym6RQ`4i4R-R2%%$1zBj!; zP!Y3?mMbn;Qd0@}!l8<_Ebf=lpoiL`sFWLf3vi&^d29$_RLCpEo;V$S9N2RHXYCH8 zu@4^D@{%;ze^ZV- zPmSsh(?U&O+_O&3r*~L~Q6cW$$OjF2 zaCMq?;Z0O3ho4FrQh%uW5&Gm+aL0Ab4%V}#^#VM+HwblaekY*alT280s?U@`}4|=7(R>B1QgI{WlVmft`ro#9)|3- z&yZ0%L6s#9o9Z+C)fWU0q8-vc>!CD2`qV<9;k{M$#|aH_HYo2uQ1WiS^^YcnA91?h z!GwKV7+bm>ZdM|`wIbRaH6@ zv;mgiILiEJ*Uhm7P#Tkh(VMdArnW%8h|>WN7~KkL^SosyAv8efmzcWPeXh`NWz&Ua zYG1-uRZB>m|0p8@RuurUi-Drx5QwOJZ;LlGibk)UNUn$d|i}2*LF~f%-Mr2M~a=w@6!fJ*dBx5 z78dXRej4&Ifx|(&5_yZ}(dMLB+I~nj$H#1+ri1<6xS#m{KCbSugR8ui_Z?^_?0#`C zJ@%+kt;uWt=@hR|Y7iU*ZcxPpX%RWN`wr%J%KBncYra1WH>+dxD0!-O$7ti4!uebG zf|QR>o2?Y2zhc@D;jYV7uE!-s26qO?zwP7U`$%4D_|>nKyvjA!s+2RV&vmbij13QV%h zj^D=yZ&RQZ4UT3mXs|^hXEx zYWju1a&%XI5|9~y=B%Ya$@xdePYf8!U0vdX0RwxxKEg~*+T8MVPdp&9l(qq2D=WMg_5sy^INmD0n{f0|CyFI(s0oNc%N|*^wj7N(0N`pq z>{T0t{#zOB1!w|9LkLx2(5Kt{kF&(@3Peop_IN;Yzz55JFDSHU6NAd61C@hDaIXZs z@P$s&+ifDH1KbDs4DT33%%;FlzR?Xi{Jx-|*2>2I%UI&#zz8L~?CST~#ylxowmb3a z{rJ0^2e(0qV{E`5^a=Cue(>AUwE06V_~AfTDsgHkPG3{G_6lC0$yH{>`7pe|F8P#4P*2YAGA-a>_j4q)rUcVp0LVewon0~mM zP;>UK&(>&u-H9kE?Jt69^(h5NDhDi0XyD$-3Z}0=w?jGoZ2{%~L9Q|95rWxB9{%5jm zXw8dbdb<<{whz2evL9I_ZQtC?8jr=2Hb3#n8)nux+rLgo)!B&ST8HlF0pm7OCTIC% zjcvcnn?d;`jkyoq@A%0Zj}IbmG!EkU01qXYHI>wno_LZ*j@U?>LI!?5#zffo853~m z7-4d3{S}c@_%|n z%)7AnN<_yGH?=ZGz2M0j6|{+~E98vR(vmf$jFGp&@8gH=fHm7WX%k|DGnDnDjfvYx zn|-Vd-10`b@Pl>l15eq>8jr`4Gtm9eT*({F4fi4MNg6Zt$r>WuF!0dursf9_j6Mc7 z3AEJvdF+6~aQtXS)Gj8{(z(t}YFn7Ba=~ZY(9uq~pGA*66r|RXy!2?zy#8n`!cJVc zpU6Uxs2svmv(s@93}Sg0k*msBo}PwlQ<>7ZpNoBhcW++$wdF4ia6>4D9}%N``iAREUAhIiHrzp&+2c&OT~?O5S-12?QSUZRe;EkfJv+ zLgQCN-W61pb3WE?b<9B{<_j?2R0z~563Eb!)D7q4CuXOdY4Q+2inp})=&KHD1lt*y zfR~(ctBN+TJ+O=8(eu-~Uh52P2Gy~lRmjK|6wxlj2Q6T!A9J=r80u05h&9+7L_XZa z8woKVH9b3|keYKeIjjl1d#u?eC8s((+x<*=x6<-sNqkXm3!+#k{)EtikkW{ZfmGj_ zD=<5Zed?AFJTOXuhyKC_s60hxQ{WW5u|g&SC_;n-p0!{%IBIKXxOa*+55LLYgNE#M z7`qjv%A@@N;eP;Z*JdI7uK-;6m;k-UdCpRDI5>_sibvj;yLhDJ!F#N6=YS;fqn6Wu z9e!OD_DwT40+N5Dps^M59 zVMSU5aHwM22*fgrVhpQ`5UN~q*tgb3EmTuNEmvR+-+lvLz+0#G%kRl znsN;fX(Ky4+*0iQjR}|K`qt8uv#P@=aZsX`G;XwdTJ`T%wAKcaB$I@s$0*xJ%>+(b|Z?NyI# zZh_0Uo^Pdc(rfwafg}4N_9&jyOaSPbV!HfvhF)XsQJ2*oUV3=}!{4uB>6p#M>g`sW zi9OM4G1V!KsYfkVpR=_n5>N0~l%A~ul~7UVt2pm&tRbk>KMa}NYY~&br?|RfYFX`H zT!V-$v+#a_fjL`{MXlM7Nw{*}f@*B98-)V!(|_MMH|0}wS5)BcxxtNS`Ikx};=FGc zIv>cZL_I^E+b`5TktF(>{ZUy8cib|~l^sEZ9F(`zEvSC$+#RG8wqBgjVLP)f-Gr+M zb&s13tmhoKXKIF{2OO>v!b4$ZGOSeD2c>zRq-B!(>GoAf&*;_9@IjxvSt~t7^g1*z z@bNuZF|W{L*?F%IBI&e@ZDfw9xo4 z`_DI`Z$qkaIyP=rnm%G`f4ZW5H2Z1V2KWByYG@Ys8N+k)Q`)BVOd*?Try#oplP*Ud zl?vozXwNes(=$J%p>L^gKILM3AtQKNeQP}5R7#3~@XF~nfaOc(8Nw_cO}y@&amwJw zSG1IGKc`mtxP!~2<;CzZ(sJ5uG&Hm9jE(v^9uZ*q=Lu=&C)?2m!;`4Mf=*AqY;3OG zv9|kk2gL`wPpSz&?F5_&yB_&yB+>3OjP2|X2fAW;N-EPUgAFLfZ_O*EAAltC#8 zF*T%*aX#jS#P&g$K+`?nU%=DT8jo<;(1HR%y$}-XaHfUbU%-hJZ4T)WKBG7wkmk^C zA3;NgH7A47fubzafNh0+pGVG3PwB%kviu6>Ikx)Q2O7EfX@zx-5QKmz9kKX^riIQ( z5*xu_5DG0K2Ig`TXbxg`a5`75#a^hNs1-t{+)4#L@qeA2KJc%Kcm-@Gv}th81LbQ^ zqI1qrye!&tR9VHl?N>Q}J{bAsLvsh7hu#auQV*VhtuTM+7D!rb#Y3;DDE33!^y}vRAJ&5UJ{@N~bmHQEr0LxZ?C3n(l0p;vo zQw9aLp>L+0))nKjuo>$n=(dnoDC3T>8vy*aMS~45NgfCOy;e->uY%gj4 zLFGP>_MH&m_7vi$0nu>&cTAi!K_iLVp6nme7E?c-0c-T*7Tpl{9b9iI^>&$!)GhGP z=;%bPS9H5x{H&y+2G0|OF6-BRch2h@0BqQ>20dC`S9|^oby#JH={vV_uK^o&C6#2< z?IB9#CE4}dAwWjAY@J?UlH~<4LaR)vJX(_APjXljs?15-0b{vS)xmtkM^uTS@uWp< zR?nhD)GN?lpYYU`h+?-#m`890I;en2KFcNOholhF35i>WXZAi~|W6~qXA zKS4*junk=Xm6N$!P)`kvLmDF1q9on?vyV`9rf}SA8NRG=j-6^YR6n!A$hN{ zD?}EGD4tk}EX$-X$t=)FD7=2Wi8$p24f!V>1cHrcfg(#Ht^a&T*2pXH@so-qa?dh9 zd%_fQ<7f}Q`9><5l1V+tQ>wA6f%&of6l3C%NAY+gkJl^NuZb&=NGUFQP72%>G6G*F zQQLs1&_Mdc{dZpgU@pYCyfRwF8a-3ngTRl^iQ^+K1w zr_6kppvdr;G0`#Wz81<>pB5Hy5C)Q{Zr}yLdiO;}9XCSk!M0&y0fI>A6X!EM1uPv( z6!GRTvfjX|JPEyRLm1y;IN3B*{YN*Nq8WKI47~pVsqidHtJVXb6)o9>gEf0LJ>oxb zo{D5PtI2TlrX_GxUbCBcuC6=uyNZY&?irwI*~ z1GNx71@IKa4Jd(Poc~qfF(TbyNO+fDR9(nTDvD`75Ij}ZT`5#Zg$BS+7P0ipn6C(A zhwyx+B!{diA?Z9U2+i!gHpX+iY;8}5fc`Lj<36a(|FmZC#`C;2qc?++p>UM|RdrUL zOgw{duhln1QIY^;Q`5q)C91*E8eBegAfZ&}TCi4XmbaQj#0v*SXE=po8P}8EIgb%isb%x4s?xdw63_ z?*=(UWXjYKlc`)3Y9q;*8ZPa1lny9dqMy~5B0!^mz2+jeJ!UpMk{%1@Dio|I~9 zngd8taT(lTc~iR(1lZxZ?RxZd0k%0`Q~D$h4f%A?Q6g~P$wPRlZ2h$E~h3P>}$VbZmD@X+V6;0G)B@q`q! z?U$Yz_LIR6k1uC*qK#hW((@D8-oM|!rV&!ly)GFh#}xte42GEzhW>*jG=edg^cnkf zLNT5I$b<~5%8s_y=){H>`X5?`aJmLt??t#ApU5r1RDED`Vf}rR=JNe;#NE>m4Wd1d zOUe{E-wC1ExhOr>Fl*%>QM2vy&2sVc8JTS4zKF{@GY~M=^Y$0ix%=9d9T#1FOP^;_ zI(zQ^MjXFfPG8H->L!69oV1jkDp(8qjU_<$mvEI1mAc-hG)LmVbbC$nV>0m@8NY~t z|0jv{T3i3aqwq#$zFyMadTMTU!8k=%NU-V?A;ZIGDSN`~C7<+@bPiVYOD=%IkJ3y1)!ts}?)K>UGPAW@`jpzUU_wSy0o?wlux9h#$e&@XBdCz(8!S8v_ z`}6(h&-dp0{DSX$-K%mq+hk`6F_xgF7ZeJPo+S<+mw?`AWGl!P5Y7srqoylK{y&zz z8r(t>K3)5YacEij#b{A|KBJ3Ue$vKNqf}8L(^EsCPC&4x)aRq05Qlm|aLVZO9APG< zC@80nBjw&&RP77^PXK zD?zxlW-{Gx0T?_JX%}BK3%G`aBGBR~WxCgdB9cwl(E{zmMh2oK$(|u(OJtV#ymQ(9 z*;*s~b2^)m5>$*qJU$H6PK!6RfPk`@Jr)3^l5MH_RFGUSQrUMqks)>y-}4phC26%m zQE&DSWc26!N*;On>c+}r*{*mLrjhu@U^zu2EFNhCD`qW-Y%7Dotd;b zwci8Hy?o5?lgvB7J`XrE8~S-+;0inaf{eTBMP~W-^sU*@Q!}EYXH4fyKF*BNNHZ%w zE+^Zw)Xvfw+3u{;nVgRH-OZ%#Zt>jP#Vm(ryw#l~EH|5Ra2;=XuD)y)H*6m(;0>IW z-XxW~!mvDy;{iGBmefvq@Wy6URWVR2QQ^Esafl@8%t?9CB)abuk|6l?A!Eft`qi!I zhaFkLijah!&4RBOb<9GdP^h$(6}=I(YBG!phO34s$}umuEeeVO$58>(X>@aP!BcZ! zn_Jgf%iJ5E5oFgn=7iRf?0$G3uqO&1C{CocAoo^xhe!8{BbNI|)Pm8nJf2v5vxtkn zn4fwj^t;8EfPq%;4qgIZE4V1@65QPSFxhIW8jSRdwyz_(Cg|Rh9{AMeB=&78=I>Jc z*L=ao?0vgi+iYWk&3+Cik*fb9q@rTZ?8TqmGD;^d@z0(rM8ef)(-0(ch}5J6eoxcw z4axm+eI?_5?mO;7Q0)R5yh}T@2v&3T9vF2Vn7<ze|ys%-cF+yMBl}e;jJ5 zZmjr(z>h@SXS8)=&2*Lu71yXZ8Q`0y_K8&D3usa>Q{2<*r9uJcSfjtKx!su^RPVsg zaV;;Md=T7ST(d?z;d~UOOfAn!ZM{9`8*fq<(pDaa9XqJON|A$16q`mq)7@SP*8vA| zZ6T49XuyFodB`(lLWb_=JH=ELR~mESrXr1NQ$3bz<4FRe#LW$9bX5O5g z5lqiW<-yqk{f^kCi^`mq8O$Z72rYi& zmYQ`rE}36zoS!IH)Y+-kB{M@_b2Ox8*pd5Hn!V_ln$Q#pQxPhxm&IUwZ3xuo86D9l z?9N%zP&D6TqdeWeMbV$nZf8b);$T;ie42e1Li|+UTkYMF+Mjnj^2YAic?(Lcq+D(G zucG7Mzl)BCY9iyD@*hRVzcgHSdt3{Tb>WI=IIYaUkazVxBU>d87)UUJruX7oha3W3NwjW zT3Omj`K?)AWIfJ_iBr_&0Gb*zxJg{B;ZD0dq@iyZXwV@fmH~}13n^Tz)dr=zX5~B_ z^l6CMNiGUJ#ISO?T)T$)nrQ<@&j&1jT$y^o7UOTKZ$pofU(+E9R9-17uj5XJLWlRi zjr$OSUX}&bF8BRD%c@wEBlnmWP~p(okv?M#r640i4h>@pqUJcZafJvbDsh3ZGC z)50E;*x~X{`kq0(2M$uGFG|*ij+F1~riMMBbB@sv<3Wi?O!TctiRxq!bB#TqQ{ml` zm~i3(T~>_OklhY2B@|wleJd zQWADN;j1=$_`s$4z*g^ohgeCYX#oNpKkpP!hP;?|+d6u}7h#w!zMD#~0G5aAFW+3h zaNB0cXbbmZU!||D644b0GSzzaYFwV4FG6zp1-fMbVOEKDI8{6}cu{Gf6)7b%h-mL^ zE~ls@bT4vbU=2>8_7`>QAfeAD5FE%Z>C0ep@E29_eR5ZkeC|Np^a_G zj_z3ATEDkE@F6-m%1lWx ztdjj9mYX_B+EdxDXWUNHGo~}L8_y_5h&deqc_>^;J4C|qVr)7(GLklnSI;3^9};_mvbn@nR>&O73g0Bd#?7}L9lLcIF(nU#kMZZ@-e|)~>+|xKyd$XN1@5<5@(^Apu zS>FIy#^O!4=bP{zfsB%Xk+2&}T6M_)SJivHOrn#?$Q z+P(R^id(DqqZ2g{3rh6ywpky(#QAqtiNG zmAi8B!pdk}%4kiQ8rasI9m%y_s?7q}4FZ=c2aKIrt(E*b^V>DpDwyZg@;_prYC1xC zI>R!>>1wlA4~6OQTxZh@OjsUaYF`jEzLRDq7VV8NxZxWjHO*2tqGsBbj9WHV+do!c zY65+2nY6}eTV^k=eYR!ov(i%0sX;tU@9SpE`DCBG+^s*%-R*6esg@-`mlRtGC!`bw z`(Kp3CEk{>u(sTbU;Zg2Nqg%Dh3Q_)bU=LX(Z@_X@Kk46O82TMR)B|x;hjq4$EUO5 zol4RVP3d|*QBq1W?9FXP)h7@fV$Sc3lna6SIQrTRKnYNvck;piud(uD?^fxRzev6-%m z;3~LW0OIL){}vjZ3y${Y=hNKT4f-*W-hNti!O{IlKoAs_Cl)}fWNJacNfA;(G~`^LYB$kG{mlO~8D(q)=F zz6s*6OVgP=MbYofm_PJl|Iw5GNN4_$5B(yQ^iwk`$|IfTsO;+kL|n<_MYb)&cwfDi z?XnJw_i$ghGMdCr*dK4;zT7jUEHQz&Mi0(lZ1sxE&Y{b-^)GeHyp>p18ox$mw!VH@!r3ELZ zaL52x5r{P`JRk)vJEU(z6nb34-CPQ^ja{Tq;se5=@CHEHmU|b^gZS*S{_&o zx?nMHNQ2T14*dw6zotQnW)U3Z{Bd0>5kxB!&P{D-i_$3x@)L-Dj|?9VG;87@Iq6o4 zR57@=s7qZ-A+q=ndr(rX*^Z~d;1>?Lo|Q`yrBXs0p7zF zCs#d36qFZ##WlVMOgYnuI<#S$bHlK3G9%c^SY1Mt&DbwFBDc(+`@>*+vVS_EZ+j$# zp4FL|m$MH-dY5&w4?@-J)rZ+geei^9+Bu>(2Pv0-+iD6%mwtnI~{v5W9J(KP1RMB8nj9(T%QQl=|$R? z@8BBf4l32uvAg(AzPr`eu@BW7)Clz=?;HrAuo?5w+eMxP*PZ3Uvb8rKFk z>WfWj7o6qE$Ixmebz~1=RU%fP2`4*&Mb+|!`{EK>lSumh!sTx8cX@kQGrH3Q3eo?r z6^r{Ytr@VV*13&=O~X5Z2+7f@Zu~iqq}*F-$uFy7TxLHER4eag7*&cfMz&-AhAF+P zlwy|vidIP4OGW6P>-Hff==IO2pYK^AvlJlJ=L|FceT~9tTJw`;OqQ!^RF{)4o|yXG z$xoby?8#FHg0V&>G*a}M-p0PGNIEx|bMW2uXDZRGRP*jCPywc6N}~?`Pz$z5|2N*c zAy-7t_gdrM=CyrLCjB+URaE+Uvqb5XMN5ySsKHsA~8xe3> zA4JQV(N)kUs6l9n@53-TS= zgW(z&G29TrDAgHOD#A>)lA6orvnVPrAfU0td90>ZS**+EYn$D6bIVO-d$W)OXy#;?2iOrTTdwm^Y71sX65_X3TX z$|%7{Xae}aqp=`Tz@xALwcw-4IYgi+>Hu0m7P#SKKwKybpCGpFVjWrD++^BT5U-G6 z&j-ij1{I-$MIEI0hM@7sxS#7see}3m!fl5Tho3ylAeV0;CunvYY&1 zcu*HUK}}k>`|u2Kk1W?ICOHtO_KkD1Qu%z!+|S3xzUJOSHvpe0o%=Y}DGxo}{o*0q z?FSC=HRFPbeu8xZRO43K=s2mmvSFEXa*w)ke?18X(1Cxng}&l>Qffzz?XB`8+Dw0Y z#Z25@3~>BE$yPWS0%O7aSU>H^{=!fB83J{qF~NYddIdPx#1wJ|##cah3t1$<6MO(3 zI37(L^XMlDrRxB(S_KnVvD=rg@BpBJMvUbis3`J4UM_!%d!)TM^{XEoG6lBl$QOPN z`;ZIPAXXG7J9ZA|fL}*GyY@Q&tAnc?|lhP*peEMx1@NpoLih@Z(!D_DY?xgnJ~TQuBb0UU(tnh5dlL!U29V z3t<+qcajUcpd;5I7GK?y;ic_LX!R`N{Ybog#MZ+Y$pig}#v5=9kGnyN^*}3up(F?w z-~|xi6zKv--5^Z?Dqucj9q7(?hXHPYSq%0Ed@O)pnldbCPHODmW0i?haTb)yhyb1uyunWG< zo1=mqmE2b)mza{4UDSOZ*S~bSydyGaewi-k#;X}`R5mqtv~45u6pd+EfUvpM6DIT& zdEgcHaZO3Q1izdDx*%2-Cp-OsF1Q8Y=P(l|Y68#?itu5-IfXbdnE`)Ra{)4Sz$}3H z*aHh=m`Z~Vqy_&l7Ubb^;42^(KmxotUYG^sjds^LfTTD8Ex`Ee2vO4#seW;+#M4~w z`=$8qgZ<2%@(Wy-#+Kk8 z7^`5tRi+f}%SCBMkK0WarHc0zX@wi12lx@=O%4MbE?gH!fUc&80!|i46`ObJMhT5u z1nU5ZAR=gBnDd2TFit4={8LJBN;lj;1iuZ2O=HiTocNab6JpmqwVoQR1%Me|Sz_(j zF7bebreCh3jidrQq4Dd?hq0_}um;*dBlq+TyAUEwe0U@_s^eSuY&2^fO9QXK25N|6 zJQIceLr`J>T^I{0!s2|p&wXze(z4=y9ZwVRubK4~1a8@tRl|mt9crX~yfyhBx(M_U zbyp5}Xv(qwY%lkHNv!Z+D@q$yG(Ys14nJF1{&JKZCm=x0 zBIfxWVNxW$tCECE*7X5R>B@D$r?v$?ffU=|@Aw1Q0Qphz`AA_~!mE;qOJZZ^haqYY znSvTHeFuJg^l8ix88Bn(%DFC`EWwYj4nu2gkJ8czAJ^!X6vL+*bA}#5~?* zE&Us((*2rfbUxQD_3xawe+hdz(I5EDv*nvuaIMVG-jr%TqzaR4qn7zvGWGa?EPG`d z*?X-E`~vC0-O0}V@E33bv2B4WkAedE1LNn-2DKc+&juan3-0EyANQmIbtB_+3@?sh zPz*DGFY5tV`^F2V0djyY%ms)zR=_V>0{1zr2P{DVu*2iF%_!{Hak)98;#)MM&>=KJ?i)=C%4Uo9hvA5!T{|&Ug z^|M&ZeHHCt08~st3H1ymrM`(O%mY7BQ#ZWxKZR2}!e?v5+}x(-^*1Rd<({DfB;02x zJ{00!rsnbRoDm5>G@2=GdPKi}8FInZp6GJSxaDY;N8l>@R>;W))+p86eG5hvmh2i^ zV?3YeXHG)vv;>E3%HcZTvcjDVkZidZu~6NWVG^-im#I0!CBZ_FD&4QEn?clq4q%;c zlPZlvME>7=v`maeRgSU`b|&PzgGN58_>;0RJ5u>~G}9YX+4|+;gN~Z2#-kQjEM#sA z_S+(5LnhN2S_2zcn}(R(LK}^#WyV0rJxsg!j7hI_c1S|&yYiy9Q`y^$A{SlW7o)Dt z;d)O()j5C_l;LW%Fb1np;(Of0>a2CWt!>Wi*F~$vfoi!nk`1cmnn#uD>r}rpi{#Oo zX&PQqboa@GfL_t%?V=vRBp1Aad-X^6Vmm7NXkD*Goh1QF2;rt##-i)m45p6>fr);@BfYSnEfSW!;%VJ_N-GKGj9(+>Dy4V8 zp{?MY5v8=VNTmW5^%|eXt`~>o5~86~2v>{j6!eR%QC*juHDN9&veyjD?U8-N7@*@C z0g%KJC~#E1<24v5iSdvZK4S}zaYuRcK2TS2q^?j|UGwdSg?}?R6^Fb`a^RBj{eJT5 z$i4hedjVN(ekBzD6=pju3x@;HRz-ql{pFRGVhX$BGIL{Xjc8=5NL_(oQEQ1{(NwI${VP5pAwT~m$(jAv#m`HYUrK4eSqo-d z<%joWlt1&9P8L~pQvuQ4T<#!rcYpkG8>60E-j@yBG-S3o$ZiMR^B9~la}FU^Ho;kf zb1RhrY7np(xi;04!(ou$b{Q4_7-sW}|K6u`P(QWEH&eS+x}K{(&0-#PR)^I7GeJkh z7wYU?wckWR@g=emBw2s5mb z%loJ7AwdOh*81BR;^j`bF&q?X^>93r&~>|^)u|RKYc6=nyK8t@3>jc9+TNmHjj^bZ zDHcgO*Kw0D2-N_5!~(8eBJGiBX$13(k()?`C5Q0F4RdhT=GzTVa;lHF#%;^yuxH&+ z@fvkEH^m1{yb+0T+jr{Lu3w10FxQD;t|BzEg~idJlW(k5zdM2Vb4yJD=7R@Ef4lp;j=vY+1VBgmg*b&n(X)pi`T?vcF> zGLbXhi4VQxcn6Zl!_0A0Kab$ciDcT1TMJbp8RVo8bs`8qC?~@x8oKPUDedKnd2TS} zj&eN9@{5W1YkXiy6^`+N(RUDA^F@qwwjoulxPr4>6>*bv6gTz2P&K?V`N0<(FK!y% zsw74wS-TvYM;Ss;uI~d|t66VJt*vjZTD^wk7YMLPeeaPp-NBWFbV^w=^DFNz;9WI( z!P8sj0$s6N>)np_=I8kzDCQ1AdEZliv0#Pq3y8(1{)St{n%*(0c%{a%nj9?vNqLM z6%f)<$(k&B!r?@&Vb3B_*Vh1QK$X9PbHSc6V&=-Jan5N|NCk4HbZB0*$%trIDKh-#g`1S)bgl!{f1Qvk1|yV z-!@ea^{k2>Kd~x>o>oN;A%6Iz4;!$QL64s*h0S(R4DalfL&7iLC(e~ag$pQ#+>YYC z5(giZLxIJWLFbh!gpYYBhJ=jvn)yT{V5JbTQ1Z*)XkWR~*KA7Bd|_sC-rTAYee|LpT{&jyN}+jJTd&A1KW!?7M$%OW zrTd+{l|yb@?oZ{FL8tMRLK^6>^3eE1D#;MN6TKmXm8GL|NtL6g$KMyc0t}`nXQ(Lh zu3R{yqQ{|v=Yq&E`vFHWAW$e_ObFO+J&^&yAqJ)k4FA_55dYRXD7{!Ag_)hzH4ih3lB70 zvujUDM@rygP)Kk+$uu?HJ5(#3$stLHYK4zoB!%I~VWQwR*ww7SGsyVGLWOp?? zwrK1I_(r-YwOLg2B5J@)P%3+gW!}Gk)!={A!^3jwc-p-zX+LJ3jH5$emH-!}v z%Zn_-Ei#nLQg7=q#%W)7XC6>0Rn-rawsKrme7b^dN?T6MKnmv^6R*aybx?<`!mp%$ zYrxW*Z4hZngZGkUfctqOL*F22-ER0$C_=(0l=@$fu;nH|)NNm5^S*6cPC&oZrYj@! zj90wTK5O_L0cGO+{N{bL<2FNO^fp7NcyRw2eboQkKL5i$;*h;~t3KH_ozu6HqoQ$3 zM?#}Nu#;1|NtyQT+$hhrz0A*u6fp8r?ex9AR*r^xP>t!1&#W=RP?PegD75UC2Ps3V z&1##{(?b{>DS_o2xTDI>>3erHhiFy|&%Vg0(3Z2*4knxGX(Z?=L$IKbWL`5Z=v(Pr zWn57+T*n^Ke@uj7dSK9m%+b#`oSmg6=i^8O8W>doOwv$MMy_8S9>1h~fzJdHXFSQA z@jw9bMA|Y4v>t0QCT~0;dC5-EX#_MBGhe{$-4QYAXsxC zQcl`x3SCT@ZI=!3gx@^38v(v?9D;9}`ua+Kc8g9y}f>unT*p8+*?#OUj&*FiAkBw)6gwYkMp}kG&HhEBVs#$2lgJ0@}18tWa$hjq2Ae( zfu_vo>0el=y2Q|wRvQ>~9IB(C3X8Rg!m+;#8N4`FSK)k{BZY>)3d4GEvsdA7eL+*P z7ekckN;CRX-HQOo_H)*mv^%?9nDgtbOFMPyv_}?;p~&=Va%Xt{Zb25PJJ)(6g%Xav zRxYhtI{MhT_jhcqWj-UX!s_6tDwR(v){Xro`_W>4m*_&Pd5Tt z(K*!V8`86*(=(oLrJ&T#(6gkWoh5k9#U2^WGj@H%`+6pG)D*-QR!kFTrK8l+IdI;2 zohy20G%hKP0y*`;KBOiZy>p?iTPd!wzP~Lz`?wtim0XF+C&yuX|Pm*qZlWmAo;3b~n z$nx()s1RE2G-Of%?TlFSOpY3)fX91jdYVFmwO+BGV0=+!uslO@FJ5j%{~fO(Gm8su z%tYmJbzC&Az5G5$V8?p`j=hceP{Du|mH1G>fEF73C}6+~HGUK@W4(c|V0#~fy?fS( z?6u>%uHhtIZ&9@%m1oc$h*0?U^x$vioOh)I78_=hp-TO9e} z)bBIleN@d7Jt}7E&T=~rIRBwiaQLwZA6#8(r7p`+((2jIQI}z8sN6GePeDxM93ReY zVY3Mh9|DBFa$7K!T*IpjyRn~ny>UY>s1X%8(l6_!l!oftCLaFN(jsC zQphpm4pf(6Z1dby%|_ehTRx-Z1cQ2%-gqL(k)fU`7zv_db!PNPd2dy5PFD5*K4NoM z%SVLnUF)*zv(#nYK+9 zG4y8{Z5e}l*mQ*0vGF?%DAL=hg3{kAI?KddyhM;;X~h^`T5FDW8P>g9HM9~bNr06P zf)gPAr-|Lf1}NDj)4_x%d__iZ&5~G4w}Y;~33+M=on0k&3v`KIyi4#k zr(*iOGd3X#{| zl8)rn%ifjH(hPd8cc7;s9mY;mFy`cW`s8Z9tN1e|slJTae0Fd3T-Pk?l9MxQnE;9)5ed^n5Eh*v zDT}JObMAJgnv9@d&7<=oC9$D;@i%N5BOcPLldbEk*^W(ky>}E|w6#h*lJPr?m0@`G zW5>EH5zSdUl8bkuWtnrqb(3iUt%FC^N#^UAo_xeHo9xn{Ys{}^wTcmOW$pvD{YbHZQ~SpjWuPN{q9rtBq{P<+f%?-iwDFaaS+E0`C!xPH?$$ zZ9`647~u=9u}W#ZE&xMmy8_TMNz3ru*R7kh=w|$^S+jj$&FR(6_wVz4_$EW6o8A5% zhHvg*1Y`nr!3Qo97zBz}Q1{QP5cD++*|iKWefkM47Nv#Rctzl@soy`=hnmM zY`1u>f^D-tXm(H8f^P#I{x%;PBm8VW6i3~#>3M3V(Omu(s%1azUsIv1eb|$y+a*)& zg30vPpLn~GYww6woXoFMH-i$jp;s?r|7+Nrl6`SH!&s4Ch^uS57Qf~gC5oC5?($LuaM1>T#Ev5Tgth8yYvaSHz4t$ zz><*7lhra$RAr^p;!F#rAXudJMp+nA1dg^YsW%Z-ZEKOvFiYo{8}_)%FB5I)7 z%xLn^8_G0!Gc7r>oHp9&84oOo^24$O49v{&kIpn6O$gZNhD;%LUaoBd;;Rzks|3x4 zen@^Y!J>#XLUe}i2Ay#6gdL)EhQ{+thmaug>Czhq>+Bc zE4o|;5CFDZ1Rw!wxC0=M;J6Gx0p>0M?f+Z`Bmi`{2!ky(z(jx(tAND-4VM9n06!Yw z41=-D04|pqeZ#&0X2daA0Vpnz0p#Kz5k>QonllDj+$F#ph89bJi~u&vfHxv*R{&-8 zvmh1_N_I)ndTveWkrzzSHr=8ij;$DG9K2YcK=_e#QT#-sgd1!s*2EcU{fF~ z1Yt}p)fFPJq+(oe72|i+3^lz;Na47`DVgR9<{sohGh2CRF6Ub!Uz`P>uZE&mIlMS4M6p=Ug1lfb)`2Q8N^)w3@barR_dcw5cg*^z^g3oN|+!t9oB1 z)wWYI)@vd7lm;_NIoA`VOJ!Xlq;AfbthUb;Ff(Lko$RCc++mCFP+$3XJhMmvH$NK= zBPYmDJL*J%*T59E4NzKy5#K8w_Iue8t)#Sj-8I(atj^lCzBL0ZSt3iX)>e6v!xxA% z*b$q&pA;dD(Ly}gUJ%S~L3axf`%=x%`RjU# z<=Wh(;}oP-XNTXs@5G54>j`4W68>c*1B_PVM-CTlZBDeYOg{vr)A{6qCCXTWny<=@ zDg?dXWHkK}16SU_@z{f|aR>y)54rECf#Ma?Y_czR2u6FcxcQb|7c1ygM9O&Kagx?ca7 zoxY0NvfZt#egyxVx6ekccE04jipklRBePtlAz!fTS_rlvQoy8Uq(h4 z1S5c8XaE2G_wT;R02;mTH+gRNcXxN2&F1ra&iFgzZu6by`Fr>azDDz#_zAtkwQ@$= zVo{s^36zZ&=>~SdY7Yiq_}q!P-w&02$oIYTsYQllI;`Xvg$i@fB{6gD4a``l^O*

      2S8i~uza&6z-tG9@+HT$Zv-wt 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 CubtnBH?O7;Nf4HxZzwc7P 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�Z` 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%0Dj-B$Fz=a2{{+P|#mQ03D&_dY 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 Nn;SNhk^jek{|n{!#ZUkM literal 217088 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

      XDmd8tm|w-Rs;CFF9h( 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

      66qwCG3coOQW$ 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 O!3-44!2eA%@P7bz9*C&` diff --git a/wntr/epanet/Windows/epanet2.lib b/wntr/epanet/Windows/epanet2.lib deleted file mode 100644 index 9ea26811c303b95ebda9d86ca8c95a8be0a8f6c6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 50330 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 h9`7o4D2|i`i^V{K}tO{r~EJ87Vf~aVIT3&h}j2 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[V+ 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/ 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 From 076d202cb32bb6eb5e5b24a96bd5d2c0f5d50673 Mon Sep 17 00:00:00 2001 From: David Hart Date: Mon, 12 Feb 2024 10:34:43 -0700 Subject: [PATCH 62/75] Updates to documentation configuration --- documentation/_templates/autosummary/base.rst | 3 +- .../_templates/autosummary/class.rst | 6 ++-- .../_templates/autosummary/exception.rst | 6 ++-- documentation/conf.py | 12 +++---- wntr/epanet/msx/enums.py | 36 +++++++++---------- 5 files changed, 34 insertions(+), 29 deletions(-) diff --git a/documentation/_templates/autosummary/base.rst b/documentation/_templates/autosummary/base.rst index 667f19687..52bf10b46 100644 --- a/documentation/_templates/autosummary/base.rst +++ b/documentation/_templates/autosummary/base.rst @@ -4,7 +4,8 @@ {{ objname | escape | underline}} -.. rubric:: *module* :mod:`{{ module }}` +.. + rubric:: *module* :mod:`{{ module }}` .. currentmodule:: {{ module }} diff --git a/documentation/_templates/autosummary/class.rst b/documentation/_templates/autosummary/class.rst index 9e9adf167..757961130 100644 --- a/documentation/_templates/autosummary/class.rst +++ b/documentation/_templates/autosummary/class.rst @@ -1,10 +1,12 @@ {{ objname | escape | underline}} -.. rubric:: *module* :mod:`{{ module }}` +.. + rubric:: *module* :mod:`{{ module }}` .. currentmodule:: {{ module }} -.. autoclass:: {{ objname }} +.. autoclass:: {{ fullname }} + :exclude-members: __new__ {% block methods %} {% if methods %} diff --git a/documentation/_templates/autosummary/exception.rst b/documentation/_templates/autosummary/exception.rst index 8d05ab977..e3504e253 100644 --- a/documentation/_templates/autosummary/exception.rst +++ b/documentation/_templates/autosummary/exception.rst @@ -1,11 +1,13 @@ {{ objname | escape | underline}} -.. rubric:: *module* :mod:`{{ module }}` +.. + rubric:: *module* :mod:`{{ module }}` .. currentmodule:: {{ module }} -.. autoexception:: {{ objname }} +.. autoexception:: {{ fullname }} :no-inherited-members: + :exclude-members: __new__ {% block methods %} {% if methods %} diff --git a/documentation/conf.py b/documentation/conf.py index 0fc5bf7c2..71ca52f48 100644 --- a/documentation/conf.py +++ b/documentation/conf.py @@ -45,7 +45,7 @@ ] add_function_parentheses = True -add_module_names = False +add_module_names = True python_display_short_literal_types = True toc_object_entries = True @@ -53,7 +53,7 @@ napoleon_google_docstring = True napoleon_numpy_docstring = True -napoleon_include_init_with_doc = True +napoleon_include_init_with_doc = False napoleon_include_private_with_doc = False napoleon_include_special_with_doc = False napoleon_use_admonition_for_examples = False @@ -69,7 +69,7 @@ # viewcode_import = False autodoc_default_options = { - 'undoc-members': True, + 'undoc-members': False, 'private-members': False, 'special-members': False, 'inherited-members': True, @@ -77,13 +77,13 @@ 'member-order': 'groupwise', } -autodoc_class_signature = 'separated' +autodoc_class_signature = 'mixed' autodoc_typehints = 'description' autodoc_typehints_format = 'short' autodoc_typehints_description_target = 'documented' -autodoc_type_aliases = {'DataFrame': 'pandas DataFrame',} +autodoc_type_aliases = {'DataFrame': 'pandas.DataFrame',} -autoclass_content = 'class' +autoclass_content = 'both' numfig=True numfig_format = {'figure': 'Figure %s', 'table': 'Table %s', 'code-block': 'Listing %s'} diff --git a/wntr/epanet/msx/enums.py b/wntr/epanet/msx/enums.py index 73d7134fc..b5e67ae78 100644 --- a/wntr/epanet/msx/enums.py +++ b/wntr/epanet/msx/enums.py @@ -9,7 +9,7 @@ @add_get(prefix='MSX_') class TkObjectType(IntEnum): - """Enumeration for object type used in EPANET-MSX. + r"""Enumeration for object type used in EPANET-MSX. .. warning:: These enum values start with 0. @@ -52,7 +52,7 @@ class TkObjectType(IntEnum): @add_get(prefix='MSX_') class TkSourceType(IntEnum): - """Enumeration for source type used in EPANET-MSX. + r"""Enumeration for source type used in EPANET-MSX. .. warning:: These enum values start with -1. @@ -82,7 +82,7 @@ class TkSourceType(IntEnum): @add_get(prefix='MSX_') class TkUnitSystem(IntEnum): - """Enumeration for the units system used in EPANET-MSX. + r"""Enumeration for the units system used in EPANET-MSX. .. warning:: These enum values start with 0. @@ -103,7 +103,7 @@ class TkUnitSystem(IntEnum): @add_get(prefix='MSX_') class TkFlowUnits(IntEnum): - """Enumeration for the flow units used in EPANET-MSX (determined from + r"""Enumeration for the flow units used in EPANET-MSX (determined from EPANET INP file read in with the toolkit). .. warning:: These enum values start with 0. @@ -149,7 +149,7 @@ class TkFlowUnits(IntEnum): @add_get(prefix='MSX_') class TkMixType(IntEnum): - """Enumeration for the mixing model used in EPANET-MSX. + r"""Enumeration for the mixing model used in EPANET-MSX. .. warning:: These enum values start with 0. @@ -176,7 +176,7 @@ class TkMixType(IntEnum): @add_get(prefix='MSX_') class TkSpeciesType(IntEnum): - """Enumeration for species type used in EPANET-MSX. + r"""Enumeration for species type used in EPANET-MSX. .. warning:: These enum values start with 0. @@ -197,7 +197,7 @@ class TkSpeciesType(IntEnum): @add_get(prefix='MSX_') class TkExpressionType(IntEnum): - """Enumeration for the expression type used in EPANET-MSX. + r"""Enumeration for the expression type used in EPANET-MSX. .. warning:: These enum values start with 0. @@ -224,7 +224,7 @@ class TkExpressionType(IntEnum): @add_get(prefix='MSX_') class TkSolverType(IntEnum): - """Enumeration for the solver type used in EPANET-MSX. + r"""Enumeration for the solver type used in EPANET-MSX. .. warning:: These enum values start with 0. @@ -248,7 +248,7 @@ class TkSolverType(IntEnum): @add_get(prefix='MSX_') class TkCouplingType(IntEnum): - """Enumeration for the coupling type option used in EPANET-MSX. + r"""Enumeration for the coupling type option used in EPANET-MSX. .. warning:: These enum values start with 0. @@ -269,7 +269,7 @@ class TkCouplingType(IntEnum): @add_get(prefix='MSX_') class TkMassUnits(IntEnum): - """Enumeration for mass units used in EPANET-MSX. + r"""Enumeration for mass units used in EPANET-MSX. .. warning:: These enum values start with 0. @@ -296,7 +296,7 @@ class TkMassUnits(IntEnum): @add_get(prefix='MSX_') class TkAreaUnits(IntEnum): - """Enumeration for area units used in EPANET-MSX. + r"""Enumeration for area units used in EPANET-MSX. .. warning:: These enum values start with 0. @@ -320,7 +320,7 @@ class TkAreaUnits(IntEnum): @add_get(prefix='MSX_') class TkRateUnits(IntEnum): - """Enumeration for rate units used in EPANET-MSX. + r"""Enumeration for rate units used in EPANET-MSX. .. warning:: These enum values start with 0. @@ -347,7 +347,7 @@ class TkRateUnits(IntEnum): @add_get(prefix='MSX_') class TkUnits(IntEnum): - """Position for units used in EPANET-MSX. + r"""Position for units used in EPANET-MSX. .. warning:: These enum values start with 0. @@ -384,7 +384,7 @@ class TkUnits(IntEnum): @add_get(prefix='MSX_') class TkHydVar(IntEnum): - """Enumeration for hydraulic variable used in EPANET-MSX. + r"""Enumeration for hydraulic variable used in EPANET-MSX. .. warning:: These enum values start with 0. @@ -427,7 +427,7 @@ class TkHydVar(IntEnum): @add_get(prefix='MSX_') class TkTstat(IntEnum): - """Enumeration used for time statistic in EPANET-MSX. + r"""Enumeration used for time statistic in EPANET-MSX. .. warning:: These enum values start with 0. @@ -457,7 +457,7 @@ class TkTstat(IntEnum): @add_get(prefix='MSX_') class TkOption(IntEnum): - """Enumeration used for choosing an option in EPANET-MSX toolkit. + r"""Enumeration used for choosing an option in EPANET-MSX toolkit. .. warning:: These enum values start with 0. @@ -502,7 +502,7 @@ class TkOption(IntEnum): @add_get(prefix='MSX_') class TkCompiler(IntEnum): - """Enumeration used for specifying compiler options in EPANET-MSX. + r"""Enumeration used for specifying compiler options in EPANET-MSX. .. warning:: These enum values start with 0. @@ -526,7 +526,7 @@ class TkCompiler(IntEnum): @add_get(prefix='MSX_') class TkFileMode(IntEnum): - """Enumeration for file model used in EPANET-MSX. + r"""Enumeration for file model used in EPANET-MSX. .. warning:: These enum values start with 0. From 63d782a86ad663e5bff1792d56d341ef9138a1f7 Mon Sep 17 00:00:00 2001 From: David Hart Date: Wed, 13 Mar 2024 10:43:20 -0600 Subject: [PATCH 63/75] Fix toolkit problems. * Updated MSX binaries, PR issued to EPANETMSX main * Updated toolkit to match modified code in MSX DLL * Fixed an error in the filename encoding --- examples/data/Net3_arsenic.msx | 4 +-- wntr/epanet/Windows/epanet2.dll | Bin 262656 -> 418304 bytes wntr/epanet/Windows/epanetmsx.dll | Bin 147456 -> 345600 bytes wntr/epanet/__init__.py | 2 +- wntr/epanet/msx/toolkit.py | 47 ++++++++++++++++++++++++++++-- wntr/sim/epanet.py | 2 +- 6 files changed, 48 insertions(+), 7 deletions(-) diff --git a/examples/data/Net3_arsenic.msx b/examples/data/Net3_arsenic.msx index 2b7cb2a81..bb01238ae 100644 --- a/examples/data/Net3_arsenic.msx +++ b/examples/data/Net3_arsenic.msx @@ -50,8 +50,8 @@ Arsenic Oxidation/Adsorption Example NODE River NH2CL 2.5 [REPORT] - NODES C D ;Report results for nodes C and D - LINKS 5 ;Report results for pipe 5 + NODES All ;Report results for nodes C and D + LINKS All ;Report results for pipe 5 SPECIES AStot YES ;Report results for each specie SPECIES AS5 YES SPECIES AS5s YES diff --git a/wntr/epanet/Windows/epanet2.dll b/wntr/epanet/Windows/epanet2.dll index 0ce700d9570b49f4c39f1c23e0146c7eb86126e4..544c418729b1f018466c8f25e2c5a46f346040ce 100644 GIT binary patch literal 418304 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�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 z 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 H5C8rjA~xqY literal 262656 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 CubtnBH?O7;Nf4HxZzwc7P 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�Z` zD=ug^`DH(NDoV4eKSd*T5LQu@imXXfanu7>R&^6uBnJPo%a|caw0Opzhtz=2$fVeO z=DFN!{!7#@-s_&Hqb>MpiyG9-;rGX7>!U&x;Eim1hrh)E*g%mH8c!2gOg*nf`I8B*Wm~doiH3{T`=Y~)Q)elAvvCsDg${L6YFqhtvBWSj!8A2(Nio*VOzb>|k2M^ZfmA8M}}C_2X|6f7kQ3n7@Y+3>)}+jlbNR)6-V+ zCwbgIwQtCMq=KS=1|AHoeH&xhB>~KUSn(xHls!5Vu7ph|BVaB}MRCa^KWg(R?0(p| zy~*8zHQ1-Jeu}geh`>8!4?+CyM)5{aK`uK=?kez>twT9F9|H_6IfnU5*UPFlQ|8}P zK!B;KJ<`kn>;SNtVbyR}16W5B2Zm5#Z_z}Y5IHQVa`jxVdes2Om0hrT$b@L-=FySh z=KP{?uj$FMrcshh~YxG+~H<_TiYy@i@Q)|&zz)9XOtwnoyqTYJG zNf_X@)}q%)QLmcGa_cCrH3ROWeGVivP$w={`Sr0LPD+zprMkmfe7{sjJDyX(pj9jP z=m=u6J|rGJ1qk7JG3LvL*iMv1>bzvFR&;TbxFGD9B}>d`v3p83%H^J4K*~7bz|yb& z+I{TX03$U4YVN%3*ixxWP{n_<`VFfGI1$Em>qt1}R1rnk&cT=|Ce2hLt9u&&o3{%6 zYp_e%_{j^D>7~nd$z0-&m)bjHA73KsMR`u$i{utZzCz?0yb=ROf^zJg>ffFr{_SEv z$*B|LNor<$LV;_~!(Xz*-VvDb8mtW2De{2umy5YcbR)qnxKD6L?8A$Mk&;iieX>DE z^wXdH;f++$q66|zz8hrOpE@|ag>B%y<~8AH3i1p0E69Zk@^Wcdpf3Cls2%@JB6-SP zJN?89F)v_u8TPr}as862#?{orRa3_PR+v^k-CEIe*mj~M9yv|pDPoTc9*sS29kCR# z$MrdyYu1l0uHIFCw%=NfSiZ&H=BsMHBK+3t#Dn!!ecj(0OG1ojkDJ18zV55qOSs3e zo8SW$y(h9G%sTWWan0F9@bAlJw}721*hzIA{9Dn_vMc}-*0rCwQRSr=g}FZjA5`cC zORFx&FUhqrgc^=(q-Gz6*`WQF+_!phz4}q*rdhe(9RBk7E8x$|-$eeV2BKAhK_2%I z*d#sl9Jkv>&n;pdCQ030Cl1@qqZUkfzGBXy<%tS8U7b0D(V6L`c&?o15TxQy#rDTQXE4+vYjd2Sxn2nfkqjLo%peq}B520sFH+cwhef%W3KXlmVbmcp9WOZnrIZ zwtSLPIxu)`AOqkxm7h{obbP2UK`klq;994|Z=4d$iw&T#Br@PX0Y-&gSMt>)LU)Sp zB`$d3r}FW4B`CFdE!#lWr=rE&zw3TToh`s5}O1`%+ z-&+0~HQsoh$E+ZMLm#0AcBG^u^`SMyp0;Z8sLMr+BGe3+RV_{%1oZA}KVOVZx*yTW zFdA+p;%RSd1sec~wM>F~HA>H;c7g?$4(5{N*G5~bGkaFom-}$X9dgCU{-Th-@wzcc z?;qgw7!1+A!jnVdB1s=*iTUfRtbFf59H!x;orb5~++Nd}?KSE`PX z-r-x>OK8>M{&e_~4z)TgrPbgdRvIqX74sHa{K(s6{PY%qYvq0xf;dA;+#+BFWPL=OO)(ILQ!Qvh>D;%gZRQD-U{ z7%o9$DZHfjMX$(O$6z79T#~hSm%L4)C;Z>oEG~jP3)ujgRXvcx_VeFCIur4AZiPu9 z9ZnB*fOJlC0Y+5lT>z+7_-{}R5M&+A8>!rKb{AS1;zVQoHXimz;070gPp=X0l&ZM=s*>avnKO!~@39oW8ivcQe(L&i$2=!6Jhw7%x zm;hXvNZ6PR;k9!EW!Gd!(xVrqN6uxVaiL%%b}Nx4SuuL~BYzW2#m50acwd+KJyaQr z6U`qmmp3ZnE)X36LsG(X`kw@Pzg+OKr?6jTp9V!UnT(zo$DNB>GAf8Ezr4vU%X;?5 zWU;+1#mMUv+eFszzRZf7{PqOyaKDEgKJkK{dr{E7c#^K$?tW(3dhx$5vDcSotScS7 zzTN$}@?$v9SM*Zlb_1Q5pz9dEG`$|9X4fwrs9Vy{5lCJAXr1gFRFPdTpbJJH6BB+g zI-d*Lo-Ud31;XN-0(RW;_~XJ}@iv*wZqc*=e_sA3@;AvJnKl(!z^X=LcUP7cd7u}| z%M-Hn2a49s{)NpA*5e7}x~V)T(6Clz9++C;pzbW{(VwStA^dDE*nGakX6@R2FH;m7 zV`R*9qDMnfn)<9_cg*z1^Q2C`B|QJsjHVyXe%OHMsH>W%I4?`tJ|o+2$VMNUiM*Oy z7@3sKy%0Has|sHW#gDveAaYS*^U<8b>nDOv@0(dAvbIDk%m&oDmJaVrb zj&q#znRU=z8){^V2klqbQ8M0L3qQ~u@5hCn5iRVJO!n`6*2%LPaW)s~o(aX{{#0z8 zJo-L#-+CU#-2uh(d%j#hv0c^T0#S?k+f-!dP?J@C3&&pVjH0ki3#&TJ8}}DRX5^tY zCh8*@e*6AxzOW@A^T40M#nsOvCdC#KBHK)eKkI}DiP*qql-d&^i6)RsgI5m93nwrc zeqRpPx|Tn4WoN?Uxku={dQiRQ&3}Wyam*35AJUdX>|LoCRtv=^G8R-?HN{w{IV%d? z-zif@=>7uk(NMZCDcjfqdLMv4MRC!`a^65d*LkG`eI*)7DZO9=5i99>$n96c>G6`HUG;45w*zn6A>|4g4qfro2}i`B{EA(cM~l zCnkFZvpBkCI)N@#Gq5jK8`_;f18 zOUs&A{Yx`;0IX<%y8ibfV82!U7hXEe}{jOLdHd^6s;46hbjg8xx zUTo=@>6Op)l3P1=(wunWSLrXTKn)2~`9CN|D2xbVT43#G=@c$vyoKZl4X(78!_|rf z2T~dwu;)f6*`wOBzx=HEehSwG1t(E1ShhWh0)Mjqq)L)7~7&!1rjz-nlI+8-90Qcj>BwPV{`(R(Sj*{sR2*^&)ljomOD^H$=uvtzA7s*h|%?}dFbLVMjs%v$_8m9;EnM>-4HH1tyh!jav@9@BO$`~L4!*D~($(6ub% zPGJFKrc1wHleMe`dVgf7KQaeU$9nydt7nR3YC`rW#o|HABd&n_f3cXK7WCuslHQZp z_{Q2Lo{^V`H|E%UPUey4@_bU)Q*iP+4vtRd^W?7@#!jUNDUQ~(G98mBwQKn=DLAPf z`F^j|Fc!H#cR@jXq*~F%W6Y`%4*;{MdVhzaSsy=>1S3m%$fnX+{N$vd>!`(QzmWTo z=i2A?S|y|)E1@olB5_S+`ID7!qMZ1PhV~WRBK{#*T4hm+UrhdlFNdRSEKm255;?b* zE8dk6Ia5~bVV_4H)#dDXGQ;g%`R+(wIp#K(Ed=4H%nfmzc$i9JOU6hni#J%}b2(2b zg>~;MzEfHDZL&sbc4lR4vgVbIGH00+sxsLnXnAqbd!g?Q`@BwUm<}9KttGi++{+g= zC+8(RFWzq0ze&q)lAVa0$o&d|E;k~h>fD**Chwql{B%>LyOuarqN^o5)vc@49XSV5 znPR%R5&w`L={%d0`bn$aAw=J@+Bj8XrAT;AZe4Y~KuYwue@G9{V z(ANyVmes1`Jj<#%j{K@jo)%i^w?Bu2^a_~Z@huY&_EE^ZfKiN{h#o03;bM&<7MlWf5t=IZpw_16X>bLJ*_$V#ZrSu+j1YQH)i`&A1oxt%<6BZ;wRA{O@vG;Cxp z;nV2FUb?Yra&ipB}g^S==kA{W6|(EY0ZY zIwEFhw*8&!q73nibAikxF;-)-X6B(x%|$UoFJr8Z;(99#L5@A<+4k)*{qRI^_4(Ij zKzgzOV~^?ZjW^$O24ejxCd&kcJc7RI*ALV^YeJatY5~we6(V z;?9?r8ZM&-nG^kV=vIo1CDcCWp!1=W`S3PWVAk){`JncnA9u)pk>enK6Eh(GDnPdk zxnuj=e=>^PAd;73`;!4z+u!gGwP?95>QFadYsUFl#@Wn|1C6$y&5G2~)=maH)Z~e7 zlOk_e;qS4FYFLwwf^xkVlW8h;J`X11>vgx)taX>`vrf>2=iFPd;M_%uENNc3C3)co zGKE;sg2Xr})5XjzTvl}?n-9J|MGO1D2(9Xycuk;in@bPT&d%)>@%3@nuzLs$$r?5g zHL%!NDZ~dz#66@wX~K6o+dueai?k@J+P(T~PF=~JL`!&gwRu@iXQFZ8>_MkW?916# zy4@%fTVlUCTb8_?EMpUWDJG3AQXY;_rN5>=ak|v@NWX)0_biicZ?yv-t;mWg8s<=1 zu^VZmx6_DB@8;jpJwH*Cj&S;@i)Hf?F6-!361_)cuhOzPeFE3Sq&FpN|J_X)GS7R? zF3Gqa-(+t5aMV=kYdv2grGqe51R}*4N}lpZF3Sr>u404aD(nXyo)>P-C&mP;$7wPJ27?UZWl}4r&^5^9*5KeH4=>bwp z?B%Z3DVjrxeUI@JyN%6tVO5goTP15eqFM$DowY1Vv4H)$ujpHA*)=>9tr+oYoc-h% zb@T~@Su2Kmt9O?ls~v*Ac)fAa>Wv-8s+k4D z44A=4cs5c2BOd=JiS&ny*ACtvPj~IlfMkDqme? zhW01P1C5_m^A1$i(#I7pS&ASalLZXENkx!h5J)%?M?{dlT*Vq(pJ~{ktmbG-460YtcrY(19EIhU@##&DNrSN*&_g!EI;wb*zg$MyIGsolF|ZTOa$YlhPv}1Iqlvhf zkkI>addA5(^)HdLp{i$$0~6w9a-vk2^fGBa!uO;w2Hdot6vWeihSJBHCz8F$_pMz} z;zPOR%;@AN$WtR_QbY-nU(OftMOIqGm!vAL#3Od*dQMs0%STt78Hp%?ZMUi;gV=ZglL~ z6hVVes^nJ=nj71s*+qTdPbD8k_F=n=i#`as`m-qJ@xdh9S&#op7U(-wi%!`And(~u zBTMtHJTGlFSxHYP#Pw@VHQo{bdSZ@dl>KV4UgE)gH1@Z4}{@SJ%V;pw)T ziHVZJf1DYuHTV&+w}qO&bG)W7UJp_%iJ#>9B!rzS($cZ*uC@mvZmZ@)U2WCxW2N`8 z?A5aLrR=2K$E&Pc*qPQ=o0U$JMETCI#4fk8#VYnw&@7&Nd*>w6b%`BCx_BnBRrqL( zXVHKrdaDxIp>o-rFala}(Mz&FF)z74p{MmYgNcaytnN>2JmCHWF|M|_`x8QdW`ANW zPa>qf2TZ^Cm=OG*7e{W&Z^o17*J@f(@23w?BV_qDo!X;U`pRvI?f9#B2b9k- z_m@|eno?jXt!@|pi8eP;+^*Ey+bd?FDw4%kG&N|$X2tz#rs#eTlT6!$4r3)*!i#J| z6unW|%hbp)r!_xdp2dh&_lhLk8@MJRc>`FgFsflG3q&6kRgbl80d6F@a|&5cbH&ho zJ;t=F2L&S6v*~<2n%?yjF|J`%yB>9o4d&%ii`j)T_A&7XOWj|-p_MJIU!Y-wfZ^`% z1QHvnMxKm4Ef^JjZNuy%*;Gz=Y8J`xxb`&eUqg#ac&=7-KU5`6M)b$VN?3M2W~p%# zBbm1#=W&B3>WH49jyNVf;y+Sbv$Kz-R#!DBa1W21a0hYjI_zN2F^%hw*MtEnG+qzb z6B1j)`_kw4HXhsIrwR$Wgb83Wp7@apiGPWEV9 ziukgJ!rZ8QpPQ@mWP|+|j*8E9(&azH>LZud{Gjc4juijCv&3OwcDFTYRMC87faSf1 zc(d)O0=FDTpGzo`7ZaYRdBuYe-J0Pm!Ak*uw}qk?53WFGo{Q zJVPd82VYQJVvi{hNql{Pd&{8b%x*>`f2H!7(#T^nJmM@s`{E}sRa`sq7+@6DzY~+I zj;k+4rf%M5=s`UO!)jB?z#C?MPnQz#5ewK60Zss#D$JA4S1&M7Vawes2KuAbB|-U1 zi=Bt|v~<#Ah0^NnGNz@p9Gj>-PS`?$mezVq6*9%0Dj-B$Fz=a2{{+P|#mQ03D&_dY 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 Nn;SNhk^jek{|n{!#ZUkM diff --git a/wntr/epanet/Windows/epanetmsx.dll b/wntr/epanet/Windows/epanetmsx.dll index 939b31f36c538fe773f3e173bef088ff46b442f0..ae094360c6fa4b062d41feba458fce4d9269eaf3 100644 GIT binary patch literal 345600 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 z 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%0DHpxSgBL4# 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[V+ zWbVSR^xcxO?~%!Ce5^HIg6yY>Bg!6xCn9&I$+n!^8@V!F++YhmD<7o<>7(DmCMMVX zPEF$XTd6?#)TH4;yhi)c4n!(b=!t5z>KM<@SR;_mJ=B?f8rDJ4byRvDY+>IsmRs4< zv%Q*c<56Qi~+av(ft9 zs^!0elP;Gz7>;YG6_alv!6yisz30)cn4HH+f%RZ}i9Zhu?=-nG(2k{hJsGc}TCol5 z;l{j&Xs>SAQ$%k#u4I;7u1a&ecnj|FmTu7Q{k5c%RzZ`eXWV`c#rH^Y9Ga!5zxp++ z_TfT>R(l(fq&i+C(}e2GMUr3K`8f@d(RmARPm!SIzX)d2dC1WwBP}C=~4rDEbcC7vdrX2a-#2wux7H&MN*7$XV6VU{dcMh4qV2EzdH z6G9H|GgEWmya73z4RZi`VlVpUw>}D1xVhurzSiz79kH!1G+o#!*K^AuN!ikM%LUF; z<+|oceuJw(Kk?XF2go1`h*WjiVL;BXfas)tNZ3SVGAld7QPu-w3rUsL{skDx948zGWEVt}*32UH z@gyLUyIbCAjxW?AwCCYPZqV3?8d zJXJx?8xyJ(!#yPB!a2>pSc^aHRe;w1#cyQYO)PAGyUOdF!4KT3q^@g}$aCqcztM4+ z6j(n3bvHHWk*Dj3V<7@s2H!`zLKV-7)HGlezH<>~yxx5eKVoGy? zV;KQN`gBH;H*c0NGB$fDDmo`b#zwIX4kjXl@J^=YKd@oTE3@dA#B7c3x)REB0n8-8 z9S>5-b08!Q_s|;MoMqh?UgWumdX<-F_6su8`NgfmkIa~AjA+4^L@XhN#%>0FcA96o z>}@k^tm1V*Dx!TMn~pv9Dm-k&WL#WT@J3a^Dt~xP9`21WdempsWZ8rl7J{1Kb4u#H z+;}kVfXt3=9|{Jwu)npJV^viJdt%LAV`oGZIvMft<5lnv0xmnVua^HNIII_G=RX7a zmpyra9JI+s4k6dp^9(R2t1Gsu=pjT;Tczdy-IRI*I6PObT{5k&{0x|OhByQI2dJG? zZwfDJn&jw?Hf^<8Q@aU;B$)wab{U{fiu&;mAfszvK?257KMdmfo#)UqZ>oj?M6PXN7ou3B#N%@#FthMzO53| zyN~9MJvsZXnTEt(>A8IB*D$<>lv zy;cTI8e0u|#stwIW&5t>9lM`xePfe|9anTccPiq`6uAsvCicJ|0ra^h=;)tF(yK@3 z31TZ{vF|JWv}TOQ*wM3}Lxsc43cq6(k`A7hrfQRWNw-C>7a$SrJ_Vl!Hv?@;3PKb( zqkOQUC3qF6MIW(?=Z_ z@XA8jZM+4CtG7)&49B~BxOL9k? z>K++E`bY@8&$WtZXlZYij?ks@UwC3`P|{G;TC=^Sr?`pJ7XAZ4qv+|4%-jdWHBa&jE}AI&^uq`f&Dmuti9uWqJIlmR2O@nz*w^buqvN5OLagi zN%8jok}%j#R@efB_74+4N%W6$%c5M`@uI6V*G=WMKMs|ZT1aS(vJt%eQE8N=zuYPi z!6&~rKF1#cpJ!x6YdFqL!l%E9&%0tt6(C2zXR3+M{1>Ix(%e7e?OuD2NBjw;OJ1Dh zEgk)P;Y^Mz4J5(Ia;3?$G7`8>q)}WjvHR$e5xcH8mpd#1p6O{m59=5Xm}gWL!!c_WIm~&cP&L1UiaYNR zw6aEZ$$rCwGk6I*M(*Z^wRpcK98GN^`pBajz5kPnieWoXTA?vEmMe97RW7i0VQsbnUGca9UEO%VYSxyKP1tl)@VGXhr z>hb-k??}A7>yZc4y)~SX>?Tvp>5iwwoK7n^HRkL`&@i*a!LeSF{UGz=Gt{k2#Z*_V z1h6>_rW3<=4zxQF4$nJW{P20Ll6kS%Og6x9BQDy`#%6z_<-1k`9FvIRYdHES=qIf?`<&{qd2F=ocnOwIEw+s*)#@K1IOek8i9X|1k(={5+T75rh@<(sI_gM8hz4gWe52JR z+(JCCv{ zBWJr_xQ5gYnR#N4m&nl}E{35maj-V4dc41Y>AW-aWm=F6CO1XTv)~420P_)nS(ReJ z^qVjpk;|{{92axUC$aM!t+P+e zQAMKhnM{oHDI5vi!f+0C_q|gj#D@^rnHQuV<-X!ZCHpE+;u&79iAMdJ*>4~p8u3`} z9OPA7)X{)+wwW<{I|*>ZX>@qZ`Sz7PDKTfedV?uq&KC(X^BbReLI-Eeb-^*!;xm-Q zF$b>TT}Zr#FHEUP9}a2SPj8605w?+OQP>DqyLqV~f;f?JBI4v3_O4});Z+?nn`TZj ziQNFk+eH`Z#x4v5b7Y}D9gNFAmqGKcI*8&8Uo)8Jah|7mp5=Lt$HkM+!`CIRX^J_U zK`~U;mvRn|@siQ5{ff&^_cDG$-81HKAm*ZF9vYMybKXKmqy4&yWpe+eTu~a%%A-_h z|BQKapmiqUCEQB@!75ZvDSssi0&59-za$J#B#a|rizEPxgn@~K5hN^^1cWFF`!APD z1yl|R&q@M=goJlg0&}?;tN0GH8cO#j^elcBZlyBdu?Gsa;2}!2V zo~LAE`l82U&gyCL?s60TY|$2JtYRjQsN@&*+tlZ8Khu;gqa^5UeNZm3||yi0RG z!i`;9$Twk71K}FHdqQjGTqZNPTc)#%JX4yQxDO$^aXfrguoFm)O@z!zZ4oI(*7Ja1 z*u`2rD*+Re5AyCp&5u6$lJK8nax3|jibqHARZE5mOU1L^7e0MBZzmwsuDtqX^O0Xs z*Pi7!=6vWGhJh&{laZhj~YwGGG z+W<}^i|yv`M?c^g+;|wl?khoF{f{;B0(T+tyEoaD$=d3LM>Fex-qDJdmCc4 zNRrWKfdiVsEf5V;!`v%GhTKeP;idJLNT3~BI>do|bY1Cpf`h~z93LYzKFNcN((lNH z*H-l^7VhD1%gSu6eXxyBl#19&+twtt7OYC^ZivnMm6*xsy6}i6TTqfd)atJm@n)1g z`(lc%?p!9`3*=oWueaiVF6cJbjbS+MEfdYVrf_Mgbb@4n|EHL(JWstBw5Tj|ONVZ_o`)DcMK}itJttHL7vGa8864 zUPJjvnL3u8bK+tPTJa+_X$9eom~)sAie8W`eAiFCDHOAXHX~Lv%hdHED7B#|cHBa{ zD)7Vz9n943xr~ab@z=pvtlVh)>!%n3^|TGKcPu7Kl8+WY4Jo`$mhnE(sCLPP2{gmjA6iKVz8c)_+{^^L` zPZkzg=J+ujepyU~Gt){x(iZ+)^=8?U)hS{h(PW8T3~6G{){Dr*I!^4+%QS>IxAYT zEGH}mh1QIiH!Y)d^Z?N(8_hmiL(e$4&#rTXr%5z3UO(sbW#_j&O%F&zBf0O(s}}A0 zF5X{`=(f{Dw`-QGY!}{5emdO~sf%k$C0+wf2EF0F=dgcPH^W|CHz-D%VAQV`9Z5Gh zc@G~=XWBK{Y)U=wWj0<+&UjMPLo9H*>BgAzsf&A3V$Mg@n_|BE33@_b&XA87JI?xt z2!g$(lR(3EOOZ1rxL2FF(_^gB4R(VmEehO+F0#*G zBa;UT92a?AA$!y-)vChzIJO@3p`OOPI+%zfV4N^&j_$i#=xD|vPZVE`&Ov%~R53=e zao!Bu{TI*EJkRsA@U-*n;1S*Y6P_=5e$Ml)Mw{(BJaLr~O))=u-UwM6EMF!X9%}}ks@61TEUvd$o;E`2jmi3l*_9v9#~PoB`_FoS2pW6jBy3Cw8b7iBHR*NC2J^u zBtMCt9NM{~ZXb*N6@87(UTs`6u^gvUk=l8y zIMEl>*tV=F9ui!=QdG#!TB&ddUbY@FIp9>WcoOwBbBhTH!4H_IzQmYVRs9Ng#{1J= ziQCJlAt$wdi&p<6K)lBKx(_T{L*4!%+KOziv5MN)sn|9w5X54DX!Dk?3(gg(&K$IS zrD&>5&Py0`(Hg?CL<&~3x&Ih3aQLzh;L=vFVV^IGWwESGBBSObz;78V{B_s2M1Lw) zt0qw=T%yyP7w6`$j`fi@lFcYdR+MkLU&$}YmWY!+OZHz@A0>5c`3p$!ZBo27ZU-Mw zjf`GQoXP)wW4oVQJ^Te*&3EWg9y?E4;T;$=+J;|+6~@?%HD=5ZkI{lHh8|Gn7}F5b zQo1U5{MfoN18u=Rp1SYb0@avgI+r1&l(j|lmtWKU(R=2_Vr83OMNNz^z$alXIzr>;X~&!WzzYK_QdFwIJTRxGaS?!G@N zGUfgrS%KYf;Z0m!81vMX*aCC4#c4(B>YD@ENCPZ_-XS6m5C&a-uEUC(0jI!!1Gsob zjDMH`-`T+cG|hl*Y78p5pvGWxXy z>|x256swHJgR{y}Ij{k)6+|1ZMK-EI)Nw!gX~db&Sd9oo5ofzt$rQzAE)v*U{f|^n z9s~ZwcAR}CtF5xTJ(vYd1S=9z9WTt_1_Zc}_1%%jSj2GSf*1=WBa# z{xgNa`ERJF7S8{U*!A!f+Jj~Pu7uv~x54DM1rl)Q#ZHfjt53jOpVXLt#S4ku;{CV%YQ=S%_x`Q(cj}V zMaNYjAT)lc7mejU6O%c{Dg?8hcwUIM%m*Q-tb?X4ca&n2&f1O&EN{1E35|X)bj+pz zFIf-COPX2wMpb$trHwWWoBd2`M8TrzOxUKhO{;1NJC>pkcL-{W1|h}X;(71^E}X;k znufQ=B%Zr@p5ysFlJHs{(dR;CyP5yf4prn3Ho2cImJZw?0^hAvx#)&F6Z0KP^k}GV zG&4Dg5DgsjeD|IB{KR|*WVOn&!@m1fI!D@boOo&qwb-H^h8?EG1l`#Nq!Dp<( z9m%v$9BKZ}Ow?B)KERHdYTYnqB`xev3yEua-|i3Rq{lT?#+K4lg?|oHRbRS-$*dX& zsBQkV?PF0@`=hG*zJ{uri+EI%6w0vUjdxNw29=&KqrXFL7cW{Tsw+z1YWW_LXs=pa zdqu-VdF@19o}_TtTvf0ca9E(s1JCKPh#Gt$s9x+_t~MLLVBhR#?lN zp~5^qV}tPHk@%+u>!e=&hOc0oFKxRlb>JVZe*M?%uwRg0I;?nD@C67t9wcO}6tJ>4 zb!#uSe}|riuSqqU7tZd(yS2tg6fz0vYUpiNPidhulo~bq7tk`%XHVlP0N~yz=#W$`$>&CFDe%@Sc2t1hPyZ)2NN=z(`UJaWcYU!6HKp!dnnqn7C=ZrG1`jN>5S-UL!ss9=bl8i9Za2@Uew&-6H_l1`8vsCA(xglLV1Z2l|y83-CZz{jho47NI%Z%TX1=NQo^)P-^8U7bJez`6% z`q^YFUTN>iSjA=GxdJ<_So9p3Yk_w^v~j9quRomECI(bJ^bu~jlhvxkY?bU}xx~gNU4|iPD%NJ%nU$V28-rO;x*5gz z)5nA*;TytT5^gnj0OZEQ@QD47vqd*zC-LDC{~$bb5jGBY@o@YN_>QAWY*mRb6OK-r z!zs)Ws|f1GR;@v7u_Ys(=Qa2POelS!Zx8duhVU#VyGb}pZ3*yF&PQ{b1G!K|`a?HZ4a;X~#8MsH z-RTgQs_z4Y?CS!K=oj%?)!RqvjZK#?&!NtS4+9i*q-?`H9KO+>!TDoH)6d~lF`b$t z#2h$sgR<#B)2Mdc#S;3@{y;F@rLIUiKxTR7s-D0e{3|l`j99PnjvBIRuoi7GM{YDY zSS-3_2O+E{6pO399oK^hD~rxY0KovBt@`h&ygB?9eJH+EYDmM_f~jn-34?o$&y<>UaDZ>|5d`d?7y*w=u!SPO2Hf#n#W z=iH9$DG_8CFGE=Fnd7BgnUm%tL*wQow)GO$wmND&%J{!2F=cBMryx>iUiK2bta88$*V9V53}e(Bnbejqx3jr1W#?rD7M&6B|wXKL=( zjV@2<3r63yLSEDR@X6Q6%xA%FY#XjM+@|8kEEe^hzD%vHL^bxYHmrzDIjHF0BV6jG zc}eo6%19~NvItepp4}s0x;R^d4<^U3@rZWJ8%VV>QW?Ajzmu+2TOEw%@Q8DN&wJQ0 zRHDr>9Ud`=m+*)olF~DbkK;8w!lsh?5RQh?&`L%ekb*Ldo4~4ML>I4G!&8LSQ2wss zr}$7lm3_3Hp*(~)YbZZcDnP#GP@c%(P4L^H20^F5qs2n?4l4ay0@oqs1j zlDSy?NW(X_=|sIuls6n`D`YA)O(>3~k_&$YH_6YK$?3yMzE7+OB0V}55Q=N;V(+$8 zb?ft)g`u+JA#R$S+;nM;>t%vAM&}?l*{EQLg0?+Nd>fCXv41cL9IVX=_{uHD za+9CbP6ZYXL+Saj)HLhb7k9Bk!ot{;A+`83ou?Q47=8 zW-dzTv*Q79?AT}x+)2{29$iVNnQlA&NZBQSKya^+r6?ob!*wX-EqpGC)!WAC=~!`1 zQFopabq^xrnDx{ z?o_KNOix{=ex&vbl^geulVITLE-Nu)ZZ7Du&6yo^Te?yO?o4bo#-Kkb3|V+-Ps1!6T#umt`; zz$V^S6HoMpOf}h{KHLX2WvxG5)?TyZpsDPKsVmjh4I|jMibG`s(B$o+pOaRsb}4a} z4dAH6?j%--vJ(Ui4#bFvh<40ilVZEcMsCGMS0c9KY;?Nfpw_S6pDK#ams^ZaXywZP zGU>*r+t-Yin()+xDT)WzW}6F<2Wf@JxHY453+9Bo$j#Wdj0tM|D`P?(J#j>P!el=% zm2~p;Y@Ob5?1L>>sq6@Boq}tcg{wQ}>^{rvW2INpBW|5z*yb!;wTUXNUM)6zb#q5M z_#I`{t2SN5ZuKl8&acD+t6uC|3Hc!M=4+sQwV*8fJS)I?;%`m*g0o%W97s3y6pyf< z8&>@3MhoBS$ti>Je|9%)sl~$Ph)BG7J*za%yytYlD7MYuEz>ZhI7E0whDV&i5_cHD zU)-wmXY@{ckNs3Rjb9&E|CYVAQYd~Bm z{{a0pRQACyabc~w1%cpHE!`A-Yr54^Ep!1{lr*?X`pVp`*6PO)nYQmWY)&=6wDP zX+*oMz%nA`*K{m1h48Ziphw9U+=E?wb>bzaLHxVe=PiV;u=u?{5haS|#1t=o1aff65>`Jr-`z%{ z$Jkp@T%y&tkODLNj7>*d0LAsG1V4*B_*#38(@l1!zTnb^*qj+!y{tDvAE#*b&!J1G zfOv?jfOyT}{1dz$=`lc7e36TaW6o1)mu^(xp4H|pF0RGJxoq;f6q}OKogP^5Qx1)+ z|c~KO{%OBhN?ofS4c)f~oXD&!dfN7wbN2{|OK{B~Z@6a1D05!#M`K1bA7-4V_~A(S{n)HaYy2xaqDR0_{Eh`bIxod#;dgNYzgh~#@ly@u?X@0-k^e}e_38~)Uk#1- z)i|?E?OPqUQAlWkL0J0A2cptfroD=xi@TS7;IWL~Rl(`>*Aei0W3`1}`VsK!+k>C< z)ljRi{$Q2?Ke?GMj$cn-EhCn`s>b+`BySS^)ql9zU!~NjS64}Yu`fiMl?@lZD9z18 zyP~g#rqrzKxEW|N<5~OPs1k=cGP;npAN~vg$l6z@#%1j}O4gQ1A6v3^c#@1g%KSe# zG5?De=~7A$b3nc_bzyVnV5jiaR#4sm84!DF6{R)2q9ktC&4LCB415_HCKzFYQvMk$ zNw?eyw7dVpOQ`G=X-n-q+(g}!!s^NCFJ|3AJ~7}Pas80zrZLr9)J{~prH}`{uIV7L zpM5sx&W?|MN84=i3N;XDSh82XAxp#^lfB``^SB*DE}4yaf$v)=zFUv@-@~k zxV4CR2r;1;uSvF^8pV5pJ4Df<(i}Ia|8jOT%`rv(ukHMy$M9vSGve1XFEc(QTKP6! zwmOmYCzUizC8arX`4wd?DZ@u9L#CBME{{ude7+){?T~fKhh%O-%wiU`RyT$JA7$?X z-(-aMy9sL)bq3&_>wCW_!~gVnW)O7WKe_sk?siu!-wAD<7+Gc#w-oS8Xu z=FH5QGqR>B(>O)`utLP1vXgxQCkQnRVlmQXcWZ2Y@-|H!wd1yoT$uTPxlaT4NsfV^ zrfvl*etkD%x4d#*=SUEvV| z+1#CTjxbt1OA&RQ=3=={Q>d@g{3{8Ak;pYbafg7bG(J4U@VpBbN4QhNJ1KIlCXoBq zDrqENNlWfAZqz)g)_vmoOPM?#ce1{r_1|d;A??TcRqA~aWuxS~7MX!5iPNaPT-G3M zp{mct$iQK;TclRC0V{jzP<%_YRgYE^OklONt(;5Z|EkUJX$%iu%WVbmbAcb3&v8R> zVb|(kc;2ZV=C_)xU5sb$D#+{H1HrnAg^tz^JO^sGYc;=2*05}7b0bcAo-M%C#?++7 zm5i9I)_uATO1=#M%bXXaPc~L}Nw`)@_rzS^Um`z_@&5q5>sg758rKLE^MoAt;f)P( zf8aIH)$p#Q5quHBTSCV5I^+4kCR{Uh#y%vfT)P2hV#`yAlwp^<*|A+8b4;VQ0V}U-K%d))-Tn}{ zjg?8RqF>iF2tqpO0&-E0kZgpl7W|+v6Rr}STA)+0GggLCJP*Lr0JcExCIt#2K(hc< zmvTmX2CXOFTp|~8wAGOerN46yU^)IuiZG5lYTV2U3p4xYjr#@qdB=VHG#t!nIFu7L zMv*qKKI*WR0nU!+gvON#>00%f9v`gVBcF_pcwZr_bni6jUUU9^gjl)zOTBjq>Lqs( zwjAg3?Td}Il{!x2ONQ2Lv%=v}-@?wagQdiOY+SYwd?x!Vz}qnptZGZRoEgD*!j(-h zP{l3uug&@ErM={8+^c*D^S;QhWvp41ym_mn48zVVZUHH#h)X!un*%q-!w?p#GNJ(D z%iP9Pbk*}oj!d|orv&b+lEz|WZ*3#p&E9%rIFMc+b;1WAHWnyQg7T6y%EWUWC?|qa zRyM_?)~-`>sM#1rK(b=|zxFFWJ%vqn<<+AHi8SE^N5WU(5N2+J)wY} z%K$p>$3Sxdq6{Y~f@+##cwNYiBq@bVNJ_KM@$-{7g6;H%laKk228s3k_baR-csImq z4^?gSTOYIaGotFY7!Ou`7Ov)^-HcyX#HQMVFz@Gc|Z*)j7PYeO%v z)ZNoH(GqF-AyIGbD%qY~k42htcn|Ox+XIi3tQ)vyV@Y^g1IIdD#jd zYj_m0@oaCL!?L^wf{A*3#@)M&o7KK{b@{rotc_JdSsO9I@67Ssysiw01GqptG1(eK z))CxIcLr^c16c})y|#QVKt}3|DoUDbo>MesLzAj6z_#D(%(guM+T=MHKx#ia{Elkf zZJxvCVhp9_GN^ekH{Nixc)7jYY7WJEJjWx){|R~;rGdB1ypxM5c>5S@4|>+!WrRGN zW=;-z-juXmu<)*V?^vC7|q;IJc7eBc_F%t7rUfm>%TCs^XKfPW%w(Jfw*ec$pMKA zsHn0}l5oz00_Qxa;E1I8CkG@hprV9}G`_gP7gumZDmaM?sHn0pQ*hGbR9L|gso*3o z&{k2h&0H`_rbo}_xfdZewn|Sfk#U+LMwr9z6z<4dBEwl{*DOP>+O0|q;D!koXAhwM z_*pe$05F7I8b;Xv5TlJR*p&|O+P1k^c3kBub!<2f8GS5l%I1z7oZewv2{a02piNrt zi1`uKoYW$OZkN=7$<)2+6o#23bBpc{R{_bS>`XdmloV%KoD|15XknyK?@8jwuq+-d z*;BJrs{Bh}^0o=`-5MrUV%|3DD%Cp>@xDir&0MemDouCKhD$}+RnkIcS0yd}%100; zPDzUjhN4J}6Dm9nW`uj4SwA5)Dy(KW&Dt8`s(T4e3x^k`=Tngth>u{T-j0LGY-B|N zkEc#-F~_jV;3We@2hs5J#O>yoH_dz{KhgjaED{K0Nh(v3h!g0keLPgPF63!6m%apD zuskFLOX`IL&GO;9b?+dlw~vU~7zQ8bs*XzV8o6zm8t*il-wqEv|jpv|f?l}}piOm#@_yF1_2(xtdEI=V? zPtCt0-q9%Qxi$UihEmtAzhgvP9Ego#c=9NL-p|L6_lXD~{R+It^$%cbTa&$}4kbj! z&z1Ve@(?zcBW#NIF@A$( zQ_b-$ME_m*5q4DpxJfam3T&6aK}nI1c!j5(_YQd0QKZk4x+@Sp9df6dC?(uQ?l8fO zbtZ*7az})F!6qf#^X7@%p{<6>pmEAm>=aRdMA)3z5e$v-8wmyEN%o;qyh>yE^YD5q z?Mv~^S+iP3#2HAmB_!J5$TFLNGY|yZcQP72lC|PAS#?bpeQdVq!RmyCJJXp8P1)7T zljllREu%{fQ@yqqTuuxcag*@|hnYF7y+cuN6{;pHu)U8nNk_fMo>D(AkWOgx6G)Ur z-nIM?+VUiZU1j%4w>ef36~B;gmhM2TCh3Sd*JwiP!WHNovJ?9f$V|84E#+tIMsEK6 zk+MMahUjM2o02uEY-c6w9@3hPCrJ`{6e?*X(y>tRMZNnaL$k4*A2E_4<^ev*{1=_D zmY;*awUPg6zMLm2kga?Ixm1_gqC-3M&pQ3HS^o^tAQk%OQvEYo|Fi?bdqKQ6B)uyK zRJ=Fj8sU~2usS&A;v;H2NQLF3GU=RdDz~G>3_1?6xEgpnB0?*@pTAm`-K*qoFn)y! zR8DjL^=b-iS$#}Zurw6C+s=Oq4VLlCQvr7$x#Gof9GI z;`nJVr-~_w-_AY@uC{*3D)@euRuBgpjE1;YE?nf2?MoEWSHGe_|6p$xd|&MciMg~+ z>3EK>iAio!oGk5tAH>t;$FYk}PPn=fhj-XjxW<+)r#&~2!SwG_IEE0*#CzZw#rcgF z%a7x2)El!m+YJncI*ICy>Q1~(edCpm_?7A#hX&M^q+3*QzIyV2)W1rQM=IRN21o2d z3E*L)rjVpFRgz(+sgP`rLVjD%ApT+<-v%XQGNuhw=|($Y%W>n$sdheWFPv1jNm{9DmM1N!pQ0 zI>?Qg_NOUgwJM?1_>4gK8aa>X*x%*0*fHSQK?~&<)to4e_m5=${2~(HP9+xV#K%&J zg)-+ijP@9hN(n1rD|koxrn;Y;gcPlENc*^MJV~T0-p`Ae5ahIBiIiXVTDf@`f?!mC&KQDqi;*>7@0e#$rG_Oe`vII*bq(=FJA0 zrF-~nl*Z)xaR?sHf_AaJ`(OnxBeU3djUsdFhiYY9>fK4Kx%d+D%SDjAP%Xyf2l-vI zoIlD<6TcnjkH+Vep`5}5s&4CI3sqHjv12!8LJwQEQ~l8a(b+h%a(oO}z$!S5slJ`y zehEfxhm-DP9!kPrB*62Uq@<`@oY*^F0C0p=@Od)d;}VS8KKFQg3!zKqz&WjVQHlFW z&^{=zMVV?DT}Wn8kALl8(BjZh>oaVEohlNcq=SAWT-0_d{vCw^%QZ~s(m*xuSw=k; znc6Xpr>&OjkDKtrcA}b$PFH}*7Gn8*5R#Q66@KxmdM>07e+*oDk5uZ1=o&-}iQRa! z48*iCW$C#^R!obFmrD#L=1*cCC4N*0`X(z!tI0hMW$%)D{}f}H!{t0$XR&U3D}HDQ zvT{3H--8k5`aq~0_3b|)tAInNoz>V_l(9U|K^OX8>`Be}f1}_E>neO!?5tr=CAp6l zNN&E1>0zop6Ag7ky0aOXXo%Ny=qNnMYq}-a%GH5``L_F_ywmZgEpG*WQDI%keY~yl zi-gp@n#S{#8EV4yphFsq8y@Vp90)}5)i>L&H*2hJ%uyUVpyfb_Jj^Bj1kj&GqcthJ zlN-^O|8}4FXXsJ1kXKWunhAYVP9xmdw4fHsK}8vY1_lVMDWW@NH+8hd<2EgFiKaRL+Gl^QeG9c zj=RnzT5l$k4|P+ud;wIkYd^4zC(}8bbW;CR(*5bAXLOR>yHL4irjwTGq!UQueHP*Y zNS0NjlSF^Plaq0II@1JFlHQ@BMnAIhsP!*MF1J1kPqO~QyG;bp$dicr2qMc-4xlVX zqyFA@%Q!09kDfmAbb2pIkKJCx?t{RzF^S40geJfHyDYXNR+FLj2}=4WAC#o`9$wdd z{WNju0$)8r75KKMLXg2r3)2PuQK!F_P9IrXA5K@R3bUsg0_{PlrFtUtO_~wpgTO~TCs~{P!k#uDyFg$z{{WhNi z^yfi7rH#1k{(&gq1WzHjXiV2Q?>#Ng#u-EH3M%j+pQ-{3@$k7F^P`asa7ApclhbPu zL+EP&)_%l0U;Lt-uIiI)Oj!__% z*SWGXsy-><+R;VA#(PqWXqafr*qsDXmka@UPJ^sXf;iDLUKEhrHv>#=prN@_{NjU3 ze9z8NSzL=V!DCe~1NjnPtZsLP-$p1_HSUJl^=9pzVI(M+!XZ$8~7Un~7wRANKL&2f82!0R_2& z=4|e}$`mgBv)`tgMA|z8q~=}lvS9ak?-Rr*jHu{;2Nd1!Fm3tt#k% z9N>>k)<1TQGayGViY-dg<=v{wdq{G}xa^wCy=H-_c?Udlk5rEIHx&6eSA12_!($XZ zNEbax7429Gn37LY8Arl(s!pA)q8)e3k52d@S5bVkPMDTX_)sTYs}shi6W-7X4X<`!hD_ZdOG1zo$!oKcs89dPbWO86aJV^n5Gk=I^n8h!f#-sb5N^=jV97w6Hg2T zJQGhWt3E?+`?0(kSr~5`Dw-*KJiS1{ba;wF0ZC2|k9&hs>>B}dR zZS!7^YMVDjx3?VsQa?!QWa@gI`npbCBR{%HpV0}=>V(_V2@mRo2|D4SWWq#hHHKot zTJ^~ozY|RaPpV>{`jQn3fdz7|A-j5+Lmo;Qbh6OBB}u?}x}1TkoDAJLbGK337lOyD z$uQ^NBjeOERy_)OQT7HV@T)m{jEL0%1NX~#uytp6bQhNEhrJE=xfvhb6!WdjRy2JM z6&YYPZ-eg^@ad7_WA_#-anL1P_o)mr5i}dGkW2odo2rLBlS+J<(v=5_b#l~u7g(a+ za{f+@dhaEJY(D-{ieo=X|Ah6=0{ydpMvW&WolU>)D`hW9 z>%*L3KayT+ONG^f`>ia&Z@fyWY8}qIcYq~lwAXdw8K6rhTIs~)I`M>b;vMP4h)(=6 zjrPiP;#8gZZaVS8bYf5^Zb~PfnojJa6aSe`{N~{fYE2R?$A?5HVyV^dfTP|DB)3H^ zkr*}qPVo4uXvB;mfLa8-YiH-kS5@Te5^3vz{6R&oAkykNE2EgNB_2zHJJPg700MU( zMZmSGcvUL?v?Z}>v&I}X#Qr(qx>6#sa{|(SwoZ|6=*Z!nB45#wLpw$OMMvJ#DN^QK3Ywk~SsmtuFGWZ743dn@r0a?J zj+&;3l8ZBrBbgDG5%F~c6i^8Sv9 z*j;Dx=xq2Jyfy3j3|F+CZQ+a1{8IC~V--cP|BgOa&#MI|IPp<)0!ouVr=8V8w|2`> z2_nCoC;JlXLb+T09@izr)V@^ey+~55J>gN>O%C!#ALr06wH1E1g82AUkmbaWH+mcJXfw*B3T zuzw;aRlJU*&nQB6SE>rS$55at3Il^za9LjxaH}1Ig#xbBPVnL^zT9(;I zSRqC8GsKRFhO$8S64`5aTaM-Y@-AGAAKsk^S%bC#Q*P~HoBl}^hcb0EfZalvVY(q0 zyLMu5M|?!=!g67_)PB*Lp$B1(GJkFho?Pqwx!Xe+NgNJ%zM9)D(D0FQxw&TIMLhym z-#OqO7PEB=Rk?~l?$6yTm$$5=7*GWx-{gb`Rj{uS``r|9Q_2;wJXOjvbIrY6k;5?m z!7@^E+X&ZV^XkuSlX4DKcs9*-Vt5mk7ohMW>n;++G22D_$i<@Bl)O*Xr8!XbIklvE zA(TXJnXzhNV=Y7?NLJuqgHZ@SxINeoX{urtm}Ghygw`8>c>#`3m1aQIn(qmRxcm z6;>;*YGP8~fsAi|#&=o9_mGV5j(Csv9tf!YFI4Phd{lRh|7{n$x4B|mhVU-SFhWgk z>~&U7WWUT}0gn1hov*$|J#?ryL+5?c0uzO-UJ($>3ePg;@dZy{wX~Ekv-k8BX7AY# z`_0~Ei}?>*d;m85j_5x?o|+5HTfZY?4HwO#fFQN8LJ{&s$mk-w>i6LbGzv=a1&wo6?c;u2}Nzec0E9iOKT-uXUw2;+` zURZk)b9DUcZsPdT+4t*026!87Q3GTsw=v`~X3AI8xRD>67T|iChg{61Z$Uo|wQ#=l z`{Lpv72Kfa+k~r#b4=`{vS)T%bBqLaw!rDolUQ;l=X%E=!D`i8kEyIoDq{IK7;HSM zB*<7VwS%PUAr)f3+S8E2HkM>$)VE*@Sy(VSvV{mRBuoDb8QB>ZEE&1Zl3 z{FEM5eeun`Kh+lxk*NBjtLlr^9!cV0^xVe4!+~2`)LS*!*)G-0bL12h0PlB8nAZL5 zWh|DnPT$Jq6y{S8&M*W9K(IV48Okc;+-s|L?I#fvvoMV5cYue+)zj?bj5`$4ac`2C z@6W2_{K_$bC~$ltDa0<$dKlD13?$-+JS-_Q-&O*uH8`sq=LjTWLs?UJQi**e!pwYG z(^}6X^bMqTWc*z^Bkz2_!Ev5E{+_Sjo1QI+?nWZU`Lm|UPm?72v!;Va=#taBS3#GC zAaPpAa$PEkJhFPDQ)>KCjbXaCwsK?Kr~!IpRmf=@SvAHf53b}bI$}=D!|e{&Wo}G%}g+eg~QPmUV+w@@`<~rl#P!G$gaqIcd!@rYS=>G%q82e&poo<;1O_6hcmPAPQ z4O7i4TjYa!@k8~PXN*UH3r1hdS_ITAEP9MZMEFd%JcEm+&^V(lrmLpjKAx}O;HMiT zo8`Bc1*7xr%gBrFpkCmfSHGMPDn#32+HFZL(;kvx0!R=GxA9}f*Z{|GTYb$*@rRHo zB0*j%z(ean@p(*D=gc|!D!yeV)bSj*AQC~ zwdF!&^)EzE30h@E!Dyf;Xte~RWo}Xbq5m+T4+2{5$;&B^LP+^LiDv!O`#PJ)`}7y?l88 z0wg1hw%JA71g#%l7bSAp8WOSWzgtRFFA&Ejoq3#o6$M=+>~?1h8#c9GOdtMU3aav- zR>)mDG<=r|$82?|39wW3I_J!;sG#f0aA(HDt8&C|>x$evI*)9KZ#RX00ZXb55_@UP zj^?Xa?EjA-jWPOfEbfv|l=F|O0vzW6+5p?N}1OnRxvtGnW>=;Y?@obz4d6YWQSb8W!4=K%-tjw$5uA* z3Wr80CQ2Ve=*mTkJP6H^#tOtRFq6vE`Uyk6RWvp3~^%Sx`m1d`RHqwS7J*E1_V>;l>lfWNzpi%`M%nbY~305Frb;*>1E;GAe zF1fwchD|r}yPrs^IV9F}2}Xx>X~k{Aq#aUHK^G-kn;0`aAHPq=lK3nYNzyewa0`5w zV>S6rH=1N9_E@nfsEF^GasJHNTW-3CweV-;O8#8EfJD#q4Su~Vfgfi)ZDwcT7^Y`F5TjxRQAYF+R1$I2 zl^9vzGE<&z6UG@)0=O6~vgg)X|^CRKUE#ajyL49+R>EIfNZ$#Kyn9R7@F| zbB0RjdlYKR5h`Sz4LtP@8V`` zI&IL{uesVJhm#yiFl4oQ37$ra81@v~=p)o!uwe>z!sTF*1*>YR_l`^%o+)J1SuI|EMbo#p# z!ZKe&$2bhK$F=cTd;cTm!oN@t%Me^X&w8I(v7VjjC9;o*DSf?|=Udo=Pio6(Zar$CnZ!mB)0}PsGL|?#yLc&(4E5#MZ}$yii?hrJh>7C z+S7L*3l26}@PkHF0x62;nHq8N0=x3UR1-qD(Vn!;^7MTMX#4@;MgvhbMhUD?aT(vr zHZoj1CE~RJVU{~;E`A!8!-Z*XO?K8zA*;AoB{+SrzRh2XTSeukUT*fA=ysa(Zv`^q zy+-HU7WQ6IRp8dWEdoc*8;rYwmz^lJl@`j89_vR`&>CZBM{P_Nhr$jQ2x{N7`WpNW z+z3PuY2n=elsX>23TbBLeHWMf{f@xkV@_y)fO2QzSx;Av1b0l#0{6=#`-A#gkFG=CTQ3 zjF+fb-df@8gpKFE46&QVUFKTK|6WwHhJPDEBb!{zc1`iKprtbEV}t)ux=C!0%`>aK1gF=6X^xK0IKcM(id5P!UfDxGuu=ulc>sIMnt%%=s0grk5TF_)C<*BXQH;%5S@H$@cjpQ}-wr>ce@_Bbrs3%_ zZws+OYr=q_b?e}uHM2~n>gAa;^Wi_7*74vN@>x7UOn+4i;@Nvkd(IQgZk)sa6W&H} z+hez4ygc2h%qauW*@dw=ymLCeNZx?%Jw49EBcd4H0GoQG?@E!!j+eTtZK}~Lln6e@ zu0*h(t!gQ!)YXeJ!e^?7VrjQCskk!oT*p1tY<6h7kX-u_{ceyVd^hM9(%Ozm0vNT4 zki44DkkzAWg*-0&ii``(aVl|$uF#3eeSzgF+NcDZY;d@JX1{ul@`?2i9+U$x=Y<52 zZ1rRtb0Tt&wJ;Koh48o?YW>_mQOl%3#_qQqzpjNtR*?gmK4L|^7gNQqfWFHmueW@j zjp0juu`9c3xAtj!lyPMDMZ#Gum`)5@!?0MtFvoJ7Ex6cRkJPh@S%-k$Sj&+^{{!a2 zgW$)GQJ-bX)G)%X3#AlR?3IV${(Vx~Rq4_)>O)fAzRW{uH>OM$_3foXl-xI0}Q{`iN<Tb+$}* zgYGe4FyL$KjqfZn5jK2q%11dCV> zUsxdUONe630kF0&l_oVK!kE65!bt3@g?p=0!_@l2$Om)syotOyoUe#|ryMZ7N4dGG z9{++bDzCPi?zc@h&rlUm{&l+*(@48yoUaJ~47H5d(p z?pTUg0pUpo606{OQjZi5O_ZIS&U`cu>W<^1)uwx&lrhsG%p`OzkoS5z3N#llk-B#b zmbASp#rIAZKY^^(auoPIWuT^MKGrnAVkurG)7uJwaXXPsH~3F8qPq2`1CZ0lISWN& zh|_XB^_w4&ys*NW;5OawNe3>tmSvIh8(_NOmB@N$he>l%Uk?`x)7)U!zJU$}s*YjN zY`Q--7d}s~hN{M6L2gWercoT0ROHq(&(^z9-5(&e?viZs8bfngps}(U*K2SN9bPrm zDfjlDqg`%sTnl}&cff0Uw-^;20oUbV48pddss{E>bB!xV3Oo`#+WyF}qv3q}FwdC$ zyy}VfoHf$&=Q~G6{rN0UjC?Zrn*G^%pa!EWoAAg;IKMEf`ut_XO389hZ^-~`z& zQkmXXEkq_VZ0B2NsM)Ro+0A0D>69^Y&|HJc>3Rqlru!@8M#o_Jb7F*R9WzZg-7#)U z>#qVFnQ%nKYRRb`FR@WTT|=SiQ;>2|Ek3BWSC8e13K>SsZhP0tAT9OYGF!@(iEcC}GH#UE=|xIY6bnU}BV~f* zN!dd6vit0~KQ(qUiadOjh9FUa^ihMcVXDT$hkiT{pgL#J(Hlu>SBkVISr?Brx30NbFMnu^`z)qC1 zeF>!qzemayrNu2ZvI2TX0?}dtxd0HYqq)xIvsLcM45iSCtkv^HG*X-U1|gkV)y-!p zCD#P8Suz)_RdT?1MHPBL-X->z-k4ih!yc#c#Vp~qCYd7s&gOc;_2+lcp(Q&@E0@rP zo69fCQ6{XdMCWs-hM0Zv^K7c4EO3S_Tbt|*k4?+JU=P>A`Qg@> z(`e&adT|0ScLTTL@u4FiM%6%lc*q1kj2X z=FX7Akl%(J0t6RXS9a2n3f41SU^!|x!*aTW-Z)`!PxUy+xD>p%@nV>rp2w_ZkI zr>i7t%S3xjH5Mphz6ezvQ|!9Z9AlisFheCnI>1nP+v~U2oL|iVuv{zo5xI>81a4o} z$cUCnd4S(K5S!FBRy)eGJM8mYoBh@vsgJZ3(_aq$!KI%+CdhtOJ8zbpAF!@;2BWro z%XK3-*-Q)N?g`~?_Iuu{Z36UWK(DY0+SNq-Uuy8ZCAKK2VZU;6b{;MVXaqn(u8G5j zjytlTEK)x$Si-HBt+FpbtgSc9nQe{{Wh~2#{1b9S;)yu@^96Uz9L!l_}m=8@0JJ*$ctnX$SradFj`hN0ofgLEF^st zOBiG>WeFGiN^K{Yu}c_k;9Hu+4?W|gytyh|(B5fL)lDKJL)uwX;XJAxu&iXZ%=P6b z;8&#TMb$eJ1e(Kv7iPd0OL5;OC4NP`kJaVj%XQds90lJiG{;e}NFqB?P^-Xn!=&~p zewB*T6ikqyreJ`gKwK(A!A#=Wzg&AE-t>B?c)Q|q*>#(ZR^A?pPAlT}6&o)sTE1dtLrU!eyljQ( z=G7nLU(m?VYYbwuqFAd<>1I5^CK4=x{`WS8GdruU+Lki+tq+KlPXPoy$aL^}VKwzFjKSIxL3c|i zK_~9a!tG9KX)bUvvP%cu06|j2!I+Ar_kkbLMOuADSI*Ma<0@x-g%k? zsIJ0mWmLiO;0@_2-1bvdXdzSSkE*aG-b+_G3u#-KzZbtGQpjq|Z12OA zjv%gQ?&t?9QQcK*BQk7q9y6{%!~iB)NbXHyo?$tzlag4vt~flB zg6QF%5f1#RlJJ4Gd)CNO*Cl|2X9ydNZkMJ-6m{nwa|ymY zu48x5T6(OYY~5u*S5P z5%qhbR3mbb?bK#+Z0eN>9dZ`a%m?Ju0i~v^Wpey3BS*AQ|1sHe%jZWkujQ~SaKi_< z+SCbJL%QJS%AEftye&OP-buK#>2Eyu72;qadIwj-(6__PS90M0-{kDnA}`-AEs~td z!SELUx8w1K!BlcYn15~&1=M^P@eaI{egwsOXt4U`Oo2bt@aa6HWH4a_b$PUpi0u^u zn=zgqR@=$j;-e9=mg5r2W}FCl92Ikc#IX{1Mmjma<_peXyFjsBdO^pIh~>zVoGg10 zg2shFDs^SFXexEoSY8AZU4*H+3oZ_cttTY37d`4Yp0S-ld^7Q^`)`xp zHm;Iln6#^S(@kAyHRt~k!XjQb>Di`xH+8PO$}a462klZ}t(WKK6fj8@EBSvnI{SxRf;A&xtTAm3LiBW=7^G5+P7o~d*3M$%28S)R9k&NzYZI! zLYify6+Tvm{u*B?0{8N0kE~&q?by($El2j6x5Xdgm`Q#^ezDp>_dWbK`~q>r0)5j! z1p{(u>w29}sYp@;arAeZu1#g$$wK|fmgAdWiIx(?nVZs5J~x-hV}hczPJtox9zOf| zXpAyBiqH4VOI6ABddh!g+8)^WJ$MIxny6okKF;#Hh0*X8_7Dlz(>sKX_R0;-8B%sV zi3!(li4Ad6Sk_hF3)jeM{YyUlypI8x-p(m!JEwBhaxkX%|5nlH>=TNlaZvji5*(9l zZ*@k#N#M$peF7b03skL3*dpLd+yXwzjWn|{)*#r#UDZo|tLGt7R#GVAVsH4IpcrtD zw3YU*aVDCgLu~-m1HgWwO>#G2v(;F8NG9$C^nqfCr8e&Y z4`#794WQKgJhIAmFPE|#sBU$EtoN#%rG0)ocSwLWhFGqA7EH8&WA2{SLRGM8Gghpg zP3Gc{2nj!z_KD0jIiH6fs_^;Yt;CBo#&H0+*6CJ@_KEnS*V;x^^;jtPoGjxb8WhA> zdHAC}Rzml6M2xfw_Q|^q(>tA?RgIAK(lw;}t-M9JimNUo>>!LgF&0km$>KK0PQu;l zi#FNJYkO4I{qKE#x@}>bA4yaSHx`_M};FnZ}spRiVXi zzo-vgqF2tA+J@pVhg{&{2Ey&zWDgfFhWJ=YxF!=)2BYF~Rh$;0EzAC- zy6>HFSStD+>l8K&B^eRiqW3=@p#U*H z7X76urMUV}Lx;)duV+vx*lYJB7f0!}Qfir$sqO3jM`y=hFr&rWl39q4?@?MW~;l0$6?!{){<ZXz0L z3W6m}Sx%))jw=(rzM=Kp&T-@$M?R8J`6u~v*guF8e8XRz1d5U;Vp=i)r^M$%2|gsm#H5J#u|!-kBMmFUZaj~q)+<&8s8oD~ zOXlvqYK9Zfjh15;<;C*0*d_ITNsSI;7kx@bY_-Hj<~Z3|8CF<5MW%}hx^3vSnRXoG zTmW>quRiL?)ZcBF$YP0Wk4~BL~u_XExBfeTNumw>swD8ogF%>k2jn2{hc zO~%Ev8e4~w5WM(XpxPDF2Jmi7+4zBLDGK+Nyg}T*4YJ-~% z`(R3=pl0K$kp7C-IOrDRRLCebd_>Z@JDFr^jQ9jnpykcKsVX?W~iNcy3a7){+GZrX=yy zDLjAGcs6tF06jfA(=U=*wQ}rqrJk!#6c5Re; z_1Aa~qHIXL+E~Rzjng$AkH)jOGoJ6!SK>u!JTZmm-y>ALmM8J7PuIlCQ zjOU+%XD^HJWc!pWJpWA=A>?L--~o-`1&ts#iNJ;Ly6b2KI%~Qh`K=&vV15-KGU58J zMJje}644n7Q9vWQMI%}*jD`9mh+bAq<~mmpjYuK-Gm#0`iy%rE4zfnPIiO*{qGD)I zot*VePD)45=CFTl5ln~JTM1ZQxNDEBYK-4pZw1j`QE|F~Xy8sc@#zr(Oi8mWjz`iu%tV9tl+ z?Ij}AI2u63LUER%7jtZrmU2a)BVoLgPWkbCjlPz&-zy4L^}H1N#6-p`ZOOtHP0c#s zk6oJ`jC`9DzBnijP)AJ+$c?K4S!k-}=$L=aHNJx^-MLT3-76pW$y(HHN1R5!IagiM z;|+(2m-LWpSGkSot|QcZOfQ@aD$CKp`b^Dk^k4r}|FuI=+2HD~J*rPq&~(*JEP5=* zZ-MUUs@>d7TSx>XGnU^V5BuXjrF-ZLYC&sfAZ96+5#sYS@%n-oH^#~!K<=l_)A!S8 zMr>UV$_2F(Q|cpE#wHdPF`o|bDdI>^Gvch*c?u#wk^Pk2x9#}|kAG0SmOWxRViS!0ft3pkxU@&)tA$}zXxep69V5rfEh zk-UMG(`H<9`z?2YSn=Gfb09e6Xkb&ekFFA92VOOtUYShM1fffieE z{J0u_CWS|9|H@D6iG-il;TPm5-zW$BB4ZSPNqR~rJm{n*BsB^5q3%cxbC?#-@Wu0S@sfzz#)8pk&k3 zW%$obzdrqij!$e%mtekPl^59FB|vh_UN+b7JdJU-4d)KPgv`-Httt5ld5C0(W2T;WSJt*xl6yv8{pEJoEyt*%Z^y3ihZeg8NUdNlS+&N zKZ3vAeoxo<1(^P}4uPHj-3Up=j3~Z8?GI}g>hEn5pC{jJ6WaLYN=y7ZagZxLHD~x8IRny?!;hGOU;C{uN(WsD!Pa4O zNf%^&Fgk%lwmF3r(K(1|?{9{)^oHrKwYIK|E?TsRcN&HPo$K)N_vm4NEH59zd=1A~ z-ZwPF&qQP@IN#C3zT6!R-x$_9Vsp3Ox^9SHuGqSsK7jIH(h@)avmX+zB|JlyUDHeE zfnkt9)@m5Z_+jr=j~i-L11-rhA_p(Y@v(tV z?g#col+xRN{MVla0?T!AKj?RT+6NALezz~t;?LcXyNNq>^H7xDtdJvt`h@Gedf|9S zBVomw8T#U7BysMHwKU{?{EiwKM?{Z+g$J19_g`-Lb1$44G;8<8Lp-MwjE#cT=0nW! z<8i?MIvy>@Z$xbnCoziOoXnHF`$b%-(c)8@&|&%v!Y>&G0Zgs=xVMI^XCN!S^)k_f zXh!_HLUY3S9a$1homTY``3!=6pK8Te9#`|k}%9Q+)~UX9ORpn<}I0t z;V;-r`5d02avKl!_z{DBQ#z=PiQjLrdFbrmuv-g7>Q_Xo_9E~K%4Im0!D)$1PTNPe zT*n^%ra0}5{|8RHjJ;9ewB}FXG~Q+BLCkY#nunPxaa@&fZCj&QZ4qHE{E+h0ej4o& zpm`^lGCNpJj^LDtR{I;YUF?qRB)h?_@YshX#Engu&$}A0fx|YyYD>;jjATB))t9?F z*O)^v((qlZU>V}ka@>YCoNzV0u6S&+=*uGhGI(r1NgX`45W0}QOQGo}cr4y3JQgZe z^6YK_Ny+>F3xAys!D;^LA^i1KYfhrcG6s`UYTR&{;<5@QUB3sx0+tOw>n>$Bs*H$w=4l#c^Nh zYQeFu)M)go?)iXbrh5hnC(%8>(96!JI3kX3#64uf_#<$ll}%vn&g!AhYeLDwj>wc& z&3G2s&jXdutYGa-b0_DGR}0B6&Ap&3S2+Itt1`yNBuHo4uyZX0ea@+TcIo*W*}M-@ zIV0+mZ7wJP4%uFX>a{wHZ^g{p@@OZ@8 zg19&n@lp`eaCTj%QdOt@9_SImRUz!=^~lvT%>AmQ#j2#20b;SWM|#e3xQ{RC4|^zS zb!kTH_0lChM*~oY&qz-gcmB8}h=~BgK3S^N0#)iMs?;)F>h-$R7g(xwYPhqcRDWiv z&#zMTE7PSuqDuW1t@tPF_t#IQC7x}PO-XMJ&Zu9xF6jVt zQom8Eqz8Vkq%u{~P*u`xx}=yc=>R%Vr#e+gNz*e++P_lODXdE}R7vOlTuHk>kvi>V z#x6B-bV+CHlB$m{>HS@l)Frc|J9SB?>yloDl7#Vk>Cd#@ZK|X@R7np5MC+~kMzvnI z<4d|*N_y<#jMnQ)NeSb6ve9@mC@6!$PgaOs3h`wc@f3~tAF@iz963dTcvvRl=Ux%S zcCuNHN3YQHPm?}hM5k_1P4QCkG?5VK)LOBKiQEx!x$0hteyw=AB+pwf@~K1JeWQ$L zy{}=Da0)D232~MttsA|&)Yl!S9_XUK5m=<-suOyP3$Q+fD zxc?&g$L?2aGz7P@LlNKB%uuY=UQ;IUSHy<=jUYxr94S@geve5HvkYb`7_P|W!7^>N ziuB?v`J*o`=XON<0CORn4{2{RpeD;c^hB}NK5$nqrSb6}%dr5hQ+X9K7s?K>oU>p| zA_X(@z30MR2zW6&GJZ?r`mIeV{SvZop|;8W?hw#p?VR=22dv?kePXLyxr>9Hae3h3 z2pdlXxEiR;E99$14t(;c_wdv)kU6f zix4-3PnmTrBM$M}es5&Js-ReGB0y?7ui=b_LMxSd9JVe=LMk~u$4`S4pB=Euf1>zV zs(5yS*Ns-?Z>)V-Ogcxgd+#jgPi5obB5BbG>WH*ZxtNtU%{p1^^T+ml7y(MSk@j`( zRj2orcu?ryWG;LbaQ2PCo~*Xfz zs#V0Bm0P4@x_SjrBgTJ~+ocnzCT9)f_DGu-NSkk$N*7S+pK9}Y%;gvlWK{ZIY4llV z^Y^2S>d)fxab;ucFERhZ&ZvLWU4^Zj-B;c$jCI{1%nLqZ#eOqn%3X8SGI!Zmp&4^{ z#GEcx9dN9&?HC}Z`eidGMZC}cf)vYjFZw~+2m#h#Mz)Z3my=zG?KDL{TCN-;l%W`1 zYI`nOn--qI`^Nlk=LvbSSd~l}1wvyD)G%IV4vTn)>XHgGOX3hPRl*xILgx}>HT-f< z5n)^6cThs zrEO4ur3Fc|s4-%|XwI)BMl>ba_F6+5b5FFY2%~k86$3COq;a-k6kBfg9=1}A?-#Lq zFc*H9#@oUeeN9STLi7G zYl6Jx;9ehp@dN2{4F9Kadv%JN9=Ma_P-$^{4VOxkUFtLLgze*>=eBYF~R9@&kc&3aZ#H){E@O5ouTWv~Bt-DiIz4lre{zct_~Xs6l>ypy3m7b98;=|LqTeG%8 zc^KI<3#&k5FU2LroJ=k3OIk)Am>7cfWyl^|_tt(ytpZHd-!lHgr%Dxbk1o7b*u6Cm z>klV(PbYKFu)A1CV;MbY7Uk9cLH5~X3ha2i5NS0)_ME3H=~W~$rHld06OX=0$y3-e zvD{Tx`?*hiE@;pLputPQp{hgWx!QhkZKuG3c(+mp z^)qkhO>1#vjlkegrS^ceM=B6xSjqSh_<&5Q8SgFO&Ut8dBNN+m*b)UX_dW zkXi{Lt!rc$RH|W6X>Xmbq(@`C=Ae=u+!TVnr!fMIfdB_e`?M+PAx(6iL`Z8fGE&mx zlvJFS9$h7<9#Hna&2FW-C49ET#qwTGN{@(lBPqP0PK%j~N3q$(D0zZWlD5xifL`q^ zFWEV9iO`)>UzRaddFO(vcFSRL!DU8r`K#NimujmHd4IjaC-R4Lb+NwK?HL2LJnNH^XIu|4CJHf8#q+Dwr^vHkaaY3iSAstw)801kV{ygQV)Pbx?(?Xh z%r-JiqEZdiOSm*G|8;XsD+*fiOn*|A(a26K72U(mlKATG|F2md%J?TW;P$~2C}TKK zfsYZCPIZ0ieNy20%Di6$tWXQ$Qfx}|^Sa}|K=y291K5u1U5cvritX6A~H{@ zZAA#aG6dhm&O2t>UP4f0VcB4Zhk(&v{M-c-F*Wss$jyc@VNZ@S(+Dt?UNqb<{Et+>^)Y1soA)Y82MM{b;}plnlVR@fwE7!@PAZMCV}|s!mO+&ql-W! zTon{64~+d1(9bUr&|%3KPHY_S5+l?c=I}(<`whK+7V+LJ6tRJZ2j?VFYG=&x5=97A zJrb^bsH*e+i3m-~0}B7QPYEfmMI1{r3=^&+LR!=at9;@Rx?K>fjW)HLD|;Gc+#}V` z5F6mc(xgniQoUd^WFfc8BrjlrjP2jIK}%AvWYXY_qy~~0+w8HH@(>u$V`?nlNM*s2 z3Ho~lIv@#JgY}-{O~6)TgTax=(616Mzb@zXpU6Cpq+2K<6)K=E0|1vj(8stMiJ$psQNY-jlDvw-1nY2eO;YqLsm+(=Bqb$~#mJyCteGA4ZS!>{u>E?24bI<@9~#c;n- z87W3JJ3|>UP?WZK>S*~?eePjpg(oUq--vgF1kD96y_HA|tmnQh1ZUX0rq((vN#qgP zp#Yonx054&OqbVA$XDq)9C*qKh)qZ8_NLOzX{ zM72gIBy@s3o$#bi_*y57N+&GV30{e@9OtAHX6l3jo#09*jMoXdI^lyPRla~#%0;^C z@`RQ|HB&23ky>Zs_YQCj=o7AAs*i6m)~n(EzhfYfynn8dog>-smz+dKqkQ=nRrd-_ z@D=HV{W@WYPVlA^*6D;2ozN$p@U%`iT_^k^ov=(NoS+lBr4#Pb3GM7RL)9_)(Oor3 zC;Xcj9QaO`4PMJ}0?Z}p*v6fs>gafdvx{U*fr>G9ov%RG43LESY8OW2$(JIIfD$B6 zs1$|d5HY-}csodx=)S(MwAAK5tJu4MQ?a-9m)L(2i-5j^*o12Z0T}6S#0ozbke{EC zB=Iu_0^&D6%0@zL&@v|`-*!Y-(7H&TsJ|p=!IF7D2+5~)=vU)-?eY#m&s7}y>_1}B zJ})6JZidl~IrY1eMBEc$Yxrq)%}dl_0C)vQx#oo{yGbxn-CM8MlKk)sg%W-^Nquzi z!`VP5T;DHORX9bmG9Jqqn;nMcwD>pdbjqBNu`o%F)8zO|*)I*;kGZ5TT8NcsY0vet zt?E((SC9_Ku&m)BY%Wq|BQ*}^nDY}(AK8`@oHq#0i@<3v_$yIpsgno8t~`*;h6sv%cA&W)4Vlwr zKdFiOIvzT$IqHit@5^p)w3#AF%(gZ!ES)Cc9 zN5T9r4Xo_5X<(yykZRyM-jdY~T+M6sIo0P2=F`AjGlAum zSFN<)x>mQ2dNw1$W3x#NEFbWe?lL&ohe$F;wwe9`c#c0Vkg5Qy_xnB z_PQBzJF(YALhU(1?I{`Tg}+Atqd9ancX!dblb@faKi^7yDmG4=Vya6v1M8!>f;r|} z#At2_M7su}T}q8l$kEXm9max`8lK^CSR~H<759UDE1gg({mH>^4`GRAkb(~go4iF8 z?H06PI9FKWBJ0=*c$0SpA5-i*P2vE;-+*|k8kY=;!lYU#il2mzV%6tQwUi!}fmDNC z1YPL{gVrLCqm>zSF0$I_B1KefRQwuhu~SgATjP&-Q!oabK_eaT5qUfCiDz(gu?$FT z?;jw=TpA&OExVs#9R7{RC2#o7ok3C0Ku2n9R*lIn#PR=CM9X`;Fvo+C5UkoROUS`& zqU{Jqv*|ivzX4oexxnKp7Ch&{Py(e#+VzrE4fRlVMkXy^j;}b_zyabvBzPIL#sQVqN{JWll=bqLUS+G6y}u&a z3j7?R%{4j581_5aE6--vlTwI1o}N_q`~l>h%0JWN7%c^!N`Xt$1>&-i?n(DfP|I6( z1tZ?81qW5~t&%=URYn|d{mSFW6=XMXn-qoNGQr1fFTZC@H~ZWXY}s_<&Ja(0V54(3 zX(KrO67N3jf8mBSr?A|!iPxp@?!*4Zh-fHB;JyW)hO606y}0`jjCTKV1v~iVWfY+_ zO|q*n2VS|3*ts*{lL6Aow|HD-5^+6sj(|VOCz>I$odfIHY_KU$wAqR$2Er4AJT9l? z>D!4XDkOK3C+O~se8;hcUQZ{f3|jjlUWX7Gs@mCUWvvg69LmAq<^nl# z6CTl*f#8#SR5AzmbiVNz*fgsOYe&K@cyTjvgCI2J^VYc-w9uNr6EI87SooG@RMgiF zVEMd+=s?USE@sIiE*1R^&Y7pM0ouS0i_^w)t7$ZJRkmzmc8-;?(~A?&a0#S+gz`G~ zmp*H|&)O9K^9osX=EIem3_WuwiaO*;hu%M(45!N zwpvg@xsp`JjVRW?nfZ0UEzdY_mMBHzk70)5a+ZtyUP4Lg@;kO^NO- zlvIQF*rC|3AFVpT<9a}_$h4OhNn4>I#eRdKw8st^8KT!7NA4RD@1MxtQD05(eVX1f zL0k*HN(9w-TxUzf?GSc3_$#Vf#9?%jtFmfB#9txhrW7BXyFx7ov^_RvlKURZn&Zel zGlN|B|1Y^pKPeOgg#i)o`(VNlF>Z+yAkGXpz&H}9dJ7qoq4kfJeT*WQV8C^aYLt9W zYz)9z>=dK@_ir=ry8JEtxy9dE0?CMCAN zSmh=|!gUm_NIZjbKlx1kKpLBtWR~L@=8w!OLBl>MWf_NVz_Ao|U=oaqU&s6zi0ZOM z=S9ccqBESWt5=G3a_dTkLXEJDrb!J0_`eUW`jb+8w#VTmaqe_^E$1dJ%B!Wc4pBb3 zlPH%qPKxpiQ|GHcE6+M*rFVp}&Jcjv<4)W24oL}%>lqgvTgVE3#2Z=t9 zXu@$H;W**b1&oL`0ca!Qgk%K%IYMV}O!1HN*v)@lU3b}|wCwn(h`h9ScW;abcn9`@ ztSrSmhhKyQU*v8(e11N1QMIXvT)Bq0Eq*%pUCIaU*ROGpR?YU`S?OlGwDW%b|Ly(j zyj0t5udv<>!ttY`1s4yGPQ2JYia$>IgWBh~m{v*dmwbovmM{+Vmfg@$bWl%H!2>_#jYWBTPr6f$Q|o)58EhASY4pI!PNDIf)On3O{Nz8GO_CraGq21LTuG>! zgB&3N&pC?3RvnGrmTTu0b~Qc=bbj^VSHk5|d1Zu~^J8=mFK_%1h=LhUeE5@<%%!*G zI%_z^9fKZjIr0?6W4b%px5YXh)toyc_=BQWNf6_(d?%WD?8=Tu_3-aV-c1xFpcgte zORDAXE{az7LQ&;a>r#EK)TdgPR#RNldZ1$xCaR;w_5STG(vF?ZBVw-me=p;Mt?7j8 zOjSD$=<91(KoFJQUWMaS!^azo<E z6MgnzO#764NegDxulr;-oATF!5Ep|I28^bwA#quM6iD^{X+O{CP!_ zu{)5fJ!n52u)ew>)bHznr)9>j)f4HTB;p_FE6ySWi-AwGRwE>3aI@xhIpT?3otPTU zL|A-JJ9y%OXx<(%t-=36E6=tp_`3F&@_y=qPvym~ymv!9 zh=)(gfji?1r-G7Ogjn#fKi%BQT0J=;)Yy=3d(m#%as9qO`qDr!eBx>>K5LYP+zzo?}XK5;$! z!j+M4Z8NS8S~LWw{qKE;uU2)-Uye@^CerK7Urt+#IcEJ-b8-u=fLom6HARQF#&} zhhAvw8pO4K$g|m8V!$~eYq2tQYduvi#v=}B_e%WXT!$A$VSc;sRho+p_#VYR&wg{U z9O(t3&lcAa85@?MPi(%})u=%nV+AcH=NpRyK`I%kXV{1(X>X2teO4VsAkk<+#~RvT00RLF4Uh~ZI0G{f zA!wqJi<2PKm|!k~7P%O-#Fqi|XpdUkgVy%g^S3Saw3S*f37`a22;PeKcuX~mdE==^8 z$Hbyo(Z}v>U$C!~;R)pLm14X^-z9Vh1n#D7p3{w8yVEz-praVw2 zCTWJvZIc1RJ}r877MMskg+ixl&|sT?%3RY`V2|J2HdlAA%Z`+U5_22fV;Uy$yxzT1 zxXghV=WfaL?>=kR&91xd++T!l2Fe}`AC{&Br^>?flCVY=2rnl6lFm}_eY;4FTG!<| z9P8FWiBb;xQUc&&en)F01(;I_y0< zFra&2KqMZZ2H}3%vZ2`A%RcsbDp$sc>6KMJlVX>z62F7F)My~r;fp>dBuIp&J&&Mi zFJVL_1WV7i{gfzmgf4t*Nx*~{$*Nc`2HrN(dqv@P3%DeZIct4XON*~9keizL;%4i+ z8Q3M{8O%Wb>%808mYeG}|EhMha!vvVUlzWW=i)vJgs)5uhL<^5Y1nW0LoTM-kt=|d zbpUiM0Ok&elKxieX7k|3jAs60XvP)2=iZL)2RjA!x7Ym#UqSO^U+6Ig=S6>b6c1xz zMXRV|&9Hf4tWX#2ZQ6jgJ^Fm!P2C)qY`hjjZJplM&f^qiK2D|{Z+^QagAPK3L)gof z{g*o<35z-mo&(YhXu7}}N9GE&b=(<1H?(gB+WZn>NFbiqeQ3GyQHiN|^s}?E#8b&s zS3ZNftb6;@s+~jpvYzeH>zVcNo9sMzMK_QSBj|#X{w2jyI^4fsghL8v^I!1ie+EM{ zH=K2ITtC;_2QIk5n<{0>iDw!CeHN`M|1sLENV78YM5^J00@T$<1k2=3K$V}BJ&}Hc zsnG9dHjKB+XC9OYu?hunQR9Vd)4xcs3p9GJc}TcEDQLnJI&!ha#6yDejNU#6#b;&} z$f0X^PEt`R?-gx3ONqd8bAbuuAC>Gta?1muqoP&l-ui3i)*rr{qW)1DUY!JCdLg0y zEZ*~ds4vijcJ$O922W!{XaYA?zSJjXC zQ=Vl~6`jjS_Hip2t|MVSM_BVYi}~C$*nA%TlKF%%?6caT=F{d+?D^b_mL&5D@@E|c zB~u|QW+BGer*2^O+TI^pH3D zm@kSV@sg}0nJkiLG6}7{(Bk(wHoT0v6rOV#q##4ixV@Knt1;OF-|RE@1=>n-xPu-y zpc@Fi5rmz@>O<>sCi?>>+t*f^s+K9tD}z}?@_+$T#rPK{x04)zX`>k&I=ozaB^klJ~~p_fpWW0;a5d< z*&BThDe(mO9*E!mmLY_F*gK45)g63(q|yb=Lz0y2glht$B?&!w>>C4hC7epb3O)>$fvs|Q*Ml?z+DDN62h z?GiV^Tx9IB1zQwZHP};4#kdoi^HAqXe^5F-y+ehuE1WVucTCp;*dT@x#I)u>S#^=+%64 zayvaszW@O97LA&)K5aLbIHNs94ia$#OnM?#JEUhpvu1)P&~~31v7lKu0j~X_+>OL| z6+Xc{ASosRC6-PTlqR0jrk9F2wdn!n6o*@pf6zES-?SR*E6W zLy<-H2cF2CT)OmAS*rPr_aSLJZ$U0F>%Ntf`Z3ian;&GIC^fo;dBAE$ ziTlFGq3or`P8Gb%_U=+%j$EwRcIEA|y=?4`tbc%2al>WvFwJc3%tuhD>35d($+q*!jf%9fXWi+ZjjYicdu=rz< zqUc4$ia;5=RrhsVhXvZ^r@}0}fTZEoV7Q6_>0C1mRdshOCor%a&%l{@+0T0an1Mf# z|EgL?V*6RFVRU$Tui2Lmi=KyGJ-bU9%Z1%kIFC~m6R-pY=E^#Tu6S7C`7E5~D=YuWgUU-&hyD&gokI^=m z3aAfZ!a=a$c$M`x7*zlMy|U;8@}H;q@H>&Ruwx_3(ser^3I0BMKO80!vd4BAon(0< zBGcO^OhOi)qI{p>XVbwZ`A-tB2+>k`6Gyh!vO6GUwQK`eP?o&FNRUD9{?KE)yrnPN z$rX#w>v>_>YFcG;0l+R>-Dpv}cD6s62rq>_q4->B$m{NkKQjVvh$@%+ddwb28H){b z0OccUEFjQOI>i^$0#{nBQM>EJoh*;5k5O3*FZ8Mq-!Chl?mdmClx(Ck4#ts>sd^q0rZsh zUDj@sgvz(Pa@r_9Y@w9Eq1#gP;nVCM3o`7=!b4DRSoHH>k>040dl5K_bgoR$M z@bZQvq<5^3_f5y%wvquS;H7x)|4>5zN=>A0f1+BYV$EwKh)xPbRwB!XN5ymCi|3P7T&5?FysY}Pkt5-K+Zs4!F2(70*Fg zSdAY%y_{^TI=BoR&mpEjsU!8v@+jl;0fT2a6Y{`hkY})ZkW_itx4Wc2;9}4F0f#Hq!s9*cOv`5sGir}JUzu+iL(b6edENJer59M|< ztU$~y8r#O+ql77hSi4p}ScUnO_4fwr%tl?XOf6ziTGzy(9k`N9|G>6POVS^E5~ZyXEczvj#5^4yF5{f~3U z3MqaT;+szs*6&%}6nL_5mkMIpT0Ozy$98#EAH0K0=>Et7G07@I_GS6|2Sm+6{gO;{ zgCh5o^ozBMLu!1Zh3N=x-P^gus?m|#arB?kShG|x+ifspuB?HX$iu8&NJ?u%?yj^f zE31A>m~6W%^;XU5fr!WcU4+r2BpX{Z7X+cwb(qgg*8z5EB9VSe5Xn;}4Bjd50@3F% zh;IYL=pmeC2@t%bfZ$K`6Ci-Sd5SL$1oRppsN$ah!O=Ct0@xI8z0V#k0Rpk>7LVdM z78BqVlRXT;euK>?#r_SX=)3}!qd zO9Ug_zpvuba@DgID3lJB_iaU7B7otLIS!=uS?Maf2pKBTT|{>gl?4;f?(s9xcd02B z3M`Q8;Z#787bZDqo)VkqD9u6uZp|}iY%T?SJPxvdF_lJ-liA31+v4coU0%J`8NqmnSPuK_GT&-Kb$|voy97)nUxC_TvTLe zxcJ(l(?}t&3j9;eU|iVms|@rIj%X$rDS$MQwq&?uo6m8JwCjW}Xy_6dfIt_k)+xZ2 zg-4Js8P+_3v3G138}kNA9u%bs%@M{J7)y3vC!$fm`5jvPn!s2fd;$MluPSQ7GwtqH z?hP?r)syoW+n4+ZWa3e#iel}IgJ0JgVC-O1a{}mnPvs!^siwv5yzJX=6{s8i297`U zn6I__3;KFcbrlFoKMiQa<-Lx|P6>qiRKZ;eE#ciKKA_ZcOr>so@*JFEA{2jf?8ldd`lT1N{Axk*eAhQpg%Y?{l z6!Huk204_xrV<`o0ZheI1zZ)RmOP5J4j?C>oN7ZHor{lG$;x6_`2tz_uB@J_fUVlf zB&I0j#K8jQuc|U@s=!c|N?IY*jCvJNL(aaYt&%KLpj!}Bf#7frf-|MXSzwHu&+)0C z@yolNrKnw&4Uc-lo7F;`}$51r$V*o%l<$>;R*T8NQJZ=!IdWNW=Sv_tLtlF)jD#i_hRX^uR!DxBv9BI1Y1i^#O5zjEkvGr;_~<= zQG&!Q?Lk#&tcFG5@?vlq`TMv$wirP(Fix1jpjiQR6DF{F9B3?qXW_DMi-pTuEO*RK zTnm?f#aMsk%DDsJskX4#UM@876;E;Rs?je{` zBZ7NkEZ3Ok(OAyKZVMBG=DKm7Anz1`lCQC1gO&>tSW~x3Hz=O}jZy`Q2f_0fhzelU z>xM2q1ndV{o`0vJ2E}SNW+I+SFJX2x2FLc-j8~T0tI2wt{RM-D>m0(tz8sCP{9-uI z+OvsZfMvLnC#kEPP7>IWvNk*argB=T4@!ZQYp&W-D>0as|;`d^DBWIwE(Dnx9oagJN}al zilq~iM%k}hzN&USAcbt*o@rH4^Mqi~n446ZjM762 zpF+AW6dcNM_2~o*>Uv~5;)o_hdQKls!EAf)v3M(4ye34`d6n}k<99Y#8O?3YS}^M)I0&h zP&MY~Do2%bz2&C=M7bz`5=-x_ZqY-@lh`}SoPK8i>f*gqilGPs+}mdAHT~)syjpW( z%?H0M@$~Nu-HcB+$#_+zpJFuwj$O^B8eA=Sks-F`Q$fOyRSv~@$q3tB9%b))cX%HG zqy))1S-62uk*vs>LLE@ase;J?JSV;Zj&7zRP3M$BP8~RDK*3K`go5UabHbCA;sISK zmF8tsaNgj~s6>K%Pz$A%d>K$s0m7vvj`DER3uAc8NbR3StOLfBE_7wli!kP zOHm@+mJ__z#Z zGi8mH>97t})r`pH*r_OEoh&bIGB1aPOOu12LmadE^4}}tNSMP8dX|+*carr8#)j@B zzlnLJgG?;3SxNjj&Q?tadb37I-?K&{;?v!?TP`ZL^o83cWJrHzgG}=IqP`O8DOVGo zz5pnL0MpY9ju0bHTfw8tH>&9D+r+gHL?mP9>}hne6!l6I)9WaXpboK}D)T#IIEm%4 zUNj-E%7groqg1jus6gICUDBry*aU7lljzyNhqb;bQ0A~^#=pbo!PBBwXdRicMN_L6 z+V+4pylb7jvz{GTnr9!2ns`O|6TndLS!s#;3M;J`&G?BM7xY)p$J+p>; zE!N2+gHgcvYCza4r+iPa?yGZ3>u`=JG2(bgq7GTYC9IClGfQ3Na+$ydq;V7~EJTz` zt&BU*>qvH~EwLIopWVgJymo#r-bpHT2A6kV z?nY|GYai0(S;uznJnJ0KZ@!tROs0<7dw*n|zTcwHq3wfm&dpI9@^MPe(XSll8gy=@ z9DFOwS)6f4^hvlJeRp#be)l|@$Vqv4?&pLYjjRo-6Yyo6fcxSn;OhK)|6G0kO_CGO zznQ%99C_^y6*sv}vFY6m>PNSz^c}g^5-`VHxKG%AG~Tx63RlN12%kBA5`p@(+qZ?W zoyb6>zXG~(IvG3g=6h!)5>yVq-%2?A&Y*vR&|lO!=4!wBiq=#5hv)hToWPngk5&%Km#4mfwlTsB7J} zn(^~)$pO4pI+DNa?0VpNx2glm`M+}Bt@5zMe8qWpApdauyn8f*^=xmwujsXPD;Nzu zHu)$)GAz$B#;1!45QBqy`;%XK@*V5jmz=Sua)+X2zp4s@;ZNJj3+iSbC&1?%7riqf zJ8~|5e62v)L%Dql)5dPj?Y2H{$!)hjc!`4#M)#6W0jJ;QZp7!l;jMH<4n|*bwIIm_ z8G`fU@1-myL{B*aAk{w>OzGh6UhXn={B0hTTSY6;)dU})7QHS-pV50!P-Y#2`)DvSdf(M_7Nb)1;%%@k$pnfX#l#q_2Z))*DM?Phtq%xsU z0;^BZ}6(&(ts^vDb($p zYXIool*Z64`GO+%qxY{4)#2LE;u7@^_Ap?J>m>V_SZQMil_s`cpV0EnnICp2rfUcG zEBX+Lb3{v5Ek!ChDMsmZ76WBzPGzba6MIlVmWY&O!f8MztEVJO^{0r+xV|bNCw$iZ ziQcpQyg_}ov?W2_PS>RrVYVFV^16c?Z|wozp?=$M7BeVH4VtBl3fARTvfmuy;qvB? z$eRZ&9l^yeImr^vMYLO)uIO`0S+2C`FYc{KT7(xxonRARj4TUc#8w)-(r-SMpft$t zh(Fn{qc4cApfE0!#~E)`rwZN0QBlCyX@?2FXP_!b*e*LvrDF$3SbIDSpVA@xsp$TF z-_N0bqW1i{3V*olbNjr_nnR!rrFEr5m?u(=z!4}xCcn%tUi1m^s$ZgVR1}*4OT+MC zsU@3o;)U3Hg&d_bqK^tSMmRK626ATP?}wsMuNty48M0m?ts#4zFSe62bI^WyFA!eB zvFNN+4x9g?h3ZeZTOT0_6rx8C=HsFFs`4L0m(NzeP*wU{yN@Zp@(Znd5y<~!2e%Nq z+4`R(oU2gGB-#IRlq9D_+&sy2anr{!d|*tHM994c(ODdjDMQ6^qk#Q0XxlHATtSpD zZ#Q5{k_Ck5Mo%?5&5bQ2uA%UWr2n}Qaieh9F~L%ndF$!XPyE+1+elA07T{k7BL;1AbKpV zGHO8%EpNC@J~XEJZS~yP{*(z)`nesc?BbKVnfP|@pmeI>n2tp|W0Tx13DB`nkq%L0 zQu-Gvu8(O>j^)cph;t=NHk4JXJ5{KZB)h2+f6;;U*C|=)QL8u1y^!7neVZQrRpgH4v5Kc&J$2fT|JE6HtTz9f%+omRgXBKh!L< z{}|_6jeJ1@j>|N>s8ny{>kY3^O%(c!4;i{XDlKhsy6N_b+EaUL*bxm^v|yp z-cZz!<&011Rtb_H0hJCU>Q-qi7u_n^7o%IXfMa9Po3rp+SRf!RkA<(wF;uP2m4471 zDn^(baZ{rtDjf=7AfyoRI3Jv+A65c{1QtD0C8=VF70itnp@@T3fmI=~HZ?%EM^z(h zt^4{FzzE~80SnW}SPql%u+%TwTOvcDc!Ru(oOJTIN2aTjTdZVQ{~Y{}Fw78yx2})6 zH?L07Y;|eT`|hpD5~CEejxk&q{>j})NDyXP_M0HN#X(Xjh<@DSto{4<2#I7rfIcke z^{3|q^Pi2=M_DnG`XC`p;C=@f;$p*iM7S+bRy3*d{ARm9f1kh#Dlyd}UM=Y(Uc{A1jB(U`Vz8I1aVITByS8TDzOl{Xq6#3p``5|fj22ZXMT}uz`U19+lhEHroLX; z?JN3+d;2SNT&|nQ0Kj;lSOdqbc$HxOKIE=La)3S50RcM;z%G!4m@HwZ0S}JG_mkM$ zOYthLu3-M(WY^)fR_6TU{{8!o$qeSRJ7QwE?Y!NlKdgo>o31AdMTw0Uq^Lr!LUV17 zPvA<3f2E~*Q-#v3^cOZ!%xPr=QbgW<5{aL7=gCp(s5BXJ`~q=E7ORgYRsy6DO}ZtP zC@_W0ZpN1MFR5xJT5`)n9F=dztFLlM8)-zp+FdD9u~ekWpxGIAe&`~?MU@3A-QgkJ zYP8P4m;v6OBKMLTo&`+Bh6_YVIqW(vqsob+*+I(z7=S&4cY**L2Z%`_)md6IS^7vN zaGX5fgPP}Hb+kNyI74mAu>wH9Ym_)4`&U;8t9`y`qb+@Eh5LMXWV&Pz+Z(~WJ~ChO=~ZX(Iptd&r^lN+lQ{GqJeDL-Q9Enard$DS@_38CoS)dRg!IFj0$S#}X-!Y9gDWS7pnD zZ3wtA5nB4>R%M9@iI<6lc%`-JVLU3hfqC6>ZUs@4a3ySYtev08ZbW(ky;5=;EwZ8L z&<+w=n?*kC?PH#`p%jUYFnx0COLm^5z)HQyZ|tjpSO*6KqrJCU;+t)@7)6Xqcx)>a z9@Dw;4HlCN+szr@=cCl@E6tzM!k4bpAR%O!B!61sxrcTAsSc^GF1O@iisaE- zxwqhpoJpwJC-K=*Q^?u;IwOkmcsc6czM{w0ZNOU3%M^+&o*2J}(DCnuFNp|nk=k#! zV%ubfm>Lw@$2?=<`nyl;iC^NAwrBr@+>)dBOkdkP7D!@dtC-n%vNsajivXH|HD!R;4g}NN&5`{7c&kBfl? zpIoG_LCNF*UM1GS*na*<$1Ezs)TyoywqcJi8?)6!E&yYAbVw@joj&Q+3>tqUA&8yAv_(qDer;C&hEWHMmB z$w`TO>rjgEn(uiZ-ATt1 ze1MEL;lY4_^JcPn=}FtArVr4adk8HDx1IPUH7(h*0{p<-chE{p`_>3d62T(T=(|y{$+G`E#=7smkSVA%6uI#E=%|iNro1q`wWC z0fMfaC6%TBLduFKYk65&i+T-vM>K>NbiFE>*elxayjl$e>BZ=%KwQZp^_=F)K*;&_ zi%f{RBIh-add+9@N54b}cjLCuDfQ^vZ-tz+9?NiF_g{R`_s4-0_I}rsfSJqwHQp8O zhU`Dr$mCTzkaA@DQab(NS&&97b0|T_Bc%13?PJ`Q{f5rg&b}y@?T?n`vo1O7D8l>T zFjZdqWq1PloxZRy%N`GJc-HY1?s~R1tJ{HEf5{5>7kKJBKk~Xaln&cPyrXqb226r? z7ikXAo-YojCPuuRy1N}2F-W&0^+opGvMK-?%@ z4)rSY7-I6sFFegwWzZ(^zFDdHM9_RCU{d;18@{t*$Gnj1I_j;Z4l`?uw+NF>?S6L< z!yN5+0!*Yk$YV?ggDfl02se2f^{~JFF%GRlWIi{9z|8D|L*Ai-08nRzG}_E!5$Dk- z%%39A*{HJc9vDy&2w#JpjWjT83(FP=yRC;<46L-#@Zvz|o4~Sr^K(*QNa*Hc*@`Ecy}pz2vE^gG1c=6GFYHAgQ}8O!X9pHoL^o2RW(ayAf0Cwp|xW#Vmf^w73! zK4(Q8JNZnL0vz}H%nhu#QTO%v;JJuO7?|tdQyZ)72T-80$ClGl!56RTxKS8$/ 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 Date: Sun, 7 Apr 2024 13:10:40 -0600 Subject: [PATCH 64/75] Updates to fix the wn.msx variable assignment --- wntr/epanet/msx/exceptions.py | 1 - wntr/msx/_library_data/msx.schema.json | 873 +++++++++++++++++++++++++ wntr/msx/base.py | 1 + wntr/network/model.py | 10 +- 4 files changed, 880 insertions(+), 5 deletions(-) create mode 100644 wntr/msx/_library_data/msx.schema.json diff --git a/wntr/epanet/msx/exceptions.py b/wntr/epanet/msx/exceptions.py index d505d33ef..dc8759543 100644 --- a/wntr/epanet/msx/exceptions.py +++ b/wntr/epanet/msx/exceptions.py @@ -47,7 +47,6 @@ 524: "illegal math operation", } """A dictionary of the error codes and their meanings from the EPANET-MSX toolkit. -Please see :doc:`/errors` for tables of these values. :meta hide-value: """ diff --git a/wntr/msx/_library_data/msx.schema.json b/wntr/msx/_library_data/msx.schema.json new file mode 100644 index 000000000..04c91af17 --- /dev/null +++ b/wntr/msx/_library_data/msx.schema.json @@ -0,0 +1,873 @@ +{ + "$schema": "http://json-schema.org/schema#", + "type": "object", + "properties": { + "wntr-version": { + "type": "string" + }, + "name": { + "type": "string" + }, + "title": { + "type": "string" + }, + "description": { + "type": [ + "null", + "string" + ] + }, + "references": { + "type": "array", + "items": { + "type": "string" + } + }, + "reaction_system": { + "type": "object", + "properties": { + "species": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "species_type": { + "type": "string" + }, + "units": { + "type": "string" + }, + "atol": { + "type": "null" + }, + "rtol": { + "type": "null" + }, + "note": { + "type": "string" + } + }, + "required": [ + "atol", + "name", + "note", + "rtol", + "species_type", + "units" + ] + } + }, + "constants": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "value": { + "type": "number" + }, + "units": { + "type": "string" + }, + "note": { + "type": "string" + } + }, + "required": [ + "name", + "note", + "units", + "value" + ] + } + }, + "parameters": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "global_value": { + "type": "number" + }, + "note": { + "type": "string" + } + }, + "required": [ + "global_value", + "name" + ] + } + }, + "terms": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "expression": { + "type": "string" + }, + "note": { + "type": "string" + } + }, + "required": [ + "expression", + "name" + ] + } + }, + "pipe_reactions": { + "type": "array", + "items": { + "type": "object", + "properties": { + "species_name": { + "type": "string" + }, + "expression_type": { + "type": "string" + }, + "expression": { + "type": "string" + }, + "note": { + "type": "string" + } + }, + "required": [ + "expression", + "expression_type", + "species_name" + ] + } + }, + "tank_reactions": { + "type": "array", + "items": { + "type": "object", + "properties": { + "species_name": { + "type": "string" + }, + "expression_type": { + "type": "string" + }, + "expression": { + "type": "string" + }, + "note": { + "type": "string" + } + }, + "required": [ + "expression", + "expression_type", + "species_name" + ] + } + } + }, + "required": [ + "constants", + "parameters", + "pipe_reactions", + "species", + "tank_reactions", + "terms" + ] + }, + "network_data": { + "type": "object", + "properties": { + "initial_quality": { + "type": "object", + "properties": { + "AS3": { + "type": "object", + "properties": { + "global_value": { + "type": "number" + }, + "node_values": { + "type": "object" + }, + "link_values": { + "type": "object" + } + }, + "required": [ + "global_value", + "link_values", + "node_values" + ] + }, + "AS5": { + "type": "object", + "properties": { + "global_value": { + "type": "number" + }, + "node_values": { + "type": "object" + }, + "link_values": { + "type": "object" + } + }, + "required": [ + "global_value", + "link_values", + "node_values" + ] + }, + "AStot": { + "type": "object", + "properties": { + "global_value": { + "type": "number" + }, + "node_values": { + "type": "object" + }, + "link_values": { + "type": "object" + } + }, + "required": [ + "global_value", + "link_values", + "node_values" + ] + }, + "AS5s": { + "type": "object", + "properties": { + "global_value": { + "type": "number" + }, + "node_values": { + "type": "object" + }, + "link_values": { + "type": "object" + } + }, + "required": [ + "global_value", + "link_values", + "node_values" + ] + }, + "NH2CL": { + "type": "object", + "properties": { + "global_value": { + "type": "number" + }, + "node_values": { + "type": "object" + }, + "link_values": { + "type": "object" + } + }, + "required": [ + "global_value", + "link_values", + "node_values" + ] + }, + "HOCL": { + "type": "object", + "properties": { + "global_value": { + "type": "number" + }, + "node_values": { + "type": "object" + }, + "link_values": { + "type": "object" + } + }, + "required": [ + "global_value", + "link_values", + "node_values" + ] + }, + "NH3": { + "type": "object", + "properties": { + "global_value": { + "type": "number" + }, + "node_values": { + "type": "object" + }, + "link_values": { + "type": "object" + } + }, + "required": [ + "global_value", + "link_values", + "node_values" + ] + }, + "NHCL2": { + "type": "object", + "properties": { + "global_value": { + "type": "number" + }, + "node_values": { + "type": "object" + }, + "link_values": { + "type": "object" + } + }, + "required": [ + "global_value", + "link_values", + "node_values" + ] + }, + "I": { + "type": "object", + "properties": { + "global_value": { + "type": "number" + }, + "node_values": { + "type": "object" + }, + "link_values": { + "type": "object" + } + }, + "required": [ + "global_value", + "link_values", + "node_values" + ] + }, + "OCL": { + "type": "object", + "properties": { + "global_value": { + "type": "number" + }, + "node_values": { + "type": "object" + }, + "link_values": { + "type": "object" + } + }, + "required": [ + "global_value", + "link_values", + "node_values" + ] + }, + "NH4": { + "type": "object", + "properties": { + "global_value": { + "type": "number" + }, + "node_values": { + "type": "object" + }, + "link_values": { + "type": "object" + } + }, + "required": [ + "global_value", + "link_values", + "node_values" + ] + }, + "ALK": { + "type": "object", + "properties": { + "global_value": { + "type": "number" + }, + "node_values": { + "type": "object" + }, + "link_values": { + "type": "object" + } + }, + "required": [ + "global_value", + "link_values", + "node_values" + ] + }, + "H": { + "type": "object", + "properties": { + "global_value": { + "type": "number" + }, + "node_values": { + "type": "object" + }, + "link_values": { + "type": "object" + } + }, + "required": [ + "global_value", + "link_values", + "node_values" + ] + }, + "OH": { + "type": "object", + "properties": { + "global_value": { + "type": "number" + }, + "node_values": { + "type": "object" + }, + "link_values": { + "type": "object" + } + }, + "required": [ + "global_value", + "link_values", + "node_values" + ] + }, + "CO3": { + "type": "object", + "properties": { + "global_value": { + "type": "number" + }, + "node_values": { + "type": "object" + }, + "link_values": { + "type": "object" + } + }, + "required": [ + "global_value", + "link_values", + "node_values" + ] + }, + "HCO3": { + "type": "object", + "properties": { + "global_value": { + "type": "number" + }, + "node_values": { + "type": "object" + }, + "link_values": { + "type": "object" + } + }, + "required": [ + "global_value", + "link_values", + "node_values" + ] + }, + "H2CO3": { + "type": "object", + "properties": { + "global_value": { + "type": "number" + }, + "node_values": { + "type": "object" + }, + "link_values": { + "type": "object" + } + }, + "required": [ + "global_value", + "link_values", + "node_values" + ] + }, + "chloramine": { + "type": "object", + "properties": { + "global_value": { + "type": "number" + }, + "node_values": { + "type": "object" + }, + "link_values": { + "type": "object" + } + }, + "required": [ + "global_value", + "link_values", + "node_values" + ] + }, + "PB2": { + "type": "object", + "properties": { + "global_value": { + "type": "number" + }, + "node_values": { + "type": "object" + }, + "link_values": { + "type": "object" + } + }, + "required": [ + "global_value", + "link_values", + "node_values" + ] + }, + "Nx": { + "type": "object", + "properties": { + "global_value": { + "type": "number" + }, + "node_values": { + "type": "object" + }, + "link_values": { + "type": "object" + } + }, + "required": [ + "global_value", + "link_values", + "node_values" + ] + }, + "NX2": { + "type": "object", + "properties": { + "global_value": { + "type": "number" + }, + "node_values": { + "type": "object" + }, + "link_values": { + "type": "object" + } + }, + "required": [ + "global_value", + "link_values", + "node_values" + ] + } + } + }, + "parameter_values": { + "type": "object", + "properties": { + "k1": { + "type": "object", + "properties": { + "pipe_values": { + "type": "object" + }, + "tank_values": { + "type": "object" + } + }, + "required": [ + "pipe_values", + "tank_values" + ] + }, + "k2": { + "type": "object", + "properties": { + "pipe_values": { + "type": "object" + }, + "tank_values": { + "type": "object" + } + }, + "required": [ + "pipe_values", + "tank_values" + ] + }, + "k3": { + "type": "object", + "properties": { + "pipe_values": { + "type": "object" + }, + "tank_values": { + "type": "object" + } + }, + "required": [ + "pipe_values", + "tank_values" + ] + }, + "k4": { + "type": "object", + "properties": { + "pipe_values": { + "type": "object" + }, + "tank_values": { + "type": "object" + } + }, + "required": [ + "pipe_values", + "tank_values" + ] + }, + "k6": { + "type": "object", + "properties": { + "pipe_values": { + "type": "object" + }, + "tank_values": { + "type": "object" + } + }, + "required": [ + "pipe_values", + "tank_values" + ] + }, + "k7": { + "type": "object", + "properties": { + "pipe_values": { + "type": "object" + }, + "tank_values": { + "type": "object" + } + }, + "required": [ + "pipe_values", + "tank_values" + ] + }, + "k8": { + "type": "object", + "properties": { + "pipe_values": { + "type": "object" + }, + "tank_values": { + "type": "object" + } + }, + "required": [ + "pipe_values", + "tank_values" + ] + }, + "k9": { + "type": "object", + "properties": { + "pipe_values": { + "type": "object" + }, + "tank_values": { + "type": "object" + } + }, + "required": [ + "pipe_values", + "tank_values" + ] + }, + "k10": { + "type": "object", + "properties": { + "pipe_values": { + "type": "object" + }, + "tank_values": { + "type": "object" + } + }, + "required": [ + "pipe_values", + "tank_values" + ] + }, + "F": { + "type": "object", + "properties": { + "pipe_values": { + "type": "object" + }, + "tank_values": { + "type": "object" + } + }, + "required": [ + "pipe_values", + "tank_values" + ] + } + } + }, + "sources": { + "type": "object" + }, + "patterns": { + "type": "object" + } + }, + "required": [ + "initial_quality", + "parameter_values", + "patterns", + "sources" + ] + }, + "options": { + "type": "object", + "properties": { + "timestep": { + "type": "integer" + }, + "area_units": { + "type": "string" + }, + "rate_units": { + "type": "string" + }, + "solver": { + "type": "string" + }, + "coupling": { + "type": "string" + }, + "rtol": { + "type": "number" + }, + "atol": { + "type": "number" + }, + "compiler": { + "type": "string" + }, + "segments": { + "type": "integer" + }, + "peclet": { + "type": "integer" + }, + "report": { + "type": "object", + "properties": { + "pagesize": { + "type": "null" + }, + "report_filename": { + "type": "null" + }, + "species": { + "type": "object", + "properties": { + "PB2": { + "type": "string" + } + } + }, + "species_precision": { + "type": "object", + "properties": { + "PB2": { + "type": "integer" + } + } + }, + "nodes": { + "type": [ + "null", + "string" + ] + }, + "links": { + "type": [ + "null", + "string" + ] + } + }, + "required": [ + "links", + "nodes", + "pagesize", + "report_filename", + "species", + "species_precision" + ] + } + }, + "required": [ + "area_units", + "atol", + "compiler", + "coupling", + "peclet", + "rate_units", + "report", + "rtol", + "segments", + "solver", + "timestep" + ] + } + }, + "required": [ + "description", + "name", + "network_data", + "options", + "reaction_system", + "references", + "title", + "wntr-version" + ] +} diff --git a/wntr/msx/base.py b/wntr/msx/base.py index 6bc035ddc..bee6b727d 100644 --- a/wntr/msx/base.py +++ b/wntr/msx/base.py @@ -73,6 +73,7 @@ def coth(x): ``D`` pipe diameter ``Kc`` pipe roughness coefficient ``Q`` pipe flow rate + ``U`` pipe flow velocity ``Re`` flow Reynolds number ``Us`` pipe shear velocity ``Ff`` Darcy-Weisbach friction factor diff --git a/wntr/network/model.py b/wntr/network/model.py index da6c159b1..cb04fa2e2 100644 --- a/wntr/network/model.py +++ b/wntr/network/model.py @@ -321,12 +321,14 @@ def msx(self): return self._msx @msx.setter - def msx(self, msx): - if msx is None: + def msx(self, model): + if model is None: self._msx = None + return from wntr.msx.base import QualityModelBase - if not isinstance(msx, QualityModelBase): - raise TypeError('Expected QualityModelBase (or derived), got {}'.format(type(msx))) + if not isinstance(model, QualityModelBase): + raise TypeError('Expected QualityModelBase (or derived), got {}'.format(type(model))) + self._msx = model def add_msx_model(self, msx_filename=None): """Add an msx model from a MSX input file (.msx extension)""" From f76e9972e50ccb0fbd6d2047d55bbbb2d2050264 Mon Sep 17 00:00:00 2001 From: David Hart Date: Tue, 30 Apr 2024 15:48:16 -0600 Subject: [PATCH 65/75] JSON schema commit --- wntr/msx/_library_data/msx.schema.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wntr/msx/_library_data/msx.schema.json b/wntr/msx/_library_data/msx.schema.json index 04c91af17..24feef0e2 100644 --- a/wntr/msx/_library_data/msx.schema.json +++ b/wntr/msx/_library_data/msx.schema.json @@ -1,5 +1,5 @@ { - "$schema": "http://json-schema.org/schema#", + "$schema": "http://json-schema.org/draft-07/schema#", "type": "object", "properties": { "wntr-version": { From d1df04eb42f4ee7e61556c796383acc576734f5d Mon Sep 17 00:00:00 2001 From: David Hart Date: Sat, 4 May 2024 09:19:20 -0600 Subject: [PATCH 66/75] Update to MSX examples and bug fix --- examples/data/msx_as.msx | 58 ++++++ examples/demos/multisource-cl-decay.ipynb | 211 ++++++++++++++++++++++ examples/networks/msx_as.inp | 36 ++++ wntr/epanet/msx/io.py | 2 +- wntr/msx/model.py | 2 +- 5 files changed, 307 insertions(+), 2 deletions(-) create mode 100644 examples/data/msx_as.msx create mode 100644 examples/demos/multisource-cl-decay.ipynb create mode 100644 examples/networks/msx_as.inp diff --git a/examples/data/msx_as.msx b/examples/data/msx_as.msx new file mode 100644 index 000000000..b20e0854b --- /dev/null +++ b/examples/data/msx_as.msx @@ -0,0 +1,58 @@ +[TITLE] +Arsenic Oxidation/Adsorption Example + +[OPTIONS] + AREA_UNITS M2 ;Surface concentration is mass/m2 + RATE_UNITS HR ;Reaction rates are concentration/hour + SOLVER RK5 ;5-th order Runge-Kutta integrator + TIMESTEP 360 ;360 sec (5 min) solution time step + RTOL 0.001 ;Relative concentration tolerance + ATOL 0.0001 ;Absolute concentration tolerance + +[SPECIES] + BULK AS3 UG ;Dissolved arsenite + BULK AS5 UG ;Dissolved arsenate + BULK AStot UG ;Total dissolved arsenic + WALL AS5s UG ;Adsorbed arsenate + BULK NH2CL MG ;Monochloramine + +[COEFFICIENTS] + CONSTANT Ka 10.0 ;Arsenite oxidation rate coefficient + CONSTANT Kb 0.1 ;Monochloramine decay rate coefficient + CONSTANT K1 5.0 ;Arsenate adsorption coefficient + CONSTANT K2 1.0 ;Arsenate desorption coefficient + CONSTANT Smax 50 ;Arsenate adsorption saturation limit + +[TERMS] + Ks K1/K2 ;Equil. adsorption coeff. + +[PIPES] + ;Arsenite oxidation + RATE AS3 -Ka*AS3*NH2CL + ;Arsenate production + RATE AS5 Ka*AS3*NH2CL - Av*(K1*(Smax-AS5s)*AS5 - K2*AS5s) + ;Monochloramine decay + RATE NH2CL -Kb*NH2CL + ;Arsenate adsorption + EQUIL AS5s Ks*Smax*AS5/(1+Ks*AS5) - AS5s + ;Total bulk arsenic + FORMULA AStot AS3 + AS5 + +[TANKS] + RATE AS3 -Ka*AS3*NH2CL + RATE AS5 Ka*AS3*NH2CL + RATE NH2CL -Kb*NH2CL + FORMULA AStot AS3 + AS5 + +[QUALITY] + ;Initial conditions (= 0 if not specified here) + NODE Source AS3 10.0 + NODE Source NH2CL 2.5 + +[REPORT] + NODES C D ;Report results for nodes C and D + LINKS 5 ;Report results for pipe 5 + SPECIES AStot YES ;Report results for each specie + SPECIES AS5 YES + SPECIES AS5s YES + SPECIES NH2CL YES diff --git a/examples/demos/multisource-cl-decay.ipynb b/examples/demos/multisource-cl-decay.ipynb new file mode 100644 index 000000000..a6d2edd9c --- /dev/null +++ b/examples/demos/multisource-cl-decay.ipynb @@ -0,0 +1,211 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [], + "source": [ + "import pandas as pd\n", + "import matplotlib.pyplot as plt\n", + "import wntr\n", + "from wntr.msx.elements import InitialQuality\n", + "wn = wntr.network.WaterNetworkModel('../networks/Net3.inp')\n", + "wn.options.quality.parameter = 'NONE'" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "Reaction(species_name='CL2', expression_type=, expression='-(k1*T1 + k2*(1-T1))*CL2')" + ] + }, + "execution_count": 16, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "wn.add_msx_model()\n", + "wn.msx.options.area_units = 'FT2'\n", + "wn.msx.options.rate_units = 'DAY'\n", + "wn.msx.options.timestep = 300\n", + "wn.msx.add_species('T1','bulk',units='MG', note='Source 1 Tracer')\n", + "wn.msx.add_species('CL2','bulk', units='MG', note='Free Chlorine')\n", + "k1 = wn.msx.add_constant('k1', 1.3)\n", + "k2 = wn.msx.add_constant('k2', 17.7)\n", + "wn.msx.add_reaction('T1', 'pipe', 'rate', '0')\n", + "wn.msx.add_reaction('CL2', 'pipe', 'rate', '-(k1*T1 + k2*(1-T1))*CL2')\n", + "wn.msx.add_reaction('T1', 'tank', 'rate', '0')\n", + "wn.msx.add_reaction('CL2', 'tank', 'rate', '-(k1*T1 + k2*(1-T1))*CL2')" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [], + "source": [ + "wn.msx.network_data.initial_quality['T1'] = InitialQuality(node_values={'River': 1.0})\n", + "wn.msx.network_data.initial_quality['CL2'] = InitialQuality(node_values={'River':1.2, 'Lake':1.2})" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": {}, + "outputs": [], + "source": [ + "sim = wntr.sim.EpanetSimulator(wn)\n", + "res = sim.run_sim()" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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", + "text/plain": [ + "

      " + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "image/png": "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", + "text/plain": [ + "
      " + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAeIAAAGbCAYAAAAYxJOqAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8g+/7EAAAACXBIWXMAAA9hAAAPYQGoP6dpAACN/ElEQVR4nOzddVhV2RrA4d85dIcBKggGYhd2d3fH2DV2zVhjO3Y7zqhjd4zd3d05tmAhoCigNOfs+4dXZhhCUOAQ33uf/dzL2rG+7YXznbX3CpWiKApCCCGE0Am1rgMQQggh0jNJxEIIIYQOSSIWQgghdEgSsRBCCKFDkoiFEEIIHZJELIQQQuiQJGIhhBBChyQRCyGEEDokiVgIIYTQIUnEQqQwHh4eqFQqZs2apetQhBDJQBKxEPF07949WrZsSc6cOTE1NSVjxoxUqlSJPXv2xHi8Vqtl0aJFFC1aFBMTEzJkyEC1atW4detWMkcuhEjJ9HUdgBCpxfPnz/n48SOdOnUia9asBAUFsW3bNho1asSSJUvo2bNnlOO7du3K+vXr6dixI/369SMwMJAbN27g4+OjozsQQqREKln0QYhvp9FocHNzIyQkhAcPHkSWb9myhdatW7N9+3aaNm2aoGt6eHiQI0cOZs6cyU8//ZTYIQshUhh5NC3Ed9DT08PR0RE/P78o5XPmzKFUqVI0bdoUrVZLYGDgN13/zz//JFeuXBgZGVGyZEmuXLmSCFELIVISScRCJFBgYCDv3r3j6dOnzJ07lwMHDlC9evXI/QEBAVy+fJmSJUsyatQorKysMDc3J2fOnGzZsiXe9WzYsIGZM2fSq1cvfv31Vzw8PGjWrBnh4eFJcVtCCB2Rd8RCJNDQoUNZsmQJAGq1mmbNmrFw4cLI/U+fPkVRFDZt2oS+vj4zZszAysqK+fPn06ZNGywtLalTp85X63nx4gWPHz/GxsYGAFdXVxo3bsyhQ4do0KBB0tycECLZSSIWIoEGDRpEixYt8PT0ZMuWLWg0GsLCwiL3f/r0CQBfX18uXrxI6dKlAWjUqBE5cuTg119/jVcibt26dWQSBqhYsSIAz549S8zbEULomDyaFiKB8ubNS40aNejYsSN79+7l06dPNGzYkC/9Hk1MTADIkSNHZBIGMDc3p2HDhly+fJmIiIiv1pM9e/YoP39Jyh8+fEisWxFCpACSiIX4Ti1atODKlSs8evQIgKxZswJgZ2cX7djMmTMTHh4er85benp6MZbLQAch0hZJxEJ8p+DgYAD8/f2Bz4nY3t6e169fRzvW09MTY2NjLCwskjVGIUTKJYlYiHiKaSKO8PBw1qxZg4mJCfnz548sb926NS9fvuTIkSORZe/evWPXrl1Uq1YNtVr+9IQQn0lnLSHiqVevXgQEBFCpUiWyZcuGl5cX69ev58GDB8yePRtzc/PIY0eOHMmWLVto3rw5Q4YMwcrKisWLFxMeHs6UKVN0eBdCiJRGErEQ8dS6dWuWL1/OokWL8PX1xcLCAjc3N6ZPn06jRo2iHGtnZ8fZs2f56aefmDt3LuHh4ZQtW5Z169ZRpEgRHd2BECIlkikuhRBCCB2SF1VCCCGEDkkiFkIIIXRIErEQQgihQ5KIhRBCCB2SRCyEEELokCRiIYQQQockEQshhBA6JIlYCCGE0CFJxEIIIYQOSSIWQgghdEgSsRBCCKFDkoiFEEIIHZJELIQQQuiQJGIhhBBChyQRCyGEEDokiVgIIYTQIUnEQgghhA5JIhZCCCF0SBKxEEIIoUOSiIUQQggdkkQshBBC6JAkYiGEEEKHJBELIYQQOiSJWAghhNAhScRCCCGEDkkiFkIIIXRIErEQQgihQ5KIhRBCCB2SRCyEEELokCRiIYQQQockEQshhBA6JIlYCCGE0CFJxEIIIYQOSSIWQgghdEgSsRBCCKFD+roOQIiU5tNzbx4t20/QG18c6pTEqXklVCqVrsMSQqRRKkVRFF0HIURK8f7OMw5UGkSYf2BkmUvXulRY9pMOoxJCpGXyaFqIf7n167ooSRjg8YoD+N1/rqOIhBBpnSRiIf7lwx33mMvveiRvIEKIdEMSsRD/ksHNJXqhSkWGYrmTPxghRLogiViIfyk6ugNGGa2ilOXv3xTL3Nl0FJEQIq2TzlpC/MfTG/foV7weHRq1oHK/tmSrWULXIQkh0jAZviTEf1x7fI+DvGDlkp+xt7fXdThCiDROHk0L8R8nTpwgc+bMkoSFEMlCErEQ/3Hp0iWKFy+u6zCEEOmEJGIh/iUiIoK///6bihUr6joUIUQ6Ie+Ihfi/NyducHXJDhqGOlDGKZ+uwxFCpBPSa1oI4Pa0jVwbtSzyZ7WRATX3TiFrdXlELYRIWvJoWqR7oX6fuPXruihl2tDwKIlZCCGSiiRike59fPKaiKCQaOUfbj/TQTRCiPRG3hGLdCPU7xNBr95imccBPUMDAHx9fZn45zzyocEYvSjH28q0lunay/2XeLhkD+GfgnFqWpG8vRui1tP7+olCJJAkYpEuXB25jL/nb0MTEoZxJmuKzOjO6r9P8ttvv6EoCmMrt8T+1OvI4/WMDXGb0l2HEQtderr+KKc7TI382evETd7ffCLLYYokIY+mRZr3bONx7kzfiCYkDICQt36c7zKD1XP+oHPnzrx48YKRJ9bwoXcpjqheUeiX9jS5s5wsVYrqNnChM7emrI9W9mT1IYI83+kgGpHWSYtYpHnuf52MVqaHmu2j51FuXLfIsjOeD3joqkeJSV2TMTqR0mi1WvyfeUYrVzRaAl++xTRrRh1EJdIyaRGLNE/fxCjGcqtMGaL8fPPmTdzc3JIjJJECffz4kVmzZpE9e3ZuhXhF22+UwRKbIrl0EJlI6yQRizTPpVs9UKmilAUSTvu5I7l9+zZvrzzgVI+ZVH9uQkVr+aBNb549e0bPnj2xt7dn+PDhFC1alCYbJ2Ka7Z+Wr9rQgHKLBqFvbKjDSEVaJRN6iHTh6fqj3Jiwho9PPbErXwCzbpXpMuEnMjwPpDcFUf3rr6D4pK4U+aW97oIVSU5RFI4dO8bUqVM5ceIE5ubmdO3alZ9++gkHBwcAIoJDebnnAuEfg3BsUAYTO1sdRy3SKknEIl1RFAXV/1vHISEhrMzWDOMPoVGO0TczpvXrLRhamukiRJGEgoODWb16NbNmzeLp06fkyJGDn376ic6dO2Nqaqrr8EQ6JY+mRbqi+tcjaiMjI4z9wqIdExEYwqfn3skZlkhir1+/ZsiQIdjb29OnTx+yZ8/O4cOHefr0KX369JEkLHRKErFIt1QqFRlL5IlWbmRrgaWLgw4iEont4sWLNGrUCCcnJxYvXkyrVq149OgRx48fp2bNmlG+mAmhK5KIRbpWctaP6Jn+06tapVZTcuaP0iknFQsPD2ft2rUUKlSIsmXLcu3aNaZMmYKXlxdLly4ld26ZMU2kLJKIRbpmX7EwLpuHsEV5Qqbu1Wl8aykuXeroOizxDd69e8eYMWPIkiULHTt2xMzMjB07dvDixQuGDRuGpaWlrkMUIkYyoYdI9248f8Qh1Uu2zRsk7wpTodu3bzNlyhR27NgBQLNmzRg5ciSFCxfWcWRCxI8kYpHuXbx4EScnJ0nCqYhGo2HXrl1MmzaNK1eukDFjRkaMGEH//v3JmFFmvhKpizyaFunezZs3pfWUSvj7+zN9+nSyZ89O8+bNCQ0NZd26dXh6ejJhwgRJwmmch4cHKpWKmzdv6jqURCWJWKRrGo2GR48eUapUKV2HIuLw+PFjunXrhr29Pb/88gslSpTg4sWL3Lp1i/bt22NgYKDrEEUi6Ny5MyqVCpVKhYGBATly5GDYsGGEhHxeL9zR0ZE3b95QsGBBHUeauNL0o+mIcA0KYGAga4iKmD158oTQ0FBKly6t61DEfyiKwuHDh5k6dSqnT5/GwsKCvn37MmTIELJmzarr8EQSqVOnDitXriQ8PJxr167RqVMnVCoV06dPR09PD3t7+yStPywsDEPD5B01kSZbxKEh4Sz77Tw/tttErzYb+WPWaT59DP36iSLduXbtGgDFihXTcSTii6CgIBYuXEjOnDmpU6cOr1+/ZtGiRXh7ezNr1ixJwmmckZER9vb2ODo60qRJE2rUqMGRI0eAqI+mtVotDg4OLFq0KMr5N27cQK1W8/z5cwD8/Pzo3r07mTJlwtLSkmrVqnHr1q3I48ePH0/RokVZtmwZOXLkwNjYOPlu9v/SZCJeu/QKZ449JTxci0ajcOnsc5YuOK/rsEQKdP78eTJlykSGDBm+frBIUi9fvmTAgAHY29szYMAAcufOzbFjx3j06BG9evXSyQek0K27d+9y/vz5GFuoarWatm3bsmHDhijl69evp3z58jg5OQHQsmVLfHx8OHDgANeuXaN48eJUr16d9+/fR57z5MkTtm3bxvbt23Xy/jnNPZoOD9dw4ZR7tPJbV18R4B+CpZX8MYt/XL9+nQIFCug6jHRLURTOnTvHlClTOHToEMbGxnTo0IHhw4eTI0cOXYcndGDv3r2Ym5sTERFBaGgoarWahQsXxnhs+/btmT17Ni9evCB79uxotVo2bdrE6NGjATh79iyXL1/Gx8cHI6PPE/fMmjWLnTt3snXrVnr27Al8fhy9Zs0aMmXKlDw3+R+pLhF7vvRn6/obPH34jiwOljRuVZh8hexRFIXbt2+zauUawsILoVZFfS+sKJ//6IX4QlEU/v77b3r06KHrUNKdsLAwNmzYwIwZM7h//z4ODg7MnDmTHj16YGFhoevwhA5VrVqVRYsWERgYyNy5c9HX16d58+YxHlu0aFHy5cvHhg0bGDFiBKdOncLHx4eWLVsCcOvWLT59+hTtiVdwcDBPnz6N/NnJyUlnSRhSWSL+9DGUKaMP8dH/8/tevw/BPPr7KGb2f7Nz91pevXqFubk5jWqORq2N+h7JKoMGK2sTXYQtUihPT0/8/f0pV66crkNJN3x8fJg3bx5Llizh/fv3lCtXjt27d1O/fn3U6jT5pkwkkJmZWeQ0pCtWrKBIkSIsX76cbt26xXh8+/btIxPxhg0bqFOnTmTi/fTpE1myZOHkyZPRzrO2to5Spy6lqt/8i2c8IpPwFxqNwo1LPpQtW5Z9+/bh6+vLktWDKFoiW+Ra8IqeL8s3DGHz5s06iFqkNIpWy8Ol+zjReCy9KYhTkNHXT0qFwjQR3PZ9xd33r4nQanQay/Xr12nRogXZsmVj9uzZ1KtXj3v37nHu3DkaNmwoSVjESK1WM2rUKEaPHk1wcHCMx7Rr1467d+9y7do1tm7dSvv2/6wlXrx4cby8vNDX1yd37txRtpQ05jxVtYgDY+n53KbVD/QbViXyZ0NDGDy6GgH+IWi1ChaWhvg1PU779u2xtLSkbt26yRSxSIku9vuNB4t3A1BSlZlbHedgrW9CztZVdRxZ4vH4+I7F90/xKfzz34y1oQl98lclq5l1ssWg0WjYvn0706ZN4/r162TOnJkxY8bQr18/bG1tky0Okbq1bNmSn3/+md9//50WLVpE2+/s7Ey5cuXo1q0bGo2GRo0aRe6rUaMGZcuWpUmTJsyYMYM8efLg6enJvn37aNq0KSVKlEjOW4lVqvoaWrRkzEvTFSuVPcZySytjrG1M0NPTY9u2bVSqVIkmTZpw+vTppAxTpGBBXu95uHRv1EJF4dbk9boJKImse3wpMgkD+IUFs+np5WSp28/Pj8mTJ5MtWzZatWqFVqtl48aNvH79mrFjx0oSFgmir69Pv379mDFjBoGBgTEe0759e27dukXTpk0xMfnnFaRKpWL//v1UqlSJLl26kCdPHtq0acPz58+xs7NLrlv4KpWSynow7d95j+3rbxIerkWlVlG5Rm469y4dr3VFg4ODqVKlCnfv3uXMmTMUL148GSIWKcnbyw/YW6ZvtHJ9U2M6fNqng4gS34fQIMZc3RnjvlmlW2KsnzSzUD18+JCpU6eyefNmwsPDadSoEaNGjUoxrQ4hUqpU9WgaoF6TAlSomovnz95jn9WCTHbx72FpYmLC0aNHKVeuHFWrVuXChQvkz58/CaMVKY1NoRwYWpsT5vcpSrldpUI6iijxmeobYKDWI/w/74VN9Aww0EvcWea0Wi0HDx5k6tSpnD17FmtrawYMGMDgwYOTfAYkIdKKVPVo+gtLK2MKFcuaoCT8hYWFBadOnSJTpkxUrlwZd/foY45F2qVvYkTZ3wei0v8nIRlntqbkzB91GFXiMtIzIL919NmnjPUN0FMlzp/8p0+fmDdvHjlz5qR+/fr4+PiwbNkyvLy8mD59uiRhIRIgVSbi72Vra8uZM2cwMjKiYsWKvHnzRtchiWSUs201Wjxdh0f5zGyzfkOLJ+uwKeCs67ASVYgmLFrZh9AgngW8/a7rPn/+nL59+2Jvb8+QIUPImzcvp06d4sGDB3Tr1i1y0gQhRPyly0QMkCVLFs6cOUNoaCgVKlTA19dX1yGJZGTumBmD2gU4HuKBgXnaG18eEB4SY7lfWFCCr6UoCqdOnaJ27drkyJGD1atX07lzZ9zd3Tl48CCVKlWKVx8NIUTM0m0iBsiRIwenT5/G19eXypUr8/HjR12HJJKRo6MjwcHBsY5PTM1craL3CNVTqcltmTne1wgNDWXZsmXkzZuXKlWq8PDhQ+bOnYu3tzcLFy6MnMtXiNTg5MmTqFQq/Pz8dB1KNOk6EQPky5eP48eP4+7uTvXq1dPkh7KI2ZdVfLy9vXUcSeKK0Gow1jPE4F/vg9UqFS1zumFp+E/rPzgijEOv7vHn/dPs8riJX+jn1rKXlxfDhg3D3t6eHj16YGdnx/79+3n27BkDBw7U+SxEIvX59zrD/96ePHmSJPVVqVKFQYMGRSkrV64cb968wcrKKknq/B6prtd0UihevDgHDhygVq1a1K9fn4MHDyb7epQi+X0ZR+jt7Y2zs7Nug0lEax5d4LrviyhlLXOUoIK9S+TP4VoNc+8cxTPIL7Ls3OuHPP1jB7s2b8XAwIA2bdowYsQIXF1dkyt0kYZ9WWf43/47v3NSrgVsaGiYYjsRpvsW8ReVKlVix44dnDlzhhYtWqDR6HZKQJH0viRiLy8vHUeSeN4Gf4yWhAH2/H2JNWvWsH79ejZv3szi/VujJGGAIDT4ZTJm4sSJvHnzhpUrV0oSFonmyzrD/96qV69Ov379GDRoEBkzZqR27doAzJkzh0KFCmFmZoajoyN9+vTh06eoQw7PnTtHlSpVMDU1xcbGhtq1a/Phwwc6d+7MqVOnmD9/fmTL28PDI8ZH09u2baNAgQIYGRnh7OzM7Nmzo9Th7OzMlClT6Nq1KxYWFmTPnp0///wz0f9tJBH/S926dVm/fj179+6lY8eOslpTGpcxY0bUajWvX7/WdSjfJCwsjLt377Jx40aGDh1KzZo1qdWkYYzH+gZ/olOnTvzwww+0adOG9bu3xXhcux+7MWrUqCgT4guRlFavXo2hoSHnzp1j8eLFwOc5phcsWMC9e/dYvXo1x48fZ9iwYZHn3Lx5k+rVq5M/f34uXLjA2bNnadiwIRqNhvnz51O2bFl69OjBmzdvePPmDY6OjtHqvXbtGq1ataJNmzbcuXOH8ePHM2bMGFatWhXluNmzZ1OiRAlu3LhBnz596N27Nw8fPkzUfwN5NP0frVq1wt/fn549e2Jtbc3ChQulR2gapaenh6WlJa9evdJ1KHEKDw/n8ePH3Llzh2vXrnHr1i0ePnzIq1evIp/c2NjY4OLiQvGihVFrFLR6UX9ny+UqwO/BwWg0GrRaLX/7vWHti6vR6rp19CwhziUxNpZ1u0Xi+rLO8Bdf5vx3cXFhxowZUY799/tdZ2dnfv31V3788Uf++OMPAGbMmEGJEiUifwairCtuaGiIqalpnI+i58yZQ/Xq1RkzZgwAefLk4e+//2bmzJl07tw58rh69erRp08fAIYPH87cuXM5ceJEoj4tkkQcgx49ehAQEMBPP/2EtbU1kydP1nVIIonY2tqmmBZxREQET58+5fbt21y/fp2bN2/y8OFDXr58SUREBPB56bbcuXNTtWpVihcvTtGiRSlQoECU+ZuvvX3O2scXiFC0AGQ0NqdpjuJRkmtJc3PuBHpz0/dlZJnehyD+HPErO2csYt26dVSqVCmZ7lykB1/WGf7CzMyMtm3b4ubmFu3Yo0ePMnXqVB48eEBAQAARERGEhIQQFBSEqakpN2/ejFxz+Fvdv3+fxo0bRykrX7488+bNQ6PRoPf/WegKFy4cuV+lUmFvb4+Pj8931f1fkohjMXToUD58+MDkyZOxtLRk+PDhug5JJIFMmTIl+ztijUbDs2fPIpduu3XrFvfv3+f58+eRCdfS0pJcuXJRoUIFihcvTrFixShQoEC8lm5zy+SEi1Vm/vZ7g6meIQVssqL3n2UG1SoV3Vwr8MDPi+effLEzsaRwBgd6XipLu3btqFKlCl26dGHevHlYWCR8Bjsh/uvf6wz/t/zfPDw8aNCgAb1792by5MnY2tpy9uxZunXrRlhYGKamplEWdkhqBgZR52ZXqVRotdpErUMScRwmTZqEv78/I0aMwNraml69euk6JJHI7OzsePEieuem//K7/xz/hy/JWNIVs2yZvno8fJ6H2d3dPcaEGxb2eeYrc3NzcuXKRenSpendu3dkws2cOfN3vRKxNDShTOaccR6jUqnIZ5OFfDZZIssKFCjA9evXmT17NmPHjmXv3r2sXLmSevXqfXMsQiTEtWvX0Gq1zJ49O3Kd6i1btkQ5pnDhwhw7dowJEybEeA1DQ8OvdrjNly8f586di1J27tw58uTJE9kaTi6SiOOgUqlYsGAB/v7+9O7dG0tLS9q2bavrsEQisre358aNG7Hu12o0nOk8nWfrjwGg0tej6NiOFB39wz/HaLW8ePEiMuHevHmT+/fv4+7uHplwTU1NyZUrF25ubnTv3p3ixYtToEAB7O3tU1wfBD09PYYNG0bLli1p37499evXp0WLFixZskSWMBRJLnfu3ISHh/Pbb7/RsGHDKJ24vhg5ciSFChWiT58+/PjjjxgaGnLixAlatmxJxowZcXZ25tKlS3h4eGBubh7j7+3QoUMpWbIkkyZNonXr1ly4cIGFCxdGee+cXCQRf4VKpWLlypV8/PiRDh06YGFhQYMGDXQdlkgEXmduU/TQWwq/ysGB6kNxm9yNzGWirsb1ZPXhyCQMoERouDF2JYff3OWy9xP+/vtv3N3dCQn5PKWkiYkJOXPmpHDhwnTq1IlixYpRsGBBsmXLluIS7tfkyJGDc+fOsWTJEn766Sdy587NokWLaN26ta5DE2lYkSJFmDNnDtOnT2fkyJFUqlSJqVOn0rFjx8hj8uTJw+HDhxk1ahSlSpXCxMSE0qVLRzaUfvrpJzp16kT+/PkJDg6OcXGf4sWLs2XLFsaOHcukSZPIkiULEydOjNJRK7mkuvWIdSU8PJy6dety5swZDh06RJUqVXQdkvgO/o9esqtoTzQh/yyOoG9mTOM7ywnQj+DJkyc8fPiQwFkHsXkaEO383XrPeehiSL58+SLf4RYsWBBHR8dUl3Djw9PTk06dOnH06NHIiRlS6uQIQqQ2kogTICQkhCpVqnD79m1OnTpFyZIldR2S+EZXRy7jzvSN0cp3q5+zU/MU+Pw0pLtJEcoGR3+sVXbxYPL2TF9PRhRFYdOmTfTp04eIiAjmzJlD9+7d0+QXDyGSk0zokQDGxsYcOXKE3LlzU716de7du6frkMQ3CvP7FGN5jXKV2LNnD/fv3yc4OJjpl7ajZxx1yr0PhLL/Xfr7/16lUtG2bVuePHlCzZo16dmzJxUrVsTDw0PXoQmRqkkiTiALCwtOnjyJnZ0dlStX5tmzZ7oOSXwDpyblYyxvPnkQDRo0IG/evBgZGWFTMAd1js3CoV5pLHJlJWf76jxv48rQX0YwcODARB/GkBpkyJCB7du3s3v3bh49ekS+fPmYPXt2uvy3ECJRKOKbvHnzRnFwcFCyZs2qvH79WtfhiG8wyLmq8qeqirJCVU1ZYVhTuTl5XbzPnTJligIoTZo0UUJCQpIwypTN399f6dSpkwIoRYsWVe7fv6/rkIT4ZqdOnVIaNGigZMmSRQGUHTt2fPWcEydOKMWKFVMMDQ2VXLlyKStXrkxwvdIi/kb29vacPXuW8PBwKlSowLt373QdkkiAvXv3Ms/jBEa/tWOqcg3VnOYUGdU+3uePHDmSdevWsXfvXipXroy/v38SRptyWVpasmrVKo4fP87bt28pXLgw48aNIzw8XNehCZFggYGBFClShN9//z1ex7u7u1O/fn2qVq3KzZs3GTRoEN27d+fQoUMJqzjh3xnEv92/f1+xsrJS8uXLp/j7++s6HBEPoaGhiqOjo1KqVClFq9Uq+vr6yuzZs7/pWsePH1fMzMyU3LlzKy9fvkzkSFOXoKAgpX///opKpVJcXV2Va9eu6TokIb4Z8WgRDxs2TClQoECUstatWyu1a9dOUF3SIv5OefPm5cSJEzx//pzq1asTFBSk65DEV8ycOZNXr16xdOlSVCoVZmZmfPjw4ZuuVbVqVS5dukRAQADFixfnzp07iRxt6mFiYsKCBQu4dOkSGo2GkiVLMmTIkMgx1kIktpCQEAICAuLc/P39o5WFhoYmSv0XLlygRo0aUcpq167NhQsXEnQdScSJoFixYhw6dIg7d+5Qr169yNmURMrj5eXF5MmT6dKlS+Rk7mZmZlHWKE2oAgUKcOPGDaytrSlTpgxHjx5NpGhTp5IlS3Lv3j1GjBjBggULcHV15cyZMyhaLS/3X+LGhDV4bD2FNkLW/BbfLiQkBHsTK6ys4t4cHByilU2dOjVRYvDy8opc1/wLOzs7AgICCA4Ojvd1ZGatRFKhQgV27dpFgwYNaNasGbt27Ur2+UrF1w0YMAADAwNmzpwZWWZubv7NLeIvsmbNytWrV6lbty5169Zl2bJldOrU6XvDTbUMDQ2ZPHkybdu2/byIROXKzHCsj+3Lf54YZS5XgNpHZqJvYqTDSEVqFRYWhj9hzDMoj0ksqSyYCAZ9OsfLly+xtLSMLDcySlm/c9IiTkS1a9dmw4YNHDhwgA4dOqDIXCkpyoULF/jrr7+YNGlSlLlnLSwsEqWzlaWlJSdOnKBJkyZ07tyZSZMmpfvfgYIFC3Ljxg1m/TA4ShIG8Dl/j8crD+ooMpFWmKoNMNOLeTNVf145ydLSMsqWWInY3t4eb2/vKGXe3t5YWlomaIUoScSJrGXLlvz5559s3LiR3r17p/sP4pRCq9XSo0cPXFxc6Nu3b5R9FhYWBAREn8byWxgaGrJlyxaGDBnC2LFj6dGjx1dXgUnr9PT0qJAl5kXU3178O5mjEWmNgYEqzi0plS1blmPHjkUpO3LkCGXLlk3QdeTRdBLo1q0bAQEBDBkyBGtra6ZNm6brkNK95cuXc+/ePU6ePBntlYGlpWW8lkKML5VKxezZs3FycmLQoEG8evWKHTt2JOsaqimNlatjjOWPP/pQUVFkmkzxzdRqUMfy66NOYDvo06dPPHnyJPJnd3d3bt68ia2tLdmzZ2fkyJG8fv2aNWvWAPDjjz+ycOFChg0bRteuXTl+/Dhbtmxh3759CbuHhIUp4mvw4MGMHTuW6dOnSyLWMX9/f4YPH07Dhg2pXLlytP3W1tZ8+hTzlJffY8CAAWzdupUTJ05Qrlw5fH19E72O1CJnm6pYF8wRpSzIWMXgnb9Tvnz5KB9+QiSEWk8V55YQV69epVixYhQrVgyAIUOGUKxYMcaOHQvAmzdvonxpz5EjB/v27ePIkSMUKVKE2bNns2zZMmrXrp2gemXRhyQ2cOBAFixYwB9//EHv3r11HU661KdPH1asWMHjx49xdIzeMhs4cCBbtmzhzZs3SVL/hQsXqFOnDtbW1pw4cYKcOXMmST0pXajfJx4u2s3bqw+xye9M3r6NOX71PN27d+f9+/f88ssvjBo1CgMDA12HKlKBgIAArKys2JipOqbqmB/uBmkjaPv2GP7+/lE6a6U00iJOYvPmzaNTp0707duX9evX6zqcdOf+/fv8+eef/PTTTzEmYQAbGxsCAwOTLIayZcty9epVNBoNJUqU4MqVK0lWV0pmZG1O4ZHtqL5tAsUndcHU3pYGDRrw9OlTunfvzoQJE8ifPz8XL17UdagiFdFTx72lBqkkzNRLpVKxYsUKmjRpQqdOndi9e7euQ0o3FEWhZ8+eZM6cmdGjR8d6nK2tLUFBQUnasc7FxYXr16+TLVs2KlWqxN69e5OsrtTGzMyMP/74gytXrqCvr0+5cuXo0aMHHz9+1HVosfr00odzveawo3B3jrccz7vrj3QdUrqlZ6BCP5ZNL4k7ayUWScTJQK1Ws3nzZqpWrUqLFi04fvy4rkNKF3bu3MnZs2dZsGABxsbGsR5nY2ODRqNJ0AD8b5E5c2YuXrxI2bJlady4MYsWLUrS+lIbNzc37ty5w+TJk1m7di25cuVix44dug4rmvBPwRyoNIhHS/fhd9ed59vOcKDSYPzuP9d1aOmSWg1qtSqWTdfRxU8qCTP1MzAwYM+ePZQoUYIGDRpw+fJlXYeUpoWGhtK/f3/KlStH8+bN4zzWxsYGINGGMMXFzMyMw4cP0759e/r06cOIESNkiNu/6OvrM3LkSB48eEDevHlp1qwZ9erVS7L399/CfctJPj2POnY0IiiEB3/I0y5d+JyIY99Sg1QSZtpgbGzM4cOHcXFxoUaNGty9e1fXIaVY/n7B3Lr2Gh+vb3s8OXXqVLy8vCLnk47Ll04cyZGI4XOyWb16NWPGjGH69Om0b99eViv6D2dnZ06dOsWaNWu4cOECuXPn5rfffksRax4Hecbc+z3oTfrtFa9LBvpxjCPWl0fTIgbm5uacPHkSe3t7KleuzNOnT3UdUoqzb/tdBnffzpxJxxnWeyeL557l4K6/2bvtLl6eX0+Wr1+/Zvr06XTr1o38+fN/9fgviTg5lzJUqVRMnDiRpUuXsmXLFmrWrJkkQ6hSM5VKRYcOHXj69CmNGjViwIABuLm5ce/ePZ3Gla12iZjLa8VcLpJWYg5f0hVJxDpgY2PDmTNnMDU1pUKFCrx+/VrXIaUYHk992bLmBpqIzy0fRYELp9zZuPIaf629wch+u7lwyj3Oa/Tv3x8jIyOmT58erzqtrKyA5GsR/1v37t3Zu3cvly9fplSpUtGmyxOfO9Nt3LiRo0eP4uvrS5EiRRg2bJjOVnXKWMKVu86g5Z9XCtmblMelSx2dxJPeyaNp8c3s7Ow4d+4cGo2GChUq8PbtW12HlCLcvBr3lxKtVmH9iiuEh0edNtI/LJjr716w88xRduzYwdSpU7G2to5Xncn9aPq/6tSpw7lz5/D29qZYsWI8fPhQJ3GkdNWrV+fRo0cMHjyYOXPm4OrqGqXjY6jfJz66J/275A0bNjDH/Thm89tRef0vNLyyiOrbJ6I2kIkKdUF6TYvvkj17ds6cOYOfnx+VKlVK1kejKZW5xdcnY//oH8rO7Ycj134+6fmQsVd3seLhWY6qfWi7ZBJduneLd51fEvH79++/LehEUKxYMa5fv46RkRElS5bk3LlzOoslJTM2NmbmzJncvHkTGxsbqlevTvs2bTnZbQab7FuwNdcPbM/fhbeX7idJ/b6+vvTt25c6derQpn93cratRka3PElSl4if2HtMf95SA0nEOubq6sqJEyd4+fIltWs2YuUf55k88hBr/ryM79ukm2QipSpT0RlLq9iHGgFEaEJp/0MzrKysKFOjClufXUWj/NOJx7ZATk55PY53nQYGBhgaGuo0EQM4OTlx/fp18uTJQ9WqVfnrr790Gk9KVrBgQa5fv878+fMJ3H4V95WH0IZ97vDm/+AFRxuPJiIk8dcF79mzJxqNhpUrVyb6tcW3kc5aIlEULVqUXTv242jbnJOHn/Lovg/H9j9k4rADBPjr5j2YrphbGDHy11q88/8bLcFky24V7ZiW7Uty4+ZVZsyYQfaShSCGXtGnHt3Cw8Mj3kODzMzMvntN4sRgY2PD2bNnqVWrFq1bt2bOnDm6DinFUqvVDBgwgPYu5aPtC/Hx482x64la3549e9i+fTtz587F3t4+Ua8tvp28IxaJJvRTBkyNbaKU+X0I5syx9DcZvqFJOPtPTqNaYwOmLGhEi07OPHl+mtz5zRk4sgpN2hShQIECDB48mNE/DY/xGtfPXyRHjhxkyJCB6tWrM378eI4fPx6tZ7ImOIQnE/9gs31pau69w9NfF6EJCU2O24yVsbExu3fvpmfPngwdOpSBAwemiGE7KZWRaSyrWiXi/IYBAQF069aN8uXL061b/F97iKSXFnpNS++CFOJdLI+hv3UcbWp24sQJAGrUqAHAyzd3uHBrOUfOzcfU1DTKsQVss2JvYolX8D8drdQqFVM69adv0ZqcOHGCc+fOMWPGDCZMmIBKpSJnzpyUKlWKqlWrUvTGK0JPXcNEpQcahTcb96EJCSXPr4OS7X5jolarWbx4MU5OTvzyyy+8eP6cKQ178HrPRQwsTHDt2QD7ioV1GmNK4dKlDr7Xok4x+VYJpvGIXqx32kC+fPm+u44BAwbw8eNH1q1bJ0s2pjB6+gp6+jE/+dIjdUyWIy3iFCJfQbsYyxcvm8q+ffvS1exL+/fvJ2vWrJGLNFy4cAFnZ+doSRhAT6VmQMHqhNzx4JPnW/JbZ6FfgWoUz+5Cw4YNmTNnDpcuXeLjx4/cuXOH33//HTc3Ny5evMig3n34dDL6Agxv955EE5wyXgmMHDmSdevWYb7nARd7zOHl7vM8W3+Mg1WH8nzHWV2HlyLczhDCDuUZmBkCYF+1KEVWDeat7zsKFy7M6NGjv2vClBMnTrB69Wp+/fVXnJ2dEylqkVhU6ri31ECWQUwhtFqFYf3W8Nbzn9+cnK7m7D46mevXr1G6dOnIJJLW5cyZk5IlS7J582YAChQogKurK9u3b4/1HFdXVwoXLpygDk7vX3ryd52e0cq1isK2Co606NCecuXKoaenl/CbSERBXu/Z7NgaNFEfT9sWyUXjG3/qKKqU4e3bt7i4uFC6dGkO7N+PNlyDvvHnhBwcHMyIESNYuHAhOXPmZMOGDZQsWTJB1w8ODiZPnjxkzJiRa9euoU4tLx3TgS/LIF6vVgdz/ZiXzvwUEU7x4wdlGUQRP1qths17RuMTuI+OPUvxy9TajJvelKtXr7Bjxw68vb0pUaIETZo0wcPDQ9fhJhkfHx/c3d2pX78+AOHh4Tx+/JgyZcrEek5ISAhPnz6lYsWKCarL1jErVmWKRCt/ZaHPmr82U6lSJTJkyEDr1q3ZtWtXki8KEZvA597RkjBAwOP0PRGMoih07NgRRVFYu3Ytaj29yCQMYGJiwvz587ly5Qp6enqULl2aPn36RA57i4/hw4fj7e3Nhg0bJAmnUCq1gjqWTaVOHe1M+c1KIdasWcOrV6+YPH0Y1eu5kidfZuDzNH9NmjTh8ePHLFy4kDNnzuDi4kLv3r11PtwmKXx5P1y9enUAHjx4QHh4OGXLlo31nFu3bqHRaOI8JjZ5fh2ERWHXyJ+fqUJpvns5vr6+nDt3jg4dOnDhwgWaNGmCjY0NNWvWZPnyz/uTi3VBZwytzKKV21UslGwxpETr1q3j4MGDLF68mMyZM8d6XPHixbl79y7jxo1j2bJluLi4cOTIka9e/8qVKyxcuJCRI0cmyntmkTRUqjgeTaeW1/mK0Lnw8HDFwcFBqV69+leP/fTpkzJq1CjF2NhYMTMzUyZNmqQEBwcnQ5TJo2PHjoqDg0Pkz8uWLVMAJSAgINZzZs+erejr6yshISHfXG+Qxytl++LlCqBcvXo12v779+8r48ePVwoWLKgAikqlUtzc3JTp06crz549++Z64+vRqoPKSv0aygpVNWWFqpqyPlNTxff20ySvN6V68+aNYmFhoTRo0CBB5z18+FApUaKEAiht2rRR3r9/H+NxYWFhSu7cuZU8efIoYWFhiRGySGT+/v4KoNyuW0txb1Q/xu123VoKoPj7++s63DhJIk4BviSba9euxfscLy8vpVOnToparVYyZ86sLF++XNFoNEkYZfJwcnJS2rZtG/lz165dFUdHxzjPadq0qZIvX77vrjs8PFzJnDmz0qJFiziP8/T0VBYuXKhUrFhR0dfXVwAld+7cytChQ5Vr164pWq32u2OJScDT18q8+r2UavrZlZAPsX8xSeu0Wq1SrVo1xcbGRnn37l2Cz9doNMpvv/2mmJqaKjY2NsrmzZsj9/k9eqm8vfJA+WXkKEWtVifob1Ikry+J+G79WsrzJvVj3O7WTx2JWB5N61hERATjxo2jRo0aFC9ePN7n2dnZsWrVKu7du0fRokXp1q0b+fLl4+DBg0kYbdLy9vbm+fPn1KtXL7Ls2rVrFCoU9yPY69evJ0onNn19fXr37s2uXbvinPs7S5Ys9O3bl9OnT/P+/Xs2bdpE/vz5Wbx4MW5ubtjZ2dGlSxeOHDmSqMsbWuTMikOXmhyPeMHHCN2OddalFStWcPz4cZYuXUqGDBkSfL5araZfv348evQINzc3WrduTcPqtdlddRDbXTuxp1QfrKedZETLbgn6mxS6oVIpcW6pgSRiHVu9enXksn3fIm/evBw6dIgzZ85gYmJC3bp1KV++PDdu3EjkSJPelwn8v7wf1mq1PHz4MM6OWh8/fuTFixcJ7qgVm379+gHw+++/x+t4CwuLyM5cHz584MiRIzRo0IB9+/ZRq1YtbGxsaNSoEZs2beLjx+8fE/5l+Exa7rAXl1evXjFgwACaNWtG8+bNv+ta2bJl4/Dhw2zYsAG7c2/wPXUncl8GjCl8zh9thCaOK4iUQK2vxLmlBpKIdehbW8MxqVChAjdu3OCvv/7i5cuXuLm50bx5c54/f55I0Sa9/fv3kz17drJkyQLA48ePCQkJibMT1vXr11EU5Zs6asUkY8aMNGnShEWLFhEREZGgcw0MDKhRowYrVqzA29ub69ev06dPH+7fv0/btm2xtbWlYsWKLFy4kDdvvm2VoC+J2N097qUg0yJFUWjbti0mJiYsW7YsUa6pUqlo27Yt1axyR9sX9Podby8/SJR6RNJJC+OIU0mYadOqVat4/fo1M2bMSJTrqVQqWrRowdOnT5k3bx7Hjx/HxcWF/v37p4h5lGOj1So8vOfN7esvqVihUmT51atXAeL8knL27FmMjIwStVfriBEj8PHxYceOHd98DZVKRbFixZgxYwaPHz/m2bNnTJ48mZCQEAYOHEjWrFkpWLAg48aN4/79+/GesMXW1hYTExMeP47/ohZpxaJFizh79iyrVq3Cxsbm6yckgKGVeczlltEnkREpi57+P7NrRd90HV38SCLWkYiICMaPH0/NmjUpVqxYol7bwMCAAQMG8OLFCwYPHsyyZcvInj07U6dOJTQ0Zb1b9H7zkZH9djPll8MUdemGmVKL58/eExGh5fSpy2Sxz4qtrW2s5587d468efOir594f3HFixenSJEiifYFCSBHjhwMGzaMK1eu4OPjw/Lly8maNSvTp08nf/78ZM+enb59+3L27Fk0mtgfh6pUKuzt7dNdIn7+/Dk//fQTbdq0oUGDBol+/bw/NoxWZlexEDYFcyR6XSJxqYjjHbFMcSnisnLlykRtDcfEwsKC6dOn8+zZM5o0acLo0aNxdnZm9erVKWYRgVWLLuLl+c880SFBMHfyCYZ030aITwmqlRzLuZPPYj3/5s2bCZ4tKT5+/vlnrl69yu3btxP92hkyZKBr164cPnyYDx8+sGvXLsqVK8eGDRuoWLEiGTNmpE2bNuzevTvaJCKakFAaZMiB861X+J66mi6mPtVqtbRu3RoLCwuWLFmSJHUUGNyCEjN6Ye5sj6GVGbk71aLatglJUpdIXGnh0bRMcZmM3r8L5ODu+7z0eM/+Q5sxtX7HgUO7kq3++/fvM2DAAI4ePUrevHlZsGABNWvWRKtVuH39NT5vPuKSLzM5cie8J2pcAgMD8fb2xtvbGy8vL16/fs2rV6/wfO2F6mP1r56vUquYOLse2XP80zL+GBDCqaP3GTx4MCPHdqNrtw6JGnN4eDj29vbUrVuXdevWJeq1Y6PRaLhw4QIbN25k9+7dvHr1CiMjIypVqkSbNm2oX7UGz/tNI/DxP+/9M9etSIH5I5IlPl2ZM2cOQ4cO5dChQ9SqVUvX4YgU4ssUl+4/VMPSMOYnYgFhEeRYdzzFT3EpiTiZBPgFM2bwPvw+/NPCsbQ2YMYfzTAxNYzjzMR3+vRp+vXrx507d6hUsSplC/flzat/pv2rXs+Vjj1LxXq+oih8+vQp5uTq6YmXlxdv377l3bt3fPjwIVqrTq1WY2Vlha1tBsrkH46e2uirMZermpWeA6qhUqm4f8eLuZNPEBryuTOVoaGaoWNrkDeWhTO+1ahRo5gzZw5v3rxJ9HeSX6MoCg8ePGDTpk1s27aNe/fu0TGDC51tXaIdW3TNFGximKozLXjy5AkFCxakbdu2rFy5UtfhiBTkSyL26Fg1zkTsvOZEghLx77//zsyZM/Hy8qJIkSL89ttvlCoV++fhvHnzWLRoES9evCBjxoy0aNGCqVOnYmxsHO97kUScTHb/dYdt629GK+/QsxQ16rlGPyGJKYrCli1bWDBzF7kd6kbbX762IZ+CX/P69esoydXX15f3798TFhYW5Xi1Wo21tTUZMmQgU6ZM2NnZkTVrVrJly4aDgwNZsmTBzs4OOzs7MmTIELmQwtZ1N9iz9e5X473zaA+PXuwnX758FMjeHUUTtRNNtuxWTFnQ6Dv+RaLz8vLCwcGBSZMmMXLkyES9dkJ5enpytfMoLDyij2/OObQTTr1a6SCqpKXVailZsiReXl48fPgQc/OYO1SJ9OlLIn7RpUqciTj7ypPxTsSbN2+mY8eOLF68mNKlSzNv3jz++usvHj58GOM0qhs2bKBr166sWLGCcuXK8ejRIzp37kybNm2YM2dOvO8llfQpS/3exrKusPe/3o8mJ5VKRevWrXnxIAN3b0QfSrNgzhoeehyOTK6ZM2cmX758ZMmSJcbkamtr+02T4jdrVxRTM0POHHuKRqMlXyF7Th55zL/7WKjVKob90oF7D1y5evl2tCQM8PqFPx8DQrCwjP+30K+xt7enQYMGLFy4kGHDhul0FaasWbOSv1oFXq6I3pP79+2b+LFmCXLmzKmDyJLO9OnTuXHjBseOHZMkLGKlVn/eYtuXEHPmzKFHjx506dIFgMWLF7Nv3z5WrFjBiBHRXwGdP3+e8uXL065dO+Dz8MK2bdty6dKlBNUriTiZ5Mlvx+ljT6OVL1g0EUu7njRo0EAnC47bZbGMMRG3adeYUeP2JPmKM2q1inpNC1CvaYHIsnyF7Niy5ga+bwPJZGdO607FKVnOCWhIRLiG/p23EhQYtUVuZmGYJI/4R4wYQdmyZdm7dy+NGzdO9OsnhEPnJnjvOUnY23+Gon2ys2Ll1UPMdnGhVatWTJs2DScnJ90FmUgePHjAuHHj6NGjB1WrVtV1OCIFU8WxytKX8oCAqA0eIyMjjIyivhILCwvj2rVrUZ5+qdVqatSowYULF2K8frly5Vi3bh2XL1+mVKlSPHv2jP3799OhQ8L6rKSSPmWpX9nKOShULGuUshwupkTgSaNGjShRogRnzyb/Qu+1GuTF1DTqWp7h2g+MndSH4sWLc/ny5WSPqUzFHMxa0pQ/1rVi5uIm/0/Cn+kb6FG/WYFo5zRoVhB9/cT/dS5Tpgz58+dP0t7t8WVsn5ES2+fj1KcNmetVwmV0L+odXsGLV6/49ddfOXDgALly5aJjx468fPkyyrmh7z4Q9t5fR5EnjEajoVWrVtjZ2TF37lxdhyNSOJW+CpVBLJv+58aNo6MjVlZWkdvUqVOjXefdu3doNBrs7KL2NbGzs8PLyyvGutu1a8fEiROpUKECBgYG5MqViypVqjBq1KiE3YROZrhOp7RarXL3pqdyYOc95f4dr8iyPXv2KC4uLgqgVKtWTbl9+3ayxuX5yk9Z8fsFZdrow8q2DTeVTx9DlCNHjii5cuVSAKVly5aKp6dnssb0NY3q9lAaVh+jzPn1uHL5nEeS1rVixQoFUB48eJCk9XyvT58+KRMmTFAsLS0VfX19pUuXLorHzbvKtfYjlKM56ypHc9VTbvacoIT5pewFI8aPH6+oVCrl7Nmzug5FpGBfFn1407eqEjikZozbm75VFUB5+fKl4u/vH7nFtFLb69evFUA5f/58lPKff/5ZKVWqVIwxnDhxQrGzs1OWLl2q3L59W9m+fbvi6OioTJw4MUH3Iok4hdBoNMqaNWuUrFmzKiqVSmnWrJni7u6u05jCw8OV+fPnK5aWloqxsbEybty4FLHkYmBgoGJkZKSMHTs2WeoLCQlRrKyslC5duiRLfd8rICBAGTNmjGJubq7Mzlr6cxL+13ZnwDRdhxirO3fuKPr6+kr//v11HYpI4SIT8YDqSuDPtWPc3gyoHu/Vl0JDQxU9PT1lx44dUco7duyoNGrUKMZzKlSooPz0009RytauXauYmJgkaDU8eTSdQqjVajp06IC7uztz587l5MmT5M6dm+7du+Pt7a2TmPT19RkwYAAeHh507NiRX3/9lZw5c/LXX39FTiTx6L4PZ48/xfvN9y9oEF8HDhwgNDSU9u3bJ0t9RkZGdOvWjY0bN0Z715QSWVhYMHHiRJ7duEMR4+izkvkcPIs2LPFWhUos4eHhtGrVCkdHxxTxKkCkDp8fQ6tj2eLf78bQ0BA3NzeOHTsWWabVajl27Fisc9kHBQVF60fzpVOnkoABSZKIUxhDQ0MGDhzIixcv+OWXX9i0aRPOzs78/PPPOksCNjY2LFmyhNu3b5MrVy5atWpF2TLlGTNkB5NHHmLpgvMM77OT7RtvJUs8a9asIVeuXOTJkydZ6gMYPHgwYWFhibbYQHKwtLaCGDoAavncKd337HUeTljMs/nrCH6tmy97/zZ+/HgePnzIpk2bEjQGU6RzalXcWwIMGTKEpUuXsnr1au7fv0/v3r0JDAyM7EXdsWPHKJ25GjZsyKJFi9i0aRPu7u4cOXKEMWPG0LBhwwSNspBxxCnc+/fvGTduHH/++SfGxsaMGDGCwYMH6+yDSlEU9uzZw/SJG8ntUC/a/knzGpDdOekmvwgNDcXW1pb+/fszbdq0JKsnJvXq1ePevXu4u7sneW/yxHKz2zh8T16JUnYg4CUW2eyp8PGfTnp65iYUXzsVy8LJ9+Xm327cuEHJkiUZNGgQs2bN0kkMInX5Mo7Ye2RtLI0NYj4mJBy7qYcSNKHHwoULIyf0KFq0KAsWLKB06dIAVKlSBWdnZ1atWgV8XjNg8uTJrF27ltevX5MpUyYaNmzI5MmTsba2jve9SCJOJV6/fs3w4cPZuHEjGTJk4Ndff6Vr166JuthBQswcf4S7N6P3JGzT2Y26TfInWb179uyhUaNG3Llzh4IFCyZZPTE5ffo0zavXYuOoXylSqiS21UqjZ5KyW27hHwJ4MHYhbw9fQKVWY9eoCvdzWGE+4y/0/9NazlDJjaIrJyV7jGFhYRQo8Lkn/L179zA0TN6Z5kTqFJmIR9eNOxH/eiDFT3GZOr7WC7Jly8a6deu4f/8+JUuWpFevXri4uER5X5ucbDPGPMHC+YvHo826lZjWrl2Lo6Nj5Ad3csr7UeEvl+oYbz3Jw2EzuVavJ0Hur5I9joQwsLGk0G+jqHx7G5VvbiX/9MFUKVA0WhIG+HDnkQ4i/DyVqLu7O1u2bJEkLBJMpVbFuaUGkohTmTx58rBv3z6uXLlC1qxZadWqFYUKFYrSwSA51GqQF0PDqO9AtHxi6qwhODk5sWzZsjiX8/sW4eHhHDx4kGbNmiX75Cea4BCe/vpHlAQW5vMe95nLkzWOb6VnZIja6HOrwTyPEyr96O+vLr1+RsmSJVm/fn2SfpmKUuelS8ydO5fhw4cn+nKgIp0wVMe9pQKpI0oRTYkSJTh37hxHjhwBoEaNGpQvX56rV68mS/2OzjaMmlKbUuWdcMppS60GeVm4qjO3bt2gUKFC9OjRg9y5cydqi/3kyZN8/PiRjh07Jsr1EiLwoTuagMBo5QFXvj5PdkpjZJeB7N2aRSnTMzXGeWB7tFotP/zwA3Z2dgwePBgPD48kiyMkJIS2bdvi6urK+PHjk6wekbalhRaxvCNOAxRFYevWrfz88888f/6cevXqMWfOHFxdk38xiS8uX77MwIEDuXjxIgUKFGDOnDnfvYRdhw4dOHr0KJ6ensneIg71fseVGl3hP+s4m+ZxpviOhckaS2LxPXOdd8cuYWBtQZaWNTHJ9nlGob///pvZs2ezadMmgoODqVixIoMHD05wT9CvGTBgAIsWLeLGjRvJ/r5fpH5f3hG/ndEES5NY3hEHh5Np2E55RyySnkqlomXLljx58oQlS5Zw9epV8ufPzw8//MDr1691ElOpUqW4cOEChw8fBqB27dqUKVOGixcvftP1NBoNe/fupUmTJjqZk9vILiPG1UpGLVSpcOyZelc9ylCxOK7je5Nz0A+RSRggf/78LF++HB8fH/744w98fHxo2rQpWbNmZfTo0bx5E31u8oQ6d+4cCxcuZPTo0ZKExXdR6ani3FIDScRpiL6+Pj179uT58+f8+uuv7Nmzhxw5ctC/f3/ev3+vk5hq1qzJnTt32LZtGz4+PpQtW5aaNWty927CHumePXsWPz+/BE+mnlgURWHQlYMsDXyBecmCZKhRlgJLJpCpbiWdxJMczMzM+PHHH7l//z6XL1+matWqzJw5E0dHR+rWrcvRo0e/6bVDUFAQbdq0oWDBgowePToJIhfpSiKOI9YVScRpkLGxMSNHjuTFixcMHDiQZcuWkT17dsaNG0dgYPT3nElNpVLRrFkzHj9+zPLly7l37x6FCxemefPmuLu7x+saa9euJUOGDJQpUyaJo43ZmjVrOHfhPC0XTqHoqmnkm/8LNuWL6yQWXShZsiSbNm3C29ubadOm8eDBA2rWrImTkxNTp05N0Be9wYMH4+3tzZYtW3S6tKRIG2KfVevzlhqkjijFN7GysmLmzJl4eHjQpk0bJk+ejKOjI/Pnzyc8PPmnONTT06Nr1654eHgwZ84cTpw4gYuLC126dIl1dRP4PM3c7t27adSokU4m0nj//j2DBg2ifv36NGjQINnrT0msra356aefePbsGSdPnqRw4cKMGTMGe3t7mjdvzoULF+JsJZ84cYKlS5cyYcIE8ubNm4yRizRLTx33lgqkjijFd7Gzs2PZsmU8fvyYqlWrMnjwYJydnVm7di3a/3Q+Sg6GhoYMGjSIly9fMnr0aP766y+cnZ0ZPHgwHz58iHb85cuXefv2rU56SwP079+fsLAwli5dqpP6UyKVSkXlypXZu3cvnp6ejBo1ivPnz1OuXDlcXV357bff+Pjx8/zjHqv3capmX46W78amdkMoUbQYw4cP1/EdiLTi8zKIsbSI9VPHo2npNZ0O3b59m8GDB3P8+HFcXFyYM2cO9evX10knKAA/Pz8mTpzIH3/8gb6+PkOHDmXYsGG8eRnEgV1/c/3aPe4/PsfRM8sxN0/emaxOnz5N5cqVmTdvHgMHDkzWulMbrVbLwYMHmTVrFidPnsTIyIhfStSj8OOor0OsapWk8prkn8FLpC1fek2/X9EGS9OYJ4IJCArDtuumFN9rWhJxOnb27FkGDhzI9evXcXNzY968eVSoUEFn8Xh5eTF69GhWrVqFs0NRKhQbgKL88+Ugd95MjJ5aO9m+MISFhZE3b17Mzc25efNmqplfOiV4+fIlCxYsoOCaa9io/vMhqVZT68ZajO0y6CY4kSZEJuJVbeNOxJ03pvhELJ8s6ViFChW4evUqu3fvxt/fn4oVK1K9enXu3LkTeUxYmIYnD9/i+zbpO3nZ29uzbNkynjx5QuliraIkYYAnD97y4G7yrRL066+/8vz5c9auXStJOIEcHR2ZOXMmtgYm0XdqtYS9T75lM0XapjLQi3NLDeTTJZ1TqVQ0bNiQhw8fsnr1ah48eECRIkVo3rw5B3ZfZXC3bUwafpChPbezeO5ZIiKS/p2ys7MzuXLEPJf0+3dBSV4/wOPHj5k2bRp9+/alSJEiyVJnWpS5WoloZaaOdli4ZtdBNCJNkuFLIq1Qq9V07NgRd3d35syZw9kzl1i39CafPoYCoChw4ZQ7h/fcT5Z48he2jyFGFXkL2sVwdOJSFIXOnTuTIUMGpk6dmuT1pWWFJvfB3MUx8mdDWyuK/T4MlTxhEIlFrY57SwV0s4aeSLG+9GgunK82qxdFn7f66sUX1Gua9CsfNWhekGOHbhAWbASAomhp0cGNDJnMkrzuNWvWcP78efbs2YOZWdLXl5aZOtpR9dQSfC/eRRMcSsbyRdAzlhWWRCLS04MYFjGJ3JcKpI6vCyLZWdvEvMzh+/c+yTLkydBIxY4jIwk3vEy1+vZsP/ITEeqnSV6vjBlOfCq1mozlCmNXvaQkYZH40kCLOHVEKZJd4eLZyGQXPRlv37uAggULcvLkySStf926dfj6vmP0+N507F6DbI62zJ8/P0nrBBkzLESqo68X95YKSCIWMdLXVzN8Yg1KlMmOsYkBWR2t6DmwPOs2z0WtVlO1alVq167NkydPEr1uRVGYNm0aFStWJH/+/KhUKvr06cPJkyeTdBGLU6dOsWHDBqZMmUKWLFmSrB4hRCJSq+JoEaeOzloyjlgkmFarZc2aNQwbNoz379/To0cPpkyZgo2NTaJc/8iRI9SqVYvDhw9Ts2ZNAPz9/bGzs2Po0KFMnjw5Uer5t7CwMFxdXbGwsJAxw0KkAl/GEX/Y3wdLM6OYjwkMxabeHzKOWKQ9arWazp074+HhwciRI1m1ahVOTk7MmjUrUeawnjRpErlz56ZGjRqRZVZWVjRq1Ijly5ej0Wi+u47/mjhxIi9evJAxw0KkNvJoWqRnpqamTJo0CXd3dxo0aMCwYcPIlSsXO3fu/Kbl8eDzovRnzpxhxIgR0WbQ+rJqz6FDhxIj/EiPHz9mxowZMmZYiNRIOmsJ8XlGrA0bNnD9+nWyZctG06ZNKVu2LDdu3EjwtSZNmkSGDBliXHe4TJky5MyZk3nz5iVC1J8pikKnTp1kzLAQqZRKrYdKL5ZNLS1ikc4ULVqU8+fPs2vXLry8vHBzc6NNmza8efMmXud7e3uzbds2+vXrh6Fh9GEuXzptHT9+PM5lExNi9erVXLhwgaVLl8qYYSFSI2kRCxGVSqWiUaNGPH78mFmzZnHgwAFy5szJL7/8QlBQ3NNTzp49Gz09vThXOeratSt6enosXrz4u2OVMcNCpAEyxaUQMTMwMGDIkCE8f/6crl27Mn36dJycnFixYkWME4IEBwezZMkS2rVrF2fvaxsbG+rXr8/SpUu/e2KRfv36ER4eLmOGhUjNpLOWEHGztrbm999/5+HDh5QoUYJu3bpFmRDk9Us/tq6/wYSR61BjyahRo756zUGDBuHp6cmxY8cSHE/Yuw/4XbzJqd372Lhxo4wZFiK1SwPjiCURi2SRK1cuDhw4wKlTp1CpVFStWpVGdXvwy8A97PnrLm88jGlY5Vd8vb4+/XnFihVxcnJKcKet5wvXc6V6F+52G40y4g9+KVCB/v37f+MdCSFShER+R/z777/j7OyMsbExpUuX5vLly3Ee7+fnR9++fcmSJQtGRkbkyZOH/fv3J+wWEhylEN+hUqVK3LlzhxUrVmKkFET519NllUrNxpVX0WrifuSsUqno1asXhw4d4u3bt/Gq1+/iLV4u2ogSEQGAvkpFHcUK//MJ79kthEhBEvHR9ObNmxkyZAjjxo3j+vXrFClShNq1a+Pj4xPj8WFhYdSsWRMPDw+2bt3Kw4cPWbp0KdmyZUtQvZKIRbJTq9U0b9oaU2PbaPvevwvi4/+XXoxLjx49UKlU8X6/+/7EpVjK4/62K4RI4VRxtIZVCUtxc+bMoUePHnTp0oX8+fOzePFiTE1NWbFiRYzHr1ixgvfv37Nz507Kly+Ps7MzlStXTvB8BJKIhU6YWxhhbWsSrTwk1J8/l/5OaGjcyThjxozUrl2bJUuWxGvyEH2rmFeT0reMuVwIkUrEo0UcEBAQZYvp8yUsLIxr165FmdFPrVZTo0YNLly4EGPVu3fvpmzZsvTt2xc7OzsKFizIlClTEjz7nyRioRNqPTUtfyhG1MmzFNSmzxg+fBjZs2fnzz//JOL/j5JjMmTIEF68eMHp06e/Wl/mJjXQM42a+EMVLWa1y37jHQghUgSVOu4NcHR0xMrKKnKLafKed+/eodFosLOzi1JuZ2cX67wFz549Y+vWrWg0Gvbv38+YMWOYPXs2v/76a4JuQRKx0JkK1XIxZnodatRzxev9FfwjjrFx2xzu3r1L8eLF6dWrF7ly5WLjxo0xDlWqWrUq2bJlY+7cuV+tyzhrZgqumIx1+eIY2FqhXyg3w7xu0OLH7nEmeyFEChePRPzy5Uv8/f0jt5EjRyZK1VqtlsyZM/Pnn3/i5uZG69at+eWXXxI8z4EkYqFTufJkokPPUhQvb8bh438RGhpK/vz5OXDgAFevXsXJyYl27dqRP39+9u7dG+UxtEqlomfPnuzfv5/3799/tS6LQnko+OdESp9ZT5lN8/h1/QrOnDlDr169kvIWhRBJSU8P9PRj2T4/mra0tIyyGRlFX60pY8aM6Onp4e3tHaXc29sbe3v7GKvOkiULefLkQU/vn05h+fLlw8vLi7CwsHjfgiRikSK0adOG4OBgTpw4EVnm5ubG6dOnOXnyJKampjRs2BA3N7fIMcgAvXr1QqvVsmzZsgTXWbduXebNm8eKFSuYOXNmYtyGECK5xaNFHB+Ghoa4ublFmZ9Aq9Vy7NgxypaN+RVW+fLlefLkSZQndo8ePSJLliwxTtMbG0nEIkUoXLhw5OIR/1W5cmWuXbvG3r17CQoKomrVqlSoUIGrV69iZ2dHzRp12LHlMts33OTBPe8Yrh67/v3707dvX4YPH86OHTsS63aEEMkl1tbw/7cEGDJkCEuXLmX16tXcv3+f3r17ExgYSJcuXQDo2LFjlMfavXv35v379wwcOJBHjx6xb98+pkyZQt++fRNUr0r51vXqhEhkPXr0YMeOHfj4+MS6JrBWq2XLli2MGDGC58+fU7d2ExxsmhAa/M/xNeq50qFnqXjXq9VqqV+/PidOnODcuXO4ubl9970IIZJWQEAAVlZW+D1dgKVF9BEYAAEfg7HONQB/f38sLS3jdd2FCxcyc+ZMvLy8KFq0KAsWLKB06dIAVKlSBWdnZ1atWhV5/IULFxg8eDA3b94kW7ZsdOvWjeHDh0d5XP01kohFinHixAmqVavG5cuXKVmyZJzHRkREsHLlStYvu4JTlorR9k+e3wAHp9jnrP6voKAgSpUqhZeXFzdv3sTBwSHB8Qshkk9kIn62MO5EnLNfghKxLsijaZFiVKxYEQsLixgfT/+Xvr4+PXr0oHLFxjHuf/roXYLqNjU15ejRo+jp6VGtWjU+fvyYoPOFEDqi0gd1LJsqYY+mdUUSsUgx9PX1qVGjBrt27Yr3OdkcrWMsz+JgleD67e3tOXr0KK9fv6Zhw4YyrEmI1EDWIxYicbVv3x53d3eePHkSr+MbNCuIqalBlLIibtnIky/zN9VfqFAhtm7dypkzZ+jZs2e8Zu0SQuiOSqVGpdKLZUsdKS51RCnSjTp16mBoaMiWLVvidXxWRysmzKlPncb5sbUL5+KtlbTs7PpdMXwZ1rRy5UpmzJjxXdcSQiSx2B5Lf9lSAUnEIkUxMzOjXLly/PXXX/E+J7O9BW27uDF2WlOevTrD+vVrvzuOL8OaRo4cyfbt27/7ekKIJJJI44h1KXVEKdKV1q1bc+vWrViXHouNjY0NVapUYfXq1YkSx4IFC6hduzbt2rXj6tWriXJNIUQiS8RxxLoiiVikOM2aNQP4pgk2evTowYMHD3jw4MF3x6FWq9m2bRu5c+emTp06vHr16ruvKYRIZNIiFiLxZc6cmSJFirBp06YEn9uoUSPMzMy+acrLmMiwJiFSOEnEQiSNFi1acP78eQIDAxN0nrGxMQ0aNGDDhg2J1uNZhjUJkYLFY9GHlE4SsUiRWrVqRVhYGAcPHkzwub169eLNmzecP38+0eKRYU1CpFDSIhYiabi4uODs7ByvWbb+q3LlymTKlIklS5Ykakz/HtY0c+o03h89i8+WfYS8epOo9QghEiANDF9KHVGKdKlxo6Yc2X+LA7vuUbxUduyyWMTrPLVaTevWrVmzZg1hYWEJWo7sa/r378+rO3/jsuEoz7Zf+FyoUuE4tDt2bRpGOz78YyD65qaoVKpEi0EI8S+q/2+x7UsFpEUsUiTvNx8Jf1+SEgU6s2nldYb33cXxg4/ifX6PHj0ICAhg//79iR7bj9ny4mhs9k+BovBq/krC3/tFFnkduczRMt3Yl7MZh9068XLbcXx2HOFm4x+5XLYVDwdPIeR1wpZsFEJEpyhKnFtqIKsviRTp95mnuXzueZQyQ0M95i5vjrmFUbyukTt3blxdXdm3b1+ixRUREcH1Bl1Rv/OLti9D45o49P6B0IAgjlfshTYsPHKfkYkaG5uoD6CMHLNQdOciVPqpo0OJECnJl9WX3vvtwNLSLJZjArG1biqrLwnxLR79HX0yj7AwDe5PfON9jQ4dOnD06FECAgK+K5aAgAA2bdpEkyZNsLGx4cqzxzEe57vrCHea9OTpb5uiJGEAU9Pof2qhL9/gd/HGd8UmRHqnKNo4t9RAErFIkTLZm0crU6kgcwzlsenatSthYWEJmi7zi+fPnzNnzhzKli1LhgwZaNu2LXfv3qVHjx6UHDMo1mER2pBQnu06FK1cHcu7Ks2n4ATHJoT4h/KV/6QG0llLpEiNWhZi7q8n0Gr/+UPyfHudsIgqQPweMTk6OuLm5sayZcvo1q0bWq3C/h33OHn4MeHhGkpXcKZ5+6IYGemj1Wq5evUqW7ZsYdeuXTx58gQ9PT1KlCjBtGnTaN68Oc7OzpHX/lS0CG9WbcP/1KVo9dqbG+IVGIHqX7GHhGgxMIz6vVdtYox1uWIJ+ncRQkSlVbRoFU2s+1IDeUcsUqzHD3w4duARnz6G4pTTlAE/NUdPX83ly5fJmjVrvK6xaNEi+vbty+vXr7lw0oddm29H2Z/NWR8Pnz0cOnSI9+/fY25uTrVq1WjTpg316tXDyir2dY21oWHcqt0Jzaeok44YZLTFtntH7o1fSoj3ewxtLXEd2g7tsyf4HjwDioK+jRW5JgzApnKphP/DCCEi3xF7v9+EpaVpLMcEYWfbJsW/I5ZELFKNZ8+eUaZMGUxMTLh06RL29vZfPcfPz49MmTIxadIkXtzLQeDHsCj7tYqWc7emUqtOFdq0aUOFChXQ14//g6I3q7fx+reoi0w4jepDpmZ10EZoCHnzDqPMNugZfR5CFfrGh7C3HzDLlxO1gUFMlxRCxMOXRPzGd32ciThLhvaSiIVITI8fP6Zs2bJYWlpy6dIlMmXK9NVzatWqxTvvEArnjHlGrGkLG5HFIfaW79f4nbrEk407OXjoEHUnjsCtQ6tvvpYQIn6+JGLPd2vjTMRZM3ZI8YlYOmuJVMXFxYWzZ8/i5+dHuXLl8PWNuxd1cHA4hXJ2olCOHjEm4awOVt+VhAGsK5dG3bMlYzxuoCqQ+7uuJYRImLTQWUsSsUh18ubNy5kzZ3j79i3ly5fnw4cPsR67e8sd3nnF3GEjY2YzfhxSIanCFEIkA62iiXNLDaTXtEiVChQowOnTp6lQoQIVK1Zk04b9PLr7HiNjA8pVyYGN7edHVTevvIzx/BYdilK/SQHUevJdVIjUTEGLQsxftmMrT2kkEYtUq3Dhwpw6dYrO7cYyc+ypyPLdf92hRacc7Nyzhud/ZySDVfTHxS55M0sSFiINiKvlm1paxPJJJFK1vK4FKFmwdZSykOBwZk3aybp168jsEBrtHKectrjmz5xcIQohkpBCXO+JUwdpEYtUzfOVP+Hh0f/csmXJz9sTbzE0NOTSWQ8O7Pwb92eveeF5g/krZ8lqSEKkFXFNZZlKJvSQFrFI1TLbW6CvH/3XOHuODJHLH5au4Mz4WfXoOTQ/Jy8t4tbtK8kdphAiiWjRxLkl1O+//46zszPGxsaULl2ay5cvx+u8TZs2oVKpaNKkSYLrlEQsUjULS2PqNskfpUxBS/N2RaMdW7ZsWTJnzszy5csTrX4lPByfZesx+nUBB0tVR//IaRRN6ngvJURakJjLIG7evJkhQ4Ywbtw4rl+/TpEiRahduzY+PtEXofk3Dw8PfvrpJypWrPhN9yCJWKR6LX4oxqBRVahQLReWGf04cHoCtpmj/wGq1WpatmzJrl27iIiISJS638xdgu+6v1C/9yO7iTkGB07i8+faRLm2EOLrvvSajm1LiDlz5tCjRw+6dOlC/vz5Wbx4MaampqxYsSLWczQaDe3bt2fChAnkzJnzm+5BErFIE4qVcqTHgHJMmduZkPC3jBs3LsbjunbtSkBAAEePHv3uOjWBQfgfPhmt3G/3QZRESvRCiLjFZxxxQEBAlC00NHonzrCwMK5du0aNGjUiy9RqNTVq1ODChQux1j9x4kQyZ85Mt27dvvkeJBGLNMXCwoL+/fuzdu1avLy8ou0vVqwYDg4OcX7DjQ9fX19W//knxJBwtcEhKP9Zj1gIkTS0StwbfF6JzcrKKnKbOnVqtOu8e/cOjUaDnZ1dlHI7O7sYP0sAzp49y/Lly1m6dOl33YMkYpHmDBs2DH19fSZNmhRtn0qlonXr1uzfvz/Gb8Vx+fDhA3/++ScVKlTAzs6O7kOH4KENi3acafFCqE1Nvjl+IUT8hWtVcW4AL1++xN/fP3IbOXLkd9f78eNHOnTowNKlS8mYMeN3XUsSsUhzrK2t+fHHH1mxYgXv3r2Ltr9r164EBgZy4MCBr17Lz8+P5cuXU6lSJTJlysSPP/5ISEgIs2bNwtPTk2qrF2OQ9Z9v0AFmxmT5qW+i3o8QInZaRRXnBmBpaRllMzIyinadjBkzoqenh7e3d5Ryb2/vGFd6e/r0KR4eHjRs2BB9fX309fVZs2YNu3fvRl9fn6dPn8b7HiQRizTpyzfeKVOmRNuXP39+CuQrwYYV59m3/S7vfD5F2R8QEMCqVauoUqUKGTNmpHv37nz8+JHp06fz+vVrrl69yqBBg7C3t8coR3ZyrVuE029TmaUOpMfLv1EZGuA9fzEevQbhOWkGIY+fJcs9C5EeaRXQxLJpE9Bp2tDQEDc3N44dO/bPtbVajh07RtmyZaMdnzdvXu7cucPNmzcjt0aNGlG1alVu3ryJo6NjvOuWCT1EmpQxY0a6devG4sWLGTNmDDY2NpH7rpx/jlue/oCKLWtusGPjLXoMKs3Dp+dZvXo1Z86cITw8nMKFCzNlyhTat29PtmzZYq1LpVZjWigfFTq0Y2P3Hrj3/xnl7edVoUKfuvPp0jWc/piNUXaHpL5tIdKdCK2KCG3ME/TEVh6bIUOG0KlTJ0qUKEGpUqWYN28egYGBdOnSBYCOHTuSLVs2pk6dirGxMQULFoxyvrW1NUC08q+RFrFIs8aMGYNGo2HatGmRZVqNlvXLrwL//IGGh2uZOm4bnTp1wsfHh4kTJ/LixQtu3brFsGHD4kzC/9a0aVO6OOVG6+OLosCXIYxKSAh+u/Yn5q0JIf5Po6ji3BKidevWzJo1i7Fjx1K0aFFu3rzJwYMHIztwvXjxgjdv3iT6PaiUhI54FiIV6dmzJxs2bMDT0xNLS0ve+XxiaM8dMR47ano5XF1zfXNdb1eux3ftlqiFKlCpwLx8abJNGPXN1xZCRBUQEICVlRVn3BdibhFz58hPH4OpmKMf/v7+WFpaJnOE8SctYpGmjR8/nrCwMGbNmgWAlY0JZuaG0Y6zzWCKi8u3DcYHCHvlie+6v6Lv+P/XXFO3Yt98bSFE7OIzfCmlk0Qs0rSsWbPSrl075s+fz6dPnzAw0KNJ68JRjlFQaNauKGr1ty8EEXT3/j/Pov/DrExJrOvWiHGfEOL7JOajaV2RRCzSvIkTJxIYGMj8+fMBqNUwHz+Pr06FarmwyRzE4XNTccyl9111GGaJPrwBwLR4ERx+HY3KwOC7ri+EiJnm/521Yto0CeyspSuSiEWalz17dlq2bMns2bMJDg4GoGDRrPQYUI7Jc38gOMyTiRMnflcdJ18/55Kfb5SyYE0Eq/y9EzzxvBAi/mIbuvRlSw0kEYt0YfLkyfj7+7Nw4cIo5WZmZvTt25f169d/dYWVLxStBs3Dc0ScXo3m7lF2/rWZxo0bs8HaEJtuP2BWshhW9WpwoaIb45b9yeDBgyUZC5FE4jOhR0onvaZFutG8eXNOnz7Nq1evosys4+vri4ODA3379o3s1BUbRashYsdklBe3Istue/oz7aERG7buiFwD+YupU6cyatQoBg8ezOzZs1GpUscHgxAp3Zde07vuL8Isll7TgR+DaZyvt/SaFiKlmDJlCr6+vixZsiRKeYYMGejUqRNLlizh48ePcV5DeXolShIGKJzVio2ju0dLwvB5hq/Jkyczd+5cfv75Z2kZC5HI0kKLWBKxSDdcXV2pX78+U6ZMITw86upIo0ePJjg4ONqj6//Sesc8f6zqnXus54waNYpJkyYxe/ZsRowYgaIohDx1J8wz8ScGECK9iYhjwYeEzqylKzLFpUhXpkyZQuHChVmxYgW9evWKLHdwcKBZs2bMnj2bIUOGxDgpPIAqQ8zzx6oyZI+z3tGjR6PVatkwczbN7z7DKvTzqk2mxYuQdcww9CzMv/GOhEjf4hovLOOIhUiBChUqRK1atZg0aRIR/1lLeMKECfj6+rJq1aoYz42IiKDTpD+49Px9lHKP98F4Zyoc4zn/NmbMGNZVrhWZhAGCrt/Ca/6ihN+IEAKQR9NCpEpTp07l9evXrFmzJkp5vnz5qFGjBlOmTEGj0UTZFxwcTN26ddm0ZStPC7ZFr1oP1PmrEFy0KfVX3aBu05ZfXd849JkHFiHR1y/+dPIsr0ZNROMf8P03J0Q6E66Na01iXUcXP5KIRbpTvHhxqlSpwoQJE6Il3C8LPmzbti2yzM/Pj4oVK3L69Gl27NhB5+490StSB/3a/bGq+gNr/9rB33//TY8ePeKsV21sHOu+wMvX8J6/+PtuTIh0SKa4FCKVmjZtGi9evGDTpk1RysuWLUvNyl3ZvtqHbi3XM33sASqUq8HDhw85fvw4DRs2jHatMmXKMH/+fNauXcuiRbE/ZjbMlgV/+0yx7v947iLasOgtZiFE7MIUCNPGskkiFiLlKl26NOXLl2fs2LFotf88vzp7/ClZrKtgZGBFRLiWv2+/I69jO86fv0D58uVjvV6fPn344YcfGDBgABcvXozxmCtXrlBv+0ZuxdJFUqVWyzhjIRJIiaM1nFpGC0oiFunW1KlTefbsGdu3b48sO3HocbTjzEwyodZm+Or1li1bRv78+WnUqFG0Wbq8vLyoX78+9jlz0HDHJszLlop2vqq0m8xJLUQCyRSXQqRiFStWpFyZ6ixdcJoZ446wdf0NAgNj7nAVGhIRY/m/GRkZsX//fiIiImjQoAFBT5/y6cxpAj08qFu3LhqNhkOHDmFiYoL9sIFYVKsE+vpgYMCe9z60/GsdISEhiX2bQqRpsT6W/v+WGsg4YpFu+b4NpIBTF0JDtNy75cW9W16ERwRjoB91ujytEkruvLbxuma2bNnYvm0b14cOwXvQwM/nA/XDw6m/dy/ZsmUDQM/CnKyjhqIMGwgqFVVv3mRU2bJ069aN9evXJ+p9CpGWyThiIVKx4wcfERoS9Suzgb4Jaj0V/P9VrYmpipOXf6N+gzoEBQXF67ol1Gqa/j/hwuc/sm45nClqbhbtWJW+Pio9Pdzc3FiwYAEbNmxg8WLpPS1EfKWFR9PSIhbplo9XzPNKazUKuV0z0bFXKRycrGlxwp4GDRpQqVIljh8/Hufk8YrvbYKOb4pxX/C165gUin3ijx9//JEzZ84wYMAASpYsiZubW8JuSIh0KEJLrOOFI1LJo2lpEYt0y7WAXaz7njx8S7bs1ujpqalRowbHjx/nwYMHlC1bFl9f3xjPUbwuoDxci55hzC1nPVubr8a0fPlycufOTYMGDXj//v1XjxcivUsLLWJJxCLdqlQjNy75Yh7Xa2lljJ7eP0OJypUrx5kzZ3j9+jWlS5fGy8srcp+ijUDxvozGfS8A5kWtURlG/dPSs7bGvErVr8ZkbGzM/v37CQwMpGnTplGGVgkhogvTquLcUgNJxCLdMjTUY9Tk2hQtmS3avsCIv6OVFStWjPPnz+Pn50fJkiV5+fIliqKg3F+B8vQvVNrPk3EY2Bhi/4MTpnktMMhgiFmlsmSZPgO9eK6H6uzszKZNmzhz5gyjRo36vpsUIo2TmbWESOXUahUDR1ShbVc3crhkIE++zDjl/cTKDeP5+eefox2fP39+Ll26REREBCVLluT13yfA/zFBIWruv/inM5ahnTGZmjpg3DYvFn2GYJA1a4LiqlevHsOHD2fGjBns27fvu+9TiLQqLTyals5aIt1T66mp0yg/dRrljywzMHvH2LFjsbS0ZOzYsVGOz5UrF1euXKF8+fL8OXcC47uWwj9Qn+X7Hejb5Dk5s3weCxwapmLVwWz0q/Rtf2aTJ0/mwoULtGnThjt37uDs7PzN9yhEWhWhgXBN7PtSA0nEQsRgzJgx+Pv7M27cOKysrBg4cGCU/Q4ODly5coWh3Ruz81xm9l6wQ6NVMWmtC5ltQsmdNZhbTy0IDNEnPFyDsUnCZ8xSq9Vs376dAgUKUK9ePa5fv45xHAtHCJEexdXyTS0tYnk0LUQsZs6cSffu3Rk8eDArV66Mtj9z5swMHLWWXefs0UR2ClHh88GY8/dsCAzRJyw8kBkzp+Dn5/dNMdja2rJv3z6ePHlCt27dvv1mhEijwpUvSyHGsEkiFiJ1U6lULFmyhFatWtG9e3f++uuvaMc8feAf5zUMzF8zffo0smbNSr9+/fD09ExwHMWLF+e3335jw4YNca7uJER6lNjviH///XecnZ0xNjamdOnSXL58OdZjly5dSsWKFbGxscHGxoYaNWrEeXxsJBELEQe1Ws369eupW7cu7dq14+DBg1H2m1saxXhe5izm9BtWiTWbJ/HixQt69OjBypUrcXJyon379jx+/HlxCX+/YHZuvs2Seec4cegRj9+/Zc6t4ww8t40ZN4/y0O/z4hG9evWiffv2DBw4kCtXriTtTQuRiiRmIt68eTNDhgxh3LhxXL9+nSJFilC7du1oi7h8cfLkSdq2bcuJEye4cOECjo6O1KpVi9evXyeoXpWipJaFooTQnbCwMGrVqsXFixc5fPgw+VyL89b7I2YWBvwycAd66n/e3Roa6TFpbgPss0YdruTv78+8efOYP38+fn5+1KvTlOwZWhD48f8LSpiBUVcDFP1//iQN1HqMcatDFlNLQkJCKF68OB8+fODevXvY2sZv/msh0qKAgACsrKzodnAphmamMR4TFhjE8jo98Pf3j3NGvC9Kly5NyZIlWbhwIQBarRZHR0f69+/PiBEjvnq+RqPBxsaGhQsX0rFjx3jfi7SIhYgHQ0NDDhw4QOHChRk9dAM/9drB9LFHGTN4L38/OYJjDmOsbUwoUCQLwyfUjJaEAaysrBg3bhyenp7Mnz+fj742/yRhQJ1fFSUJA4RrNZx98xT4PNnHgQMHZLIPIf4lPi3igICAKFtoaPRV1sLCwrh27Ro1atSILFOrP8+sd+HChXjFEhQURHh4eIK/JEsiFiKeTExMmDRmOTmylY8sU6FHoTwNaNSiJPNXtmDYhBrkzhvzbF1fGBsb079/fxrWaxOlXGUU8yxAwRHhkf/byclJJvsQ4l+0WlWcG4CjoyNWVlaR29SpU6Nd5927d2g0Guzsok59a2dnF2UmvbgMHz6crFmzRknm8SHDl4RIgL9vv4uhVMWi2WfJkMmMXHniTsL/ljNPJu7ceBP5s/apFr2S0b8bF80YdeavevXqMXLkSKZOnUr58uVp2LBhvOsUIq2JCFejDo+5TRnx//KXL19GeTRtZBRz347vMW3aNDZt2sTJkycTPMxQWsRCJICZuWGM5VqtwoGd0afFjEut+nmjPMJW3oD9CwsM1HoA6KnU1HXMR+EM0afgnDRpEpUrV6Zdu3a4u7snqF4h4ktRFIJP7OfDpCF8mDiI4KO7SWndiuLTIra0tIyyxZSIM2bMiJ6eHt7e3lHKvb29sbe3jzOGWbNmMW3aNA4fPkzhwrGvsBYbaRELkQDV6uTh/MlnxPRZ9P5d/NYr/sLc0ogJs+tx8YwH3p4BuOTPTNESDgRpwvAM9Mfe1AJLQ5MYz/3vZB83btyQyT5EogvauY6gnesjf/709AGa9+8wb9VVh1FFpYlQR7Z8Y9oXX4aGhri5uXHs2DGaNGkCfO6sdezYMfr16xfreTNmzGDy5MkcOnSIEiVKJCj2L6RFLEQC5HbNRNd+ZWPcFxKR8DHCxiYGVKnlQuvObhQv5YharcLcwIg81pljTcJf2NjYsHfvXp4+fUrXrinng1GkDUpEOMGHdkQrDz66GyUsemcnXYlPizi+hgwZwtKlS1m9ejX379+nd+/eBAYG0qVLFwA6duzIyJEjI4+fPn06Y8aMYcWKFTg7O+Pl5YWXlxefPn1KUL2SiIVIoErVc9OqYzFU6n/+yBW1P7N+G0DHjh1j7JGZVIoXL87ChQvZuHEjf/zxR7LVK9IuLy8vNm3aRO9uXVGCY3jKExqCEhSY/IHFIjETcevWrZk1axZjx46laNGi3Lx5k4MHD0Z24Hrx4gVv3vzTr2PRokWEhYXRokULsmTJErnNmjUrQfXKOGIhvtFb74/8fduLDJnMyF84C4sW/cGgQYPIly8f+/fvx8HBIdli6dChA5s3b+bcuXOULFkyUa4Z4eeP/8GjRHi/xbRoIcwrlEGlp5co1xYpx6tXrzh+/DgHDx7k7NmzvHz5Evg8n/qOKoVxUkddOUHPwRnbyYt1EWoUX8YRN1y9DgPTmMcRhwcFsafTD/EeR6wrkoiFSEQXL16kUaNGhIWFsXXr1gQPY/hWISEhuLm54evry71798iQIcN3XS/c+y3PB/yMxvdDZJlF5fJkHTPse0NN17SKFrVKtw8iPTw8OHbsGAcPHuTcuXORLTxnZ2cqVKhA3bp1qVq1KlmyZCH8+RP8Z49B8f/8e6CysMJq8EQMcrnq8haAfxJx/ZXr40zE+7q0T/GJWDprCZGIypQpw71792jUqBG1a9dm0qRJjBw5EpUqYY/IEsrY2Jj9+/dTqFAhmjZtyokTJ9D7jtbr+y3boyRhgI+nzhHc/CEm+XX/IZzaeAa+5dSba3gH+2JlaE7ZzIXJa5Pju66phASifXoJFC3qXKVRmVhEP0ZRePr0aWTiPX/+fOR0jbly5aJOnTrUrVuXypUrkzlz5mjnGzjlJsOs1YTduQqKgmEhN1RGKatTYHi4GmLprBUeS3lKI4lYiESWKVMmzpw5w5AhQ/jll184f/48mzZtwtzcPEnrdXJyYvPmzdSvX59Ro0Yxffr0b7pOxAc/Ai9fj3FfyJNnkogTKDA8mB0exwnXfp5FzT/sEwdfncfcwBQHc7uvnB0zrecDInZMhrDP73A1J1ei32gEKseCPHz4kKNHj3Lo0CEuXLiAr68vKpWKPHny0Lhx48jEG9/Zn1SGhhi5lfumOJODVon9XbBWSdovwIlFErEQSUBfX58FCxZQvnx5OnfuTOHChdm/fz958+ZN0nrr1q3LqFGjmDJlCuXLl6du2XIo4REYZo17HOQXny5fw3PCNJTQsBj3G+fOmZjhpguP/J9HJuF/W35gPQEXX2NkZISpqSkmJiaYmJhgamqKsbExJiYmGBkZYWRkhLGxcZT/tj/1OwZh/+pIFR7C8zVjcZtzig8fPqBWq8mbNy+tW7embt26VKxYESsrq2S86+SjxNEpS0lgZy1dkUQsRBJq3bo1hQoVom7duhQvXpzVq1fTsmXLJK1z4sSJ3Dp/Ht+JM3hm/fldsXFeF7L88jOGWWJvgSlaLd7zF8eahC0ql5fW8DcIiqnnMeDl48W2tWsJDw8nLCyM8PBwwsPDYzz236xNDPCeHH02tWxmavp1aUe5mg0oX748FhbRH1WnRRHhatCPe2atlE46awmRDAICAmjZsiWHDx9m8ODBzJw587ve4X6Nx7gphJ67FKXMKK8LJmN+xsvLC29vbzw9PXn58iWvXr3izZs3aHzeMcf88xSdigIoRE5ckrlPV2ybNZBe0wmg0WhYsmQJMxfOod/6MejpR233NMhekdxW2aOUKYpCWFgYoaGhhISEEBoaGuV/h4SEEBoSTKl7KzDURB0mpzUwxujHlaj0Y579La350lmr4ryt6JvE3FkrIjiIM4NaSGctIcTnKfYOHjzIxIkTmTBhAleuXGHnzp3f3bs5JopGQ+ila9HKQx88prxzDjxDgiPLzMzMsLW1JWPGjDhmtiNUA4ZaUDQA/zzWe7d6C+ZlSmDkGH26TRHdsWPH6N27N48fP6Zp06aUsyrEnVB3giJC0FfpUSJT/mhJGEClUkU+jo4rcWisAtGcWROlbN7Jx7Rt+AYnJ6dEv5+UTKsl9nfEqWSBMknEQiQTlUrFuHHjKFOmDC1btqRAgQLs3bv3m6fFi6MiVPr6KBFR30sqwJ8rVpAxZw7s7e2xs7OLNi3mu9Ubebd6E/9OwgDaT4G837KLLEP7JG6saczTp0/p3bs3R44coVChQpw/f56yZT/PxFZKWwT/sE+YG5hiqGfwXfXolWiMyjITmr9PgqLlXYZ8LJjZnzklS3LmzBlcXdPPK4S08Gg6dUQpRBpSu3Zt7ty5g62tLeXKlePPP/9M1Our1GqsalePVm5eugT127ahdOnSODk5xTg3dcZObbGoVS3G64a9TPgUnumFv78//fv3x9XVlZs3b7J69Wpu3boVmYQB9NR62BpbfXcS/kKdpxwGTUZh0HQ0WSo158qVK5iZmVGmTBlu3ryZKHWkBl96Tce4pZJe05KIhdABJycnrl+/TosWLejVqxedOnVK1KkxM/Xqwke3IgRGRKDo6WFZowpZRgyO8xytVsvWrVvpsW5FjPtNCqSfVlZ8aTQafvvtN5ycnFi6dCnDhw/Hw8ODjh07JvnY8f/Kli0bV65cwd7engoVKnD+/PlkrV9XNOGfF32IadNIi1gIERdjY2M2bNjAwoUL2bBhAyVLluTVq1eJcm21oQFbVWFUvnYal31byDJiMHoWMY9j1mq1bNq0CVdXV1q2bMk7UyOC3ApGOcbQyQHbVo0TJba04vDhw7i6ujJgwABq1KjB06dPmTx5MqaxzPKUHDJmzMjFixdxdXWlevXqHDlyRGexJJfEnGtaVyQRC6Fjffv25cyZM3h5eVGoUCGOHTuWKNc9efIkJUqUiNZb9wutVsuGDRtwcXGhbdu2ZMiQgZMnT3L58mXcZv8KQ3sx3/0+n1rWJ8efc9C3Srm9TpPTo0ePqFGjBrVr18bc3JxLly6xdetWsmVLGR3ZrKysOHPmDCVKlKB+/frs3LlT1yElLa0S95YKSCIWIgUoU6YMd+/exdXVlVq1ajF16tTvWoA9IiKCW7duUbVq1Wj7NBoN69atI1euXLRv3x47OzvOnDnDxYsXqVy5cuRxQVkzs+TFI/TLlUBtlD6GxMTFz8+P3r17kz9/fu7cucO6deu4ceMGpUqV0nVo0ZiamnL06FGqV69OixYtWLt2ra5DSjJ64do4t9RAErEQKUTmzJk5e/Ysffr0YdSoUTRq1CjB65p+cfPmTUJCQqIsOqHRaFizZg25cuWiQ4cOODg4cO7cOc6fP0+FChWiXSMo6PNEFGZmZt92Q2lEREQE8+fPx8nJiVWrVjFy5Eg8PDxo3759sr8HTggjIyP27NlDkyZN6NSpU5pdJlOlVVDHsqlSSYtYhi8JkYLo6+vz22+/UbZsWbp160aRIkXYv39/vIejRAR85P1fewjce4hxeYpRyC4rERERrF27lvHjx/PixQsqVarEpk2bKFOmTJzXCgz8vOasLt956trBgwfp27cv7u7utGzZknnz5pElSxZdhxVv+vr6bNmyhW7dutG3b180b73pksuOiNcv0M+RB9M6zVBbWus6zO+ip9GiFxFzy1fRpI4WsSRiIVKgdu3aUaRIkcipMdesWUPz5s3jPEcbFo5H/18IdX9BRqClXXae9fqZ7k+vc9XjGVWqVOGvv/6K96PULy3i9JiIHzx4QJ8+fThx4gTFixfn8uXLiT/eO5mo1WpWrFiBg4Up1e+dJviZEQDhf98k7OpZbCb+jsrYRMdRfju1BtSamFu+/1lKOcWSR9NCpFAFChTg7t27VKhQgRYtWjB06FA0mtg/WT6evkCo+4soZfph4XRycuXKlSucOHEiQe8zvzwWT0+J+MOHD/Tq1YuCBQty//59Nm7cyNWrV1NtEv5CpVIxonIpMpkYRSnXeHsScvGkboJKJLE9lv6ypQaSiIVIwSwtLTlw4ABjx45l7ty5VKlSBV9f3xiPDfP0jrG8UdkK35RIAgICUKvVGBkZff3gVC4iIoI5c+bg5OTEmjVrGD16NO7u7rRp0yZFvwdOCM1br5jLfd4kcySJSy9CG+eWGkgiFiKFU6vVTJgwgf3793Pr1i0KFizI9evR1ws2LZI/xvNNixb4pno/ffqEkZFRmklEsdm/fz8uLi789NNP1K9fH3d3d8aPHx/jzGOpmYFrwRjLDfMWTuZIEpe0iIUQyaZOnTrcuXMHGxsbypQpw9KlS6PsNytSAJuGtaKUmRbKh23jOt9U35dEnFAarZb3IZ8I16bsF3T379+ncuXK1K9fn4wZM3L16lU2btyIvX381m5ObYwr1MSgQLEoZUZlq2JQyE1HESUO/Qgt+uGxbKmkRSydtYRIRb5Mjdm5c2d69uzJuXPn+PPPPzE0/DzON+vPfbBpUJM+dRpQqWUzOs+YjEr9bd+3P336lOBW4Y13Hux5fp2P4SGY6BlQ06EQFbPk/ab6k8r79+8ZPnw4K1aswM7Ojs2bN9OyZcs03/JXGRhi9fMUwu/dIOL1cwxyumLgEvNTlFQlrmFKqaRFLIlYiFTG2NiYjRs3Uq5cOYYMGcLNmzfZt29f5MxOJvlc2O7nhYOJ/jcnYYAgIsjgGHWoTrg2gtu+L/kUHoKrdRbsTa0j93kH+7PpyQW0fP7wC9aEs/v5dbKYWpPbSvetzPDwcObPn8+ECRPQaDSMGzeO4cOHp4t34F+oVCoMCxbHsGBxXYeSaOJ6BJ1aHk1LIhYiFVKpVAwYMICSJUvSqFEjChYsyLZt26hW7fPKSSYmJt88GYh/WBDrH5/Dqk056rYpxx/3jtDepTyKovDH30f5EPp5fPHeFzeo61iEatkKoNVqOfHoRmQS/rcjD67hUKR6tNa1RtFy5NUdLvk8JUKroXCG7DTIXgyTJFjYfu/evfTr148XL17Qrl07Zs+ejZ2dXaLXI5KfXrgWPVXMj6C1MrOWECKplS1blnv37pEnTx5q1qzJ1KlTuXn1FUVdO+Dn6cCdGwlfunDL04u4f3wb+bP7x7dseXqJw6/uRCbhL/Y/v0H5GlWwtLRk3tx5MV5v+7ZtmJmZkTNnTho3bsyUKVM4evQoOx9d4tjre3wKDyFEE85ln6dsfJK4Kwbdu3ePihUr0rBhQ+zs7Lh+/Trr1q2TJJyGqLXaOLfUQKV8z4S2QogUISIiggEDBnDy0DNKFmofZV/HXqWoXjf6zFxBQUH4+Pjg7e2Nj48Pb9684aWXJ8E1XaK9L1W0Wvw932LtED2BuW88Tl4Le9wqleWS1Uc0yj8ffiqgqsqBZ1fvcPHiRW7dusWjR48IDQ2l76ElmFhGXRFKBYwq1gRro+8bu/zu3TuGDRvG6tWryZIlC/Pnz6dZs2Zp/j1wehIQEICVlRUN267EwDDm35fwsCD2bOyCv78/lpYpd9ESScRCpBHh4Rp6t99AeFjUcpU6nBCDw3j7ePPu3TvevXuHn58fISEh0a5hmzkTnbfNRq2vF3WHVove+xA0GaN/4A0uVJesZjYAPPTzZM/zG3gH+2NjZEZdxyIUy+gc5XiNRsPTp09Z5nuVmNZt/7lIAzKbfNuHZlhYGHPnzmXSpEkoisIvv/zC0KFD09V74PTiSyJu0nI5BgaxJOLwIHb+1S3FJ2J5RyxEGvExIDRaEgZQtAbcu/cI2wwW5MuXD3t7e7JmzUq2bNmwt7fHzs6OzJkzkzFjRvT19dn45DzX33lEuUbxzDkpU8iFJX8fi9LiLWjjEJmEAVyts+JqnZUwTQQGar0YW6B6enrkyZOHIo/fctP3eZR99iZW8UrCrwPfc8H7AR/Dg8ltmYXSmV04sHc//fv359WrV/zwww/MmjWLzJkzf/VaInVL7M5av//+OzNnzsTLy4siRYrw22+/xTkj3V9//cWYMWPw8PDAxcWF6dOnU69evQTVKYlYiDTC2saETHbmvPWO2kkri4Mld3ZGnwAkNs1zlMJArReZjItndKaRkxuGevr0L1iLc16P+BgeQl7rrJTJnDvGaxjqff2jpYmzGx/Dg3ka4APAR893DK3z9Q+wF5/esuLBP18IngV4s+nobv7oOJIyZcqwd+9eChdO3ZNUiPjTD9eiTyyLPiSws9bmzZsZMmQIixcvpnTp0sybN4/atWvz8OHDGL/UnT9/nrZt2zJ16lQaNGjAhg0baNKkCdevX6dgwZgnUImJPJoWIg25efUVC6efIvz/H0AGhnoMGlWFgkWzJvhaXz4akvq96tvgAA4fO8oPDZtz5cqVr07Huf7xaR74vYpW7upjRPt68h44vfjyaLpVgz8xNIh50Yqw8GC27O0Z70fTpUuXpmTJkixcuBAArVaLo6Mj/fv3Z8SIEdGOb926NYGBgezduzeyrEyZMhQtWpTFixfH+16kRSxEGlK0hAPT/2jClfPPUalUlKrghI3tt3V8Sq6ElsnEktZ1GjE4UybmzJnDhg0b4jz+Q2jMw7IKlXGTJJwOacKCiIjlEbQmIhj4nLT/zcjIKFq/gbCwMK5du8bIkSMjy9RqNTVq1ODChQsxXv/ChQsMGTIkSlnt2rXZuXNngu5BErEQaUyGTGbUaZy6ZkzS19ena9euzJ8/n4CAgFhbL9evX+fCoaPkrBG11axGhZN5puQIVaQQhoaG2Nvbs+3woDiPMzc3x9HRMUrZuHHjGD9+fJSyd+/eodFoog1ts7Oz48GDBzFe28vLK8bjvbxiXmAjNjKOWAiRIvTv35+wsDBWrVoVbZ+/vz89evSgRIkS3PzrKKbaqG2IatkKY21klkyRipTA2NgYd3d3/P3949xevXoVrezfrd6UQFrEQogUIVu2bNRq1pDjbx+S6fF5XG2yUMTWiXVr1zJ48GCCg4OZNGkSw4YNQ6Wn5qHfa7bv383v42cy7MZdXYcvdMDY2DjRVsnKmDEjenp6eHtHXU7U29s71oVA7O3tE3R8bKRFLIRIEV4HfqDI4Fa41C/PdV8PNj65QJeF4+jcuTNlypTh8ePH/PLLLxgYGKCv1qOAbXY6VGiA99MX7N69W9fhi1TO0NAQNzc3jh07Flmm1Wo5duwYZcuWjfGcsmXLRjke4MiRI7EeHxvpNS2ESBHWPDrDnfcvo5WX9DOnVZ1GsZ6XL18+nJycOHjwYFKGJ9KBzZs306lTJ5YsWUKpUqWYN28eW7Zs4cGDB9jZ2dGxY0eyZcvG1KlTgc/DlypXrsy0adOoX78+mzZtYsqUKQkeviSPpoUQKYJ3kH+M5a4li8R5XqtWrZg+fTpBQUGYmn7f1JgifWvdujVv375l7NixeHl5UbRoUQ4ePBjZIevFixeo/7WiWbly5diwYQOjR49m1KhRuLi4sHPnzgQlYZAWsRAihYhpRi8VMLxoIzIYm8d4DsCjR49wdXVl69atNG/ePGmDFCIJyDtiIUSKUNOhEOYGUTvelMvkEmcSBsiTJw85c+ZkzZo1SRmeEElGErEQIkXIaGzBz0Xq09jJjWKmWdnUZxIv9sU8kcJ/tWjRgqNHjxIaGprEUQqR+OTRtBAiRapXrx63b9/m+fPn6OnpxXnsnTt3KFy4MHv27KFBgwbJFKEQiUNaxEKIFGn8+PG8fv2abdu2ffXYggUL4uDgwNq1a5MhMiESl7SIhRApVokSJQgNDeX27dtfnUd64MCBrFq1Cl9fX/T1ZUCISD2kRSyESLHGjh3L3bt3OXPmzFeP7dChAwEBAZw8eTLpAxMiEUmLWAiRYmm1WnLlykWOHDk4fvx4nMcqioK9vT21a9eWHtQiVZEWsRAixVKr1YwcOZITJ05w//79OI9VqVQ0btyYffv2odUmbEF4IXRJErEQIkXr1KkTtra2TJw48avHdujQgffv33Pu3LlkiEyIxCGJWAiRohkZGTFgwAC2bt3Kmzdv4jy2fPny2NraSu9pkapIIhZCpHgDBw5EX1+fGTNmxHmcWq2mfv367Nq1C+n+IlILScRCiBTP2tqazp07s3TpUj5+/BjnsR07dsTHx4dr164lU3RCfB9JxEKIVGHUqFGEhITwxx9/xHlclSpVsLS0lMfTItWQ4UtCiFSjadOmnD9/nlevXmFgYBDrca1bt+b8+fO8ePHiqxOBCKFr0iIWQqQa48aNw8fHh40bN8Z5XIcOHXj16hV3795NpsiE+HbSIhZCJDm/oDCMDfQwNoh78Yb4KF++PO/evePBgwextnZDQ0PJU7Iw7Qb1pEXDJhS0zY6RXuwtaCF0SRKxECLJeLwLZNK+v7nz2h8jfTWNi2ZjUA0X9NXf/jDu8OHD1K5dm0OHDlGrVq0YjznleY+jr29F/mxpYEL3fDWxMYp7bWMhdEESsRAiSWgVhRaLz/PqQ3CU8l6VctKtQs5vvq6iKOTNm5eMGTPGOHFHQFgQs2/vQvufj7YiGZxpkbPcN9crRFKRd8RCiCRx+5V/tCQMsP+u13ddV6VS8csvv3D+/Hlu3LgRbf+rQN9oSRjg+ce331WvEElFErEQItVp27Yt9lmzMHfzcs553edN0AcAwsLC2Ld5e4zn3Dx7iREjRuDj45OcoQrxVZKIhRBJorCDFY42JtHK6xW0/+5rh6Gh57qpODUvx8GXN/jj3gHmHlpPzpw5Gd5nMAH3X0U5Xo0K01dBzJs3DwcHB9q2bSs9qkWKIYlYCJEk1CoVnaubkdEmDAA9PQXXHEEUyB343dc+43UfrXnUXtDvbVUULleCmzdvMqfDTzR2LkU+awdKZMpN7wJ1WDJ1Hp6enowaNYojR45QqFAhKlasyMGDB2U6TKFT0llLCJEkIrQalj3YRpg2nNAwFXp6Cvp6YKQ2pHveZuipv30o059/H+JloG+08sbOpSiRKfdXzw8LC2PDhg1MmzaNhw8fkjNnToYNG0anTp0wNjb+5riE+BbSIhZCJIkwbThh2nAAjAw/J2GAUG0Yof8v/1axDUOyNbKI1/mGhoZ07tyZ+/fvc+zYMZycnPjxxx/JkiULI0eO5O1b6dglko8kYiFEkjDVN8bWyCpauZW+Oab639fqrJAlPwb/aVE7mNiSwyJzgq6jUqmoVq0ax48f5+HDhzRq1Ig5c+bg4OBAu3btuH//fpTjFUVB++4NStCn74pfiH+TR9NCiCTjGejD7ucnI1vGIZ+COblgD1uWb8A34hMWBibYGlt+07W9g/246P0Q74D3rJmzmGo5ijFx3PjvjtnX15f58+fz+++/8/79eypWrMjo0aOpmtuBkNWz0Hq/BH0DDMvVxrh1P1R63z9bmEjfJBELIZJUqCaMZwGfezF73XvJoEkjaTa+J/rGhgDksXKgqXN59L/jnXGnTp3YuXMnnp6emJmZJUrcYWFhrFu3jmnTpvHi2VPud6yMrWHUGI2bdsOodptEqU+kX5KIhRDJJigilHm3tqKoo84RXSlLISraF/rm67p7eNBx4iCqdmhCxowZKZoxJxXs86JWff/bN0VRuLb+T1zObo22T+2QE4vRS767DpG+yTtiIUSycQ94Ey0JA9z1efZd172v9qVK71Yo5oa8DQngyKubHHp587uu+YVKpaJIcbeY9+npJ0odIn2TRCyESBaenp6sWbEqxn2Xz10ke/bsdOnShd27d/PpU8ydoSK0Gh75efLIzxONVgtAmCaCq2+fRDv2ovdDgiPCEiV2fddiqDJEn4jEoFydRLm+SN/k0bQQIklduXKFyZMns3fvXgyNDBm2Zz4GNlHf42Z9o8+xDbs5duwYXl5e6OvrU6RIEerXr0/jxv9r7/5jorwPOI5/nuPu4K70OKZUQJCx2rGKdsRRkobakDlM2pg4nFvTtEWSxraYKE2W4fyjWaIzoi4OmpiYKK7daruYBpvgwh/OdG3DRUu0xBI7K20pp+L1FzK6YrmDb//gj9bcGctx8CW59+vP73P58r2/3jz3PM/3WaeKigpFbozopYv/0f+iU/tXBzw+bSyrUcDjU0tv4m0tU/mih4lrYY29+oImLvbKuSMg7+r1ynrk8ZTMjfRGiAHMyMejQzr/xUealFF5sEQ/DRYrFoupo6NDu3fvVm9vr/Lz89XU1KTGxkY5Po/euNqrj0aHFL40oKtvX9A//9ouaep6bH9/vzo7O9XZ2anTp0/rxo0bysnJUcOLO+UvXHDT387zZGvBe9fV7bqiu8pK4taW4bj0x4r1ynJ7U/Z9TXRcynDLmcGrHIHvI8QAktb7Rb+6wu/cNGb+O6wXntupSCSilStXavv27aqrq1NGgsd8Dh8+rE2bNqmvr0/l5eVxx8fHxxUKhfR61wn5f7My4Rpa1zyjYGGennrpzwmP/+Hnv1bA60/i2wFzg3/pACTFGKO3r70XN/5NUaaqH3pQPT09Onv2rDZs2JAwwpJUX1+vhQsXaseOHQmPe71e1dTUaN/uFrkUf5PXRCym9evq9MbxLi3xLYg7XujPJcKY9wgxgKREJ2P6Khr/vuGsbL/a//GiKisrbzuH1+tVU1OTOjo6NDQ0dMvPGSMl+unOneHWkSNHVFZWpg33VCsv67udvIavfKpV2bffdxqwjRADSIo3w6O7soJx4wGPf1pnoVu2bJHH41FLS8stPxMzEzIJUmwcacJM3T2dm5mtLcsf0dP3rtFjxQ/o7xv/pL3P7/zB6wBsIcQAklZb9At5XN89S5vhuLSmqHJaG2nk5OSooaFB7e3tGh0dTfgZJzqprwYiceM/uXORfN+7EctxHBVnL9Sy/FJta27W0aNHdenSpWl8I2DucbMWgBn5f3RM718f1KQx+lmwWAHv9LeYDIfDKi0t1a5du7Rt27abjkUiEdXW1mpo5HNtffkvGsucGi/05+rxe1bd8k1MY2NjKikpUVVVlU6cODHtNQFzhRADmBfq6uoUCoV0+fJleTweSdL58+dVW1urWCymrq4uVVVV6drX1yVJ+f7gbec8ePCgGhsb1dPT84OuWQM2EGIA80Lo3R61/vsVLaupVCDzDgU+n9DWtU+qqKhIp06dUnFx8bTnjMViWrp0qRYvXqzu7u5ZWDUwc1wjBmDdpDE6543o3l/eL+NyNBL9WuGcb7Ru60adO3cuqQhLktvt1t69exUKhXTy5MkUrxpIDc6IAVg3MBrR3z44FTde4MvVs8sentHcxhitWLFCxhj19fXJceKfRwZs4owYgHXjk7GE41EzMeO5HcdRW1ubLly4oGPHjs14PiDVCDEA60rvXCR/RmbceHnukpTMv3r1alVXV6u5uVmxWOLoA7YQYgDWeVxuPXr3gwp4pjYCcSQtz12iVfnx+08nq62tTYODgzp06FDK5gRSgWvEAOaNSTOpyNiI/O5M5czCHtFr167VmTNnNDg4KJ/Pl/L5gWRwRgxg3nA5LhX4c2clwpLU2tqq4eFh7d+/f1bmB5LBGTGAtFJfX6/jx48rHA4rGAzaXg7AGTGA9LJnzx6Nj4/f8tWLwFwjxADSSkFBgTZv3qwDBw7o4vsD+vRa4hdNAHOFn6YBpJ2rVz5Tw+/2qSBvuSRHP777R2r8/SrlFwZsLw1piDNiAGnnX699oIK8FZp6UEoa+PBLHdj3lt1FIW0RYgBp553uT+LGBj8e1tCVEQurQbojxADSjtuTkXjcnXgcmE2EGEDaeehXS+PGlt2Xr7xF2RZWg3Tntr0AAJhrv32iQsYYvXmyX9HohCofWKInN91ve1lIU9w1DSBtGWNkjORy8WpE2EOIAQCwiGvEAABYRIgBALCIEAMAYBEhBgDAIkIMAIBFhBgAAIsIMQAAFhFiAAAsIsQAAFhEiAEAsIgQAwBgESEGAMAiQgwAgEWEGAAAiwgxAAAWEWIAACwixAAAWESIAQCwiBADAGARIQYAwCJCDACARYQYAACLCDEAABYRYgAALCLEAABYRIgBALCIEAMAYBEhBgDAIkIMAIBFhBgAAIsIMQAAFhFiAAAsIsQAAFhEiAEAsIgQAwBgESEGAMAiQgwAgEXfAvKsh/Zm2ZPQAAAAAElFTkSuQmCC", + "text/plain": [ + "
      " + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "image/png": "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Z1uDmpoa6urqWrwuIyODgoKCDrnn+++/T11dHcOGDePiiy/m5ZdfxjRNpk6dyoMPPsjEiROb/Xx9fT3dunVr8Lrt2lmxYgXDhw9vVxuPHDnCV7/6VZYvX85bb73Fl770pSavFUJQVlYWV4m4KdTX11NdXZ1QGzrqb9wY5s+fT0VFRZuNCV15WKOzQhsjGhptxLp16zjzzDPp168fb7zxRqMbcVsxa9Ys/vGPf7R43amnntqsJqE1sJmLOXPmMHToUP75z39SWVnJnXfeyRlnnMHnn39Onz59mvz8yJEjee+996iuro5jYt5//30Adu/e3a721dTU8JWvfIXPP/+ct99+u0Xj6Omnn2b37t388pe/bPG7n332Wa666qqE2iGSWFv06aefJisri4svvrjVn41EIjz//PNMnjyZYcOGJaF1GhrJgzZGNDTagDVr1jBjxgyGDRvG66+/TteuXTv0+2+++Wa+/e1vt3hdRxpANTU1gBXhsWjRIvLz8wE49thjHXbk17/+dZOfv+6663j11VeZMWMGd911F3l5efzlL39h+fLlgMVqtBWVlZWcffbZbNmyhcWLF7fIdqxbt47rr7+eqVOnMnPmzBa/f/r06SxcuLDN7esIVFVV8dprr3HeeedRWFjY6s8vWrSIsrIybrvtto5vnIZGkqGNEQ2NNuCCCy6guLiYN954w9m0OxJjxoxhzJgxHf69zSEnJwew+ubu0wknnMDgwYMdfUZTOPfcc7n//vu59dZbOe644wAYNmwYd911FzfffHO7ntONN95IXV0dK1eubNEQKS0t5fzzz6egoIAXXngBv9/f4vf36dOnWdbHC/znP/+hrq6uXS4av9/PjBkzOrhlGhrJhxawami0AV//+tfZvHmz46PvaFRWVlJaWtriz8GDBzvsnn379gWguLi4wXu9evXi0KFDLX7HrFmzKCsr48MPP2T58uWsW7fO0bSMGDGizW376le/ihCCe+65B9M0m7yusrKSc889l4qKChYsWOD0qSUcOXIkoeddWlra5j60hKeffpqCggK+8pWvtPqzR44c4aWXXmLatGmN/v00NFSHZkY0NNqA3/72twQCAX7wgx/QpUsXvvWtb3Xo999www2ea0YmTZoENK7t2LNnD6NGjUroe/Ly8pg6darz/7feeoucnBxOOumkNrftoosu4uyzz+bKK6+k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", + "text/plain": [ + "
      " + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "_=wntr.graphics.plot_network(\n", + " wn, node_attribute=res.node['T1'].loc[3600*12,:], \n", + " title='12 h', node_colorbar_label='River\\nFraction',\n", + ")\n", + "_=wntr.graphics.plot_network(\n", + " wn, node_attribute=res.node['T1'].loc[3600*24,:], \n", + " title='24 h', node_colorbar_label='River\\nFraction',\n", + ")\n", + "_=wntr.graphics.plot_network(\n", + " wn, node_attribute=res.node['T1'].loc[3600*36,:], \n", + " title='36 h', node_colorbar_label='River\\nFraction',\n", + ")\n", + "query = '117' # '191', '269', '117'\n", + "res.node['CL2'][query].plot()\n", + "res.node['T1'][query].plot()\n", + "plt.title('Node {}\\nk1 = {:.1f}, k2 = {:.1f}'.format(query, k1.value, k2.value))\n", + "_=plt.legend(['Cl2', 'T1'])" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": {}, + "outputs": [], + "source": [ + "d_k1 = dict()\n", + "for i in range(7):\n", + " newk = 1.3 + (2*i*1.3)\n", + " k1.value = newk\n", + " resk = sim.run_sim()\n", + " d_k1[newk] = resk" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "Text(0.5, 1.0, 'Cl2 at node 117')" + ] + }, + "execution_count": 24, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAiMAAAGzCAYAAAD9pBdvAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8g+/7EAAAACXBIWXMAAA9hAAAPYQGoP6dpAADG2UlEQVR4nOzdd3iUVfbA8e/UZCaV9IQEEnqHAIIUBSsCYu+7gIqoq+gquiq/xb6K7trYXRuKYK8g6qIgqAgIqDTpLRBCKullkkx9f3+8mYGQQsokk5DzeZ48mUzeciZicubec8/VKIqiIIQQQgjhI1pfByCEEEKIjk2SESGEEEL4lCQjQgghhPApSUaEEEII4VOSjAghhBDCpyQZEUIIIYRPSTIihBBCCJ+SZEQIIYQQPiXJiBBCCCF8SpIRIdqZxMREbr75Zl+H0aZoNBqeeOIJX4chhGgiSUaEaCNSUlK444476NatG/7+/gQHBzNmzBjmz59PRUVFneft27ePhx56iCFDhhAUFERsbCyTJ09m8+bNXo1vz549PPHEE6Smpnr1um3R999/z4wZMxgwYAA6nY7ExMQ6j33mmWe47LLLiI6OrjcpSkxMRKPR1PrRs2fPlnkhQrQTel8HIISA5cuXc+211+Ln58e0adMYMGAANpuN9evX87e//Y3du3ezYMGCWs99++23WbhwIVdffTV33XUXxcXFvPnmm5x99tmsWLGCCy+80Csx7tmzhyeffJLx48fX+8f5TPDRRx/x6aefMnToUOLi4uo9du7cucTExJCcnMzKlSvrPO6VV16hrKys2nNHjx5l7ty5XHzxxV6JW4j2SpIRIXzsyJEj3HDDDXTt2pUff/yR2NhYz/fuvvtuDh06xPLly+s8/8Ybb+SJJ54gMDDQ89ytt95K3759eeKJJ7yWjHQkzz77LG+99RYGg4FLL72UXbt21XnskSNHSExMJC8vj8jIyDqPu+KKK2o8949//AOAP/3pT82OWYj2TKZphPCxf/7zn5SVlbFw4cJqiYhbjx49+Otf/1rn+cOGDauWiACEh4dzzjnnsHfv3tPe/+jRo9x111307t0bk8lEeHg41157bbXpmMWLF3PttdcCcN5553mmF9asWVPndW+++WYCAwPJyMjgiiuuIDAwkMjISB588EGcTme1Yy0WCw888AAJCQn4+fnRu3dvXnjhBU7dVNxqtXL//fcTGRlJUFAQl112Genp6bXePyMjg1tvvZXo6Gj8/Pzo378/77zzzml/HgBxcXEYDIYGHducUaKPPvqIpKQkRo8e3eRrCHEmkJERIXzsm2++oVu3bl7/g5SdnU1ERMRpj/v999/ZsGEDN9xwA/Hx8aSmpvL6668zfvx49uzZg9ls5txzz+Xee+/l3//+N//3f/9H3759ATyf6+J0OpkwYQIjR47khRdeYPXq1bz44ot0796dv/zlLwAoisJll13GTz/9xIwZMxgyZAgrV67kb3/7GxkZGbz88sue691222188MEH3HTTTYwePZoff/yRyZMn17hvTk4OZ599NhqNhlmzZhEZGcl3333HjBkzKCkp4b777mvET7JlbNu2jb179/L3v//d16EI4XuKEMJniouLFUC5/PLLG3xO165dlenTp9d7zNq1axWNRqM8+uijp71eeXl5jec2btyoAMp7773nee7zzz9XAOWnn35qUJzTp09XAOWpp56q9nxycrIybNgwz9fLli1TAOUf//hHteOuueYaRaPRKIcOHVIURVG2b9+uAMpdd91V7bibbrpJAZTHH3/c89yMGTOU2NhYJS8vr9qxN9xwgxISElLra67L5MmTla5du572uNzc3Bpx1OeBBx5QAGXPnj0NjkWIM5VM0wjhQyUlJQAEBQV57ZrHjx/npptuIikpiYceeui0x5tMJs9ju91Ofn4+PXr0IDQ0lK1btzY7njvvvLPa1+eccw6HDx/2fP3tt9+i0+m49957qx33wAMPoCgK3333nec4oMZxp45yKIrCkiVLmDJlCoqikJeX5/mYMGECxcXFXnldzeFyufjkk09ITk4+7eiSEB2BTNMI4UPBwcEAlJaWeuV6FouFSy+9lNLSUtavX1+jlqQ2FRUVzJs3j0WLFpGRkVGtTqO4uLhZ8fj7+9co6uzUqROFhYWer48ePUpcXFyNhMz9R/ro0aOez1qtlu7du1c7rnfv3tW+zs3NpaioiAULFtS5Aun48eNNe0Fe8vPPP5ORkcH999/v0ziEaCskGRHCh4KDg4mLi6t3tUZD2Ww2rrrqKnbs2MHKlSsZMGBAg8675557WLRoEffddx+jRo0iJCQEjUbDDTfcgMvlalZMOp2uWec3hTvmP//5z0yfPr3WYwYNGtSaIdXw4YcfotVqufHGG30ahxBthSQjQvjYpZdeyoIFC9i4cSOjRo1q0jVcLhfTpk3jhx9+4LPPPmPcuHENPveLL75g+vTpvPjii57nKisrKSoqqnacRqNpUmyn07VrV1avXk1paWm10ZF9+/Z5vu/+7HK5SElJqTYasn///mrXc6+0cTqdbXJZs9VqZcmSJYwfP/60PUyE6CikZkQIH3vooYcICAjgtttuIycnp8b3U1JSmD9/fr3XuOeee/j000957bXXuOqqqxp1f51OV2MJ7X/+858ay28DAgIAaiQpzTVp0iScTif//e9/qz3/8ssvo9FomDhxIoDn87///e9qx73yyivVvtbpdFx99dUsWbKk1hGn3NxcL0bfeN9++y1FRUXSW0SIk8jIiBA+1r17dz766COuv/56+vbtW60D64YNG/j888/r3YvmlVde4bXXXmPUqFGYzWY++OCDat+/8sorPYlEbS699FLef/99QkJC6NevHxs3bmT16tWEh4dXO27IkCHodDqef/55iouL8fPz4/zzzycqKqpZr3/KlCmcd955/P3vfyc1NZXBgwfz/fff89VXX3Hfffd5akSGDBnCjTfeyGuvvUZxcTGjR4/mhx9+4NChQzWu+dxzz/HTTz8xcuRIZs6cSb9+/SgoKGDr1q2sXr2agoKCemPasWMHX3/9NQCHDh2iuLjY06Bs8ODBTJkyxXPs+++/z9GjRykvLwdg7dq1nmOnTp3qGdlx+/DDD/Hz8+Pqq69u4k9MiDOQT9fyCCE8Dhw4oMycOVNJTExUjEajEhQUpIwZM0b5z3/+o1RWVnqOO3Vpr3sJbV0fR44cqfe+hYWFyi233KJEREQogYGByoQJE5R9+/bVuoT4rbfeUrp166bodLrTLvOdPn26EhAQUOP5xx9/XDn1V09paaly//33K3FxcYrBYFB69uyp/Otf/1JcLle14yoqKpR7771XCQ8PVwICApQpU6Yox44dq3VJbU5OjnL33XcrCQkJisFgUGJiYpQLLrhAWbBgQb0/D0VRlEWLFtX58zz1ZzJu3Lg6jz3151NcXKz4+/srV1111WljEKIj0SjKKeOzQgghhBCtSGpGhBBCCOFTkowIIYQQwqckGRFCCCGET0kyIoQQQgifkmRECCGEED4lyYgQQgghfKpdND1zuVxkZmYSFBTUYi2phRBCCOFdiqJQWlpKXFwcWm3d4x/t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1tbarlWjaYRon22ybt06YTQaxR/+8Aexd+9e8eGHHwq73S7+/ve/h2zmzp0r4uPjxaJFi8SWLVvEr3/96xpDOIcOHSp++uknsXr1apGVlRUWqlhSUiJSU1PFbbfdJrZt2yYWLlwo7HZ7tVBFo9Eo5s+fL3bu3Clmz54dsdDeSZMmic6dO4dCez/77DORnJwsHn300ZBNW2+XsrIysXHjRrFx40YBiBdffFFs3LgxFBXSmurfEF9aol28Xq+49tprRXp6uti0aVPY87dqZExbbJfmpt2KESGEeOWVV0RmZqYwm81ixIgRYu3atZF2qUkANf69//77IZuKigpx3333iYSEBGG328X1118vcnJyws5z6NAhceWVVwqbzSaSk5PFww8/LHw+X5jNihUrxJAhQ4TZbBbdu3cPu0aQ1tqup4qR9tomX375pRgwYICwWCyiT58+4q233grbr2maePrpp0VqaqqwWCzisssuE7t37w6zKSwsFLfccouIjo4WsbGxYvLkyaKsrCzMZvPmzeKCCy4QFotFdO7cWcydO7eaLx9//LHo1auXMJvNon///uLrr79u/go3AIfDIR588EGRmZkprFar6N69u3jyySfDvlDaerusWLGixufIpEmThBCtq/4N8aW5qKtdDh48WOvzd8WKFW26XZobRYgqKQYlEolEIpFIWph2OWdEIpFIJBJJ60GKEYlEIpFIJBFFihGJRCKRSCQRRYoRiUQikUgkEUWKEYlEIpFIJBFFihGJRCKRSCQRRYoRiUQikUgkEUWKEYlEIpFIJBFFihGJRCKRSCQRRYoRiUQikUgkEUWKEYlEIpFIJBHl/wM4QR3ugt7bjQAAAABJRU5ErkJggg==", + "text/plain": [ + "
      " + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "res.node[\"T1\"].loc[0:3600*36, query].plot(style='k.:')\n", + "for newk, resk in d_k1.items():\n", + " resk.node[\"CL2\"].loc[0:3600*36, query].plot()\n", + "plt.legend(['Tracer', *[\"{:.1f}\".format(k) for k in d_k1.keys()]], title=\"k1 (1/day)\")\n", + "plt.title(\"Cl2 at node {}\".format(query))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.12.1" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/examples/networks/msx_as.inp b/examples/networks/msx_as.inp new file mode 100644 index 000000000..0887e00db --- /dev/null +++ b/examples/networks/msx_as.inp @@ -0,0 +1,36 @@ +[TITLE] +EPANET-MSX Example Network + +[JUNCTIONS] +;ID Elev Demand Pattern + A 0 4.1 + B 0 3.4 + C 0 5.5 + D 0 2.3 + +[RESERVOIRS] +;ID Head Pattern + Source 100 + +[PIPES] +;ID Node1 Node2 Length Diameter Roughness + 1 Source A 1000 200 100 + 2 A B 800 150 100 + 3 A C 1200 200 100 + 4 B C 1000 150 100 + 5 C D 2000 150 100 + +[TIMES] + Duration 48 + Hydraulic Timestep 1:00 + Quality Timestep 0:05 + Report Timestep 2 + Report Start 0 + Statistic NONE + +[OPTIONS] + Units CMH + Headloss H-W + Quality NONE + +[END] diff --git a/wntr/epanet/msx/io.py b/wntr/epanet/msx/io.py index fc271d30e..5ac252e09 100644 --- a/wntr/epanet/msx/io.py +++ b/wntr/epanet/msx/io.py @@ -779,7 +779,7 @@ def _write_quality(self, fout): for node, conc in getattr(val, typ).items(): fout.write(" {:<8s} {:<8s} {:<8s} {}\n".format(typ.upper()[0:4], node, species, conc)) if val.global_value: - fout.write(" {:<8s} {:<8s} {}\n".format("GLOBAL", species, val)) + fout.write(" {:<8s} {:<8s} {}\n".format("GLOBAL", species, val.global_value)) fout.write("\n") def _write_parameters(self, fout): diff --git a/wntr/msx/model.py b/wntr/msx/model.py index 49bf90058..be46e2201 100644 --- a/wntr/msx/model.py +++ b/wntr/msx/model.py @@ -755,7 +755,7 @@ def from_dict(cls, data) -> "MsxModel": ver = data.get("wntr-version", None) if ver != __version__: logger.warn("Importing from a file created by a different version of wntr, compatibility not guaranteed") - warnings.warn("Importing from a file created by a different version of wntr, compatibility not guaranteed") + # warnings.warn("Importing from a file created by a different version of wntr, compatibility not guaranteed") new = cls() new.name = data.get("name", None) new.title = data.get("title", None) From 168e59d8701ec0cdb6438701699e425bd5ee4787 Mon Sep 17 00:00:00 2001 From: David Hart Date: Sun, 5 May 2024 09:22:48 -0600 Subject: [PATCH 67/75] Update to MSX demo --- examples/demos/multisource-cl-decay.ipynb | 196 ++++++++++++++++++---- 1 file changed, 165 insertions(+), 31 deletions(-) diff --git a/examples/demos/multisource-cl-decay.ipynb b/examples/demos/multisource-cl-decay.ipynb index a6d2edd9c..eb4877902 100644 --- a/examples/demos/multisource-cl-decay.ipynb +++ b/examples/demos/multisource-cl-decay.ipynb @@ -1,12 +1,25 @@ { "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# WNTR / EPANET-MSX demo\n", + "This demo shows a simple example of multispecies chlorine decay taken from the \n", + "EPANETMSX user manual. The Net3 example network from EPANET is used, and two \n", + "different decay coefficients are assigned - one for each source of water.\n", + "The river uses decay coefficient k1, the lake uses decay coefficient k2, and \n", + "the two values are an order of magnitude different. Once the initial example,\n", + "from the EPANETMSX user manual, has been run, parameter sensitivity is performed\n", + "to look at the impacts of different decay coefficients for the river source." + ] + }, { "cell_type": "code", - "execution_count": 15, + "execution_count": 1, "metadata": {}, "outputs": [], "source": [ - "import pandas as pd\n", "import matplotlib.pyplot as plt\n", "import wntr\n", "from wntr.msx.elements import InitialQuality\n", @@ -14,60 +27,171 @@ "wn.options.quality.parameter = 'NONE'" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Create a new MSX model" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "wn.add_msx_model()\n", + "wn.msx.title = 'Multisource Chlorine Decay'\n", + "wn.msx.references.append(\"\"\"(2023) Shang F, L Rossman, and J Uber. \n", + "\"EPANET-MSX 2.0 User Manual\". EPA/600/R-22/199\"\"\")\n", + "wn.msx.options.area_units = 'FT2'\n", + "wn.msx.options.rate_units = 'DAY'\n", + "wn.msx.options.timestep = 300" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Add the species" + ] + }, { "cell_type": "code", - "execution_count": 16, + "execution_count": 3, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "Reaction(species_name='CL2', expression_type=, expression='-(k1*T1 + k2*(1-T1))*CL2')" + "Species(name='CL2', species_type=, units='MG', atol=None, rtol=None, note='Free Chlorine')" ] }, - "execution_count": 16, + "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "wn.add_msx_model()\n", - "wn.msx.options.area_units = 'FT2'\n", - "wn.msx.options.rate_units = 'DAY'\n", - "wn.msx.options.timestep = 300\n", + "# Add the species\n", "wn.msx.add_species('T1','bulk',units='MG', note='Source 1 Tracer')\n", - "wn.msx.add_species('CL2','bulk', units='MG', note='Free Chlorine')\n", - "k1 = wn.msx.add_constant('k1', 1.3)\n", - "k2 = wn.msx.add_constant('k2', 17.7)\n", + "wn.msx.add_species('CL2','bulk', units='MG', note='Free Chlorine')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Add the coefficients" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "Constant(name='k2', value=17.7, units='1/day')" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Add the constant coefficients\n", + "k1 = wn.msx.add_constant('k1', 1.3, units='1/day')\n", + "k2 = wn.msx.add_constant('k2', 17.7, units='1/day')\n", + "k2" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Add the recations" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "Reaction(species_name='CL2', expression_type=, expression='-(k1*T1 + k2*(1-T1))*CL2')" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Add the reactions\n", "wn.msx.add_reaction('T1', 'pipe', 'rate', '0')\n", - "wn.msx.add_reaction('CL2', 'pipe', 'rate', '-(k1*T1 + k2*(1-T1))*CL2')\n", - "wn.msx.add_reaction('T1', 'tank', 'rate', '0')\n", - "wn.msx.add_reaction('CL2', 'tank', 'rate', '-(k1*T1 + k2*(1-T1))*CL2')" + "wn.msx.add_reaction('CL2', 'pipe', 'rate', '-(k1*T1 + k2*(1-T1))*CL2')\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Set up the initial quality" ] }, { "cell_type": "code", - "execution_count": 17, + "execution_count": 6, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "{'T1': InitialQuality(global_value=0.0, node_values=<1 entries>, link_values=<0 entries>),\n", + " 'CL2': InitialQuality(global_value=0.0, node_values=<2 entries>, link_values=<0 entries>)}" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ - "wn.msx.network_data.initial_quality['T1'] = InitialQuality(node_values={'River': 1.0})\n", - "wn.msx.network_data.initial_quality['CL2'] = InitialQuality(node_values={'River':1.2, 'Lake':1.2})" + "net_data = wn.msx.network_data\n", + "net_data.initial_quality['T1'] = InitialQuality(\n", + " node_values={'River': 1.0}\n", + ")\n", + "net_data.initial_quality['CL2'] = InitialQuality(\n", + " node_values={'River':1.2, 'Lake':1.2}\n", + ")\n", + "net_data.initial_quality" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Run the simulation and view the results" ] }, { "cell_type": "code", - "execution_count": 18, + "execution_count": 7, "metadata": {}, "outputs": [], "source": [ "sim = wntr.sim.EpanetSimulator(wn)\n", - "res = sim.run_sim()" + "res = sim.run_sim()\n" ] }, { "cell_type": "code", - "execution_count": 25, + "execution_count": 8, "metadata": {}, "outputs": [ { @@ -102,7 +226,7 @@ }, { "data": { - "image/png": "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Z1uDmpoa6urqWrwuIyODgoKCDrnn+++/T11dHcOGDePiiy/m5ZdfxjRNpk6dyoMPPsjEiROb/Xx9fT3dunVr8Lrt2lmxYgXDhw9vVxuPHDnCV7/6VZYvX85bb73Fl770pSavFUJQVlYWV4m4KdTX11NdXZ1QGzrqb9wY5s+fT0VFRZuNCV15WKOzQhsjGhptxLp16zjzzDPp168fb7zxRqMbcVsxa9Ys/vGPf7R43amnntqsJqE1sJmLOXPmMHToUP75z39SWVnJnXfeyRlnnMHnn39Onz59mvz8yJEjee+996iuro5jYt5//30Adu/e3a721dTU8JWvfIXPP/+ct99+u0Xj6Omnn2b37t388pe/bPG7n332Wa666qqE2iGSWFv06aefJisri4svvrjVn41EIjz//PNMnjyZYcOGJaF1GhrJgzZGNDTagDVr1jBjxgyGDRvG66+/TteuXTv0+2+++Wa+/e1vt3hdRxpANTU1gBXhsWjRIvLz8wE49thjHXbk17/+dZOfv+6663j11VeZMWMGd911F3l5efzlL39h+fLlgMVqtBWVlZWcffbZbNmyhcWLF7fIdqxbt47rr7+eqVOnMnPmzBa/f/r06SxcuLDN7esIVFVV8dprr3HeeedRWFjY6s8vWrSIsrIybrvtto5vnIZGkqGNEQ2NNuCCCy6guLiYN954w9m0OxJjxoxhzJgxHf69zSEnJwew+ubu0wknnMDgwYMdfUZTOPfcc7n//vu59dZbOe644wAYNmwYd911FzfffHO7ntONN95IXV0dK1eubNEQKS0t5fzzz6egoIAXXngBv9/f4vf36dOnWdbHC/znP/+hrq6uXS4av9/PjBkzOrhlGhrJhxawami0AV//+tfZvHmz46PvaFRWVlJaWtriz8GDBzvsnn379gWguLi4wXu9evXi0KFDLX7HrFmzKCsr48MPP2T58uWsW7fO0bSMGDGizW376le/ihCCe+65B9M0m7yusrKSc889l4qKChYsWOD0qSUcOXIkoeddWlra5j60hKeffpqCggK+8pWvtPqzR44c4aWXXmLatGmN/v00NFSHZkY0NNqA3/72twQCAX7wgx/QpUsXvvWtb3Xo999www2ea0YmTZoENK7t2LNnD6NGjUroe/Ly8pg6darz/7feeoucnBxOOumkNrftoosu4uyzz+bKK6+k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", + "image/png": "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eKLZ60477TQWLFjQbvdtCv369aOurg6AHj16cN9993H22We3+Xs/+ugjzj//fE455RT+85//kJ2d3eT1f/jDH+jSpQvnnXdes9/9la98hffee6/Z66ZPn87jjz+ebJNbhAMHDjB37lwuvvjiVjFUb731Fvv37281q6KhoRq0MaKh0U5YvXo106ZNY9iwYbz55pt06dKlXb//Zz/7Gd/5zneava49DaDm8Oabb1JbW8uaNWt46qmnqK6ubvN3vvvuu1x44YWcc845PPfccwSDwSavv+uuu3j77bf5+9//TkFBQbPf/+c//5mDBw82e12qRLgAL774IqFQqE0umqysLC655JJ2bpmGhhxoY0RDo51w4YUXUlRUxFtvvZUSen/UqFGMGjWq3b+3LTjjjDMAOO+88/jKV77C6NGjyc/P56abbmrV99XW1nLBBRcwYcIEXnjhBQKBppeo559/nttvv52rr76aG264Ial7TJgwoVVta088/fTTdO/ePSkm50hUVVXx6quvMnXqVHr06JGC1mloeA9tjGhotBO+/vWv88QTT/D0009z3XXXtfv3l5eXc/jw4WavCwaDdO/evd3v3xyGDh3Ksccey9NPP91qYyQ7O5vzzz+fV199lblz5/LlL3+50WvnzZvHFVdcwQUXXMBDDz2U9D0OHDhAKBRq9rrc3NyUaG+2b9/OBx98wPe+9z2ysrJa/PlXXnmFmpoa7aLRSCtoY0RDo53wxz/+kUAgwPe//306d+7c7lEON998s3KakSNx+PBhR0PSGtgJwL7yla/wzW9+kzfffJPTTz+93nWLFi3iq1/9Kscff3xSDIobX/va16RqRp599lmEEK02Jp5++mny8/O56KKL2rllGhryoI0RDY12gmEYPPzww1RWVjJ9+vR23zBkaUY2bdoEWMwHQCQSobKyst59Fi9ezKpVq9pshAWDQV566SWmTp3KhRdeyPz585k4caLz/po1a7jgggsYNGgQ//3vf1scWitbM/LMM88wYMAATj755Abf37dvH/v27WPAgAHk5eUlvFdWVsbbb7/NpZdeWu89DY2ODG2MaGi0I3w+H0899RQXX3wxl1xyCXPmzOHMM88ELDfL/fffD1jRIgB/+9vfKCgooKCgoFnXRntqRlrSFjtU1071XlVVRXFxMdOmTeOYY46hU6dOrFq1iscee4yuXbvy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Neeee64YN26c+OSTT8QHH3wghg0bJi699FLn/fLyclFUVCQuu+wysXr1avHss8+K3Nxc8Y9//MO55qOPPhJ+v1/84Q9/EF988YW4/fbbRVZWlli1alWL2pIqTJ06VTz22GNi9erVYvny5eL8888XAwYMEFVVVc41119/vSguLhbz588XS5YsESeccII48cQTnfcjkYgYPXq0mDJlili2bJmYM2eOKCwsFDNnznSu2bx5s8jLyxMzZswQX3zxhbj//vuF3+8Xc+fOda5JZgw215ZU4rXXXhNvvPGGWL9+vVi3bp247bbbRFZWlli9enVSbcuU5+TG4sWLxaBBg8TYsWPFzTffnHT7MuVZzZo1SxxzzDFiz549zk9ZWVnSbcuU53TgwAExcOBAceWVV4pFixaJzZs3i7feekts3LjRuSbd1vSMNUYmTpwobrzxRuf/0WhU9O3bV8yePVtiq9oHRxojpmmK3r17iz/+8Y/Oa4cOHRLZ2dni2WefFUII8cUXXwhAfPrpp841b775pjAMQ+zatUsIIcTf//530a1bN1FXV+dc8/Of/1yMGDHC+f8ll1wiLrjggoT2TJo0SVx33XVJt8VL7N27VwDivffec9qSlZUl/v3vfzvXrFmzRgBi4cKFQgjL8PP5fKKkpMS55sEHHxRdunRxns3PfvYzccwxxyTca9q0aWLq1KnO/5sbg8m0xWt069ZN/POf/9TPqQFUVlaK4cOHi3nz5onTTjvNMUb0s4pj1qxZYty4cQ2+p59THD//+c/FySef3Oj76bimZ6SbJhQKsXTpUqZMmeK85vP5mDJlCgsXLpTYstRgy5YtlJSUJPS3a9euTJo0yenvwoULKSgo4Pjjj3eumTJlCj6fj0WLFjnXnHrqqQSDQeeaqVOnsm7dOg4ePOhc476PfY19n2Ta4iXKy8sB6N69OwBLly4lHA4ntG/kyJEMGDAg4VmNGTOGoqIi55qpU6dSUVHB559/7lzT1HNIZgwm0xavEI1Gee6556iurmby5Mn6OTWAG2+8kQsuuKBef/SzSsSGDRvo27cvQ4YM4bLLLmP79u1Jty1TntNrr73G8ccfzze/+U169erFscceyyOPPOK8n45rekYaI/v27SMajSYMaICioiJKSkoktSp1sPvUVH9LSkro1atXwvuBQIDu3bsnXNPQd7jv0dg17veba4tXME2TW265hZNOOonRo0c77QsGgxQUFDTavrY8h4qKCg4fPpzUGEymLanGqlWryM/PJzs7m+uvv56XX36ZUaNG6ed0BJ577jk+++wzZs+eXe89/azimDRpEo8//jhz587lwQcfZMuWLZxyyilUVlbq5+TC5s2befDBBxk+fDhvvfUWN9xwAz/84Q954oknnPbZ7WmqDx1pTe8QVXs1NFKBG2+8kdWrV/Phhx/KboqyGDFiBMuXL6e8vJwXX3yR6dOn895778lullLYsWMHN998M/PmzSMnJ0d2c5TGeeed5/w+duxYJk2axMCBA3nhhRfIzc2V2DK1YJomxx9/PHfddRcAxx57LKtXr+ahhx5i+vTpkluXGmQkM1JYWIjf76+njC4tLaV3796SWpU62H1qqr+9e/dm7969Ce9HIhEOHDiQcE1D3+G+R2PXuN9vri1e4KabbuK///0v7777Lv3793de7927N6FQiEOHDjXavrY8hy5dupCbm5vUGEymLalGMBhk2LBhTJgwgdmzZzNu3Dj++te/6ufkwtKlS9m7dy/HHXccgUCAQCDAe++9x3333UcgEKCoqEg/q0ZQUFDAUUcdxcaNG/WYcqFPnz6MGjUq4bWjjz7acWml45qekcZIMBhkwoQJzJ8/33nNNE3mz5/P5MmTJbYsNRg8eDC9e/dO6G9FRQWLFi1y+jt58mQOHTrE0qVLnWveeecdTNNk0qRJzjXvv/8+4XDYuWbevHmMGDGCbt26Ode472NfY98nmbakEkIIbrrpJl5++WXeeecdBg8enPD+hAkTyMrKSmjfunXr2L59e8KzWrVqVcJEnzdvHl26dHEWkOaeQzJjMJm2eA3TNKmrq9PPyYWzzjqLVatWsXz5cufn+OOP57LLLnN+18+qYVRVVbFp0yb69Omjx5QLJ510Ur2UA+vXr2fgwIFAmq7pSUtd0wzPPfecyM7OFo8//rj44osvxPe+9z1RUFCQoNLuSKisrBTLli0Ty5YtE4C45557xLJly8S2bduEEFboVUFBgXj11VfFypUrxVe+8pUGw8COPfZYsWjRIvHhhx+K4cOHJ4SBHTp0SBQVFYnLL79crF69Wjz33HMiLy+vXhhYIBAQf/rTn8SaNWvErFmzGgwDa64tqcINN9wgunbtKhYsWJAQXlhTU+Ncc/3114sBAwaId955RyxZskRMnjxZTJ482XnfDi8855xzxPLly8XcuXNFz549Gwwv/OlPfyrWrFkjHnjggQbDC5sbg821JZW49dZbxXvvvSe2bNkiVq5cKW699VZhGIb43//+l1TbMuU5NQR3NE0y7cuUZ/XjH/9YLFiwQGzZskV89NFHYsqUKaKwsFDs3bs3qbZlynNavHixCAQC4ne/+53YsGGDePrpp0VeXp546qmnnGvSbU3PWGNECCHuv/9+MWDAABEMBsXEiRPFJ598IrtJrca7774rgHo/06dPF0JY4Ve//OUvRVFRkcjOzhZnnXWWWLduXcJ37N+/X1x66aUiPz9fdOnSRVx11VWisrIy4ZoVK1aIk08+WWRnZ4t+/fqJu+++u15bXnjhBXHUUUeJYDAojjnmGPHGG28kvJ9MW1KFhp4RIB577DHnmsOHD4vvf//7olu3biIvL0989atfFXv27En4nq1bt4rzzjtP5ObmisLCQvHjH/9YhMPhhGveffddMX78eBEMBsWQIUMS7mGjuTGYTFtShe9+97ti4MCBIhgMip49e4qzzjrLMUSSbVsmPKeGcKQxop+VhWnTpok+ffqIYDAo+vXrJ6ZNm5aQO0M/pzhef/11MXr0aJGdnS1GjhwpHn744YT3021NN4QQInkeRUNDQ0NDQ0OjfZGRmhENDQ0NDQ0NdaCNEQ0NDQ0NDQ2p0MaIhoaGhoaGhlRoY0RDQ0NDQ0NDKrQxoqGhoaGhoSEV2hjR0NDQ0NDQkAptjGhoaGhoaGhIhTZGNDQ0NDQ0NKRCGyMaGhoaGhoaUqGNEQ0NDQ0NDQ2p0MaIhoaGhoaGhlRoY0RDQ0NDQ0NDKv4fPxzDAcJCT+0AAAAASUVORK5CYII=", "text/plain": [ "
      " ] @@ -131,14 +255,22 @@ "_=plt.legend(['Cl2', 'T1'])" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Perform analysis of different k1 values" + ] + }, { "cell_type": "code", - "execution_count": 22, + "execution_count": 9, "metadata": {}, "outputs": [], "source": [ "d_k1 = dict()\n", "for i in range(7):\n", + " # Increase the reaction rate\n", " newk = 1.3 + (2*i*1.3)\n", " k1.value = newk\n", " resk = sim.run_sim()\n", @@ -147,22 +279,22 @@ }, { "cell_type": "code", - "execution_count": 24, + "execution_count": 10, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "Text(0.5, 1.0, 'Cl2 at node 117')" + "Text(0, 0.5, 'River Fraction [/100%] // Concentraion [mg/L]')" ] }, - "execution_count": 24, + "execution_count": 10, "metadata": {}, "output_type": "execute_result" }, { "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAiMAAAGzCAYAAAD9pBdvAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8g+/7EAAAACXBIWXMAAA9hAAAPYQGoP6dpAADG2UlEQVR4nOzdd3iUVfbA8e/UZCaV9IQEEnqHAIIUBSsCYu+7gIqoq+gquiq/xb6K7trYXRuKYK8g6qIgqAgIqDTpLRBCKullkkx9f3+8mYGQQsokk5DzeZ48mUzeciZicubec8/VKIqiIIQQQgjhI1pfByCEEEKIjk2SESGEEEL4lCQjQgghhPApSUaEEEII4VOSjAghhBDCpyQZEUIIIYRPSTIihBBCCJ+SZEQIIYQQPiXJiBBCCCF8SpIRIdqZxMREbr75Zl+H0aZoNBqeeOIJX4chhGgiSUaEaCNSUlK444476NatG/7+/gQHBzNmzBjmz59PRUVFneft27ePhx56iCFDhhAUFERsbCyTJ09m8+bNXo1vz549PPHEE6Smpnr1um3R999/z4wZMxgwYAA6nY7ExMQ6j33mmWe47LLLiI6OrjcpSkxMRKPR1PrRs2fPlnkhQrQTel8HIISA5cuXc+211+Ln58e0adMYMGAANpuN9evX87e//Y3du3ezYMGCWs99++23WbhwIVdffTV33XUXxcXFvPnmm5x99tmsWLGCCy+80Csx7tmzhyeffJLx48fX+8f5TPDRRx/x6aefMnToUOLi4uo9du7cucTExJCcnMzKlSvrPO6VV16hrKys2nNHjx5l7ty5XHzxxV6JW4j2SpIRIXzsyJEj3HDDDXTt2pUff/yR2NhYz/fuvvtuDh06xPLly+s8/8Ybb+SJJ54gMDDQ89ytt95K3759eeKJJ7yWjHQkzz77LG+99RYGg4FLL72UXbt21XnskSNHSExMJC8vj8jIyDqPu+KKK2o8949//AOAP/3pT82OWYj2TKZphPCxf/7zn5SVlbFw4cJqiYhbjx49+Otf/1rn+cOGDauWiACEh4dzzjnnsHfv3tPe/+jRo9x111307t0bk8lEeHg41157bbXpmMWLF3PttdcCcN5553mmF9asWVPndW+++WYCAwPJyMjgiiuuIDAwkMjISB588EGcTme1Yy0WCw888AAJCQn4+fnRu3dvXnjhBU7dVNxqtXL//fcTGRlJUFAQl112Genp6bXePyMjg1tvvZXo6Gj8/Pzo378/77zzzml/HgBxcXEYDIYGHducUaKPPvqIpKQkRo8e3eRrCHEmkJERIXzsm2++oVu3bl7/g5SdnU1ERMRpj/v999/ZsGEDN9xwA/Hx8aSmpvL6668zfvx49uzZg9ls5txzz+Xee+/l3//+N//3f/9H3759ATyf6+J0OpkwYQIjR47khRdeYPXq1bz44ot0796dv/zlLwAoisJll13GTz/9xIwZMxgyZAgrV67kb3/7GxkZGbz88sue691222188MEH3HTTTYwePZoff/yRyZMn17hvTk4OZ599NhqNhlmzZhEZGcl3333HjBkzKCkp4b777mvET7JlbNu2jb179/L3v//d16EI4XuKEMJniouLFUC5/PLLG3xO165dlenTp9d7zNq1axWNRqM8+uijp71eeXl5jec2btyoAMp7773nee7zzz9XAOWnn35qUJzTp09XAOWpp56q9nxycrIybNgwz9fLli1TAOUf//hHteOuueYaRaPRKIcOHVIURVG2b9+uAMpdd91V7bibbrpJAZTHH3/c89yMGTOU2NhYJS8vr9qxN9xwgxISElLra67L5MmTla5du572uNzc3Bpx1OeBBx5QAGXPnj0NjkWIM5VM0wjhQyUlJQAEBQV57ZrHjx/npptuIikpiYceeui0x5tMJs9ju91Ofn4+PXr0IDQ0lK1btzY7njvvvLPa1+eccw6HDx/2fP3tt9+i0+m49957qx33wAMPoCgK3333nec4oMZxp45yKIrCkiVLmDJlCoqikJeX5/mYMGECxcXFXnldzeFyufjkk09ITk4+7eiSEB2BTNMI4UPBwcEAlJaWeuV6FouFSy+9lNLSUtavX1+jlqQ2FRUVzJs3j0WLFpGRkVGtTqO4uLhZ8fj7+9co6uzUqROFhYWer48ePUpcXFyNhMz9R/ro0aOez1qtlu7du1c7rnfv3tW+zs3NpaioiAULFtS5Aun48eNNe0Fe8vPPP5ORkcH999/v0ziEaCskGRHCh4KDg4mLi6t3tUZD2Ww2rrrqKnbs2MHKlSsZMGBAg8675557WLRoEffddx+jRo0iJCQEjUbDDTfcgMvlalZMOp2uWec3hTvmP//5z0yfPr3WYwYNGtSaIdXw4YcfotVqufHGG30ahxBthSQjQvjYpZdeyoIFC9i4cSOjRo1q0jVcLhfTpk3jhx9+4LPPPmPcuHENPveLL75g+vTpvPjii57nKisrKSoqqnacRqNpUmyn07VrV1avXk1paWm10ZF9+/Z5vu/+7HK5SElJqTYasn///mrXc6+0cTqdbXJZs9VqZcmSJYwfP/60PUyE6CikZkQIH3vooYcICAjgtttuIycnp8b3U1JSmD9/fr3XuOeee/j000957bXXuOqqqxp1f51OV2MJ7X/+858ay28DAgIAaiQpzTVp0iScTif//e9/qz3/8ssvo9FomDhxIoDn87///e9qx73yyivVvtbpdFx99dUsWbKk1hGn3NxcL0bfeN9++y1FRUXSW0SIk8jIiBA+1r17dz766COuv/56+vbtW60D64YNG/j888/r3YvmlVde4bXXXmPUqFGYzWY++OCDat+/8sorPYlEbS699FLef/99QkJC6NevHxs3bmT16tWEh4dXO27IkCHodDqef/55iouL8fPz4/zzzycqKqpZr3/KlCmcd955/P3vfyc1NZXBgwfz/fff89VXX3Hfffd5akSGDBnCjTfeyGuvvUZxcTGjR4/mhx9+4NChQzWu+dxzz/HTTz8xcuRIZs6cSb9+/SgoKGDr1q2sXr2agoKCemPasWMHX3/9NQCHDh2iuLjY06Bs8ODBTJkyxXPs+++/z9GjRykvLwdg7dq1nmOnTp3qGdlx+/DDD/Hz8+Pqq69u4k9MiDOQT9fyCCE8Dhw4oMycOVNJTExUjEajEhQUpIwZM0b5z3/+o1RWVnqOO3Vpr3sJbV0fR44cqfe+hYWFyi233KJEREQogYGByoQJE5R9+/bVuoT4rbfeUrp166bodLrTLvOdPn26EhAQUOP5xx9/XDn1V09paaly//33K3FxcYrBYFB69uyp/Otf/1JcLle14yoqKpR7771XCQ8PVwICApQpU6Yox44dq3VJbU5OjnL33XcrCQkJisFgUGJiYpQLLrhAWbBgQb0/D0VRlEWLFtX58zz1ZzJu3Lg6jz3151NcXKz4+/srV1111WljEKIj0SjKKeOzQgghhBCtSGpGhBBCCOFTkowIIYQQwqckGRFCCCGET0kyIoQQQgifkmRECCGEED4lyYgQQgghfKpdND1zuVxkZmYSFBTUYi2phRBCCOFdiqJQWlpKXFwcWm3d4x/t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1tbarlWjaYRon22ybt06YTQaxR/+8Aexd+9e8eGHHwq73S7+/ve/h2zmzp0r4uPjxaJFi8SWLVvEr3/96xpDOIcOHSp++uknsXr1apGVlRUWqlhSUiJSU1PFbbfdJrZt2yYWLlwo7HZ7tVBFo9Eo5s+fL3bu3Clmz54dsdDeSZMmic6dO4dCez/77DORnJwsHn300ZBNW2+XsrIysXHjRrFx40YBiBdffFFs3LgxFBXSmurfEF9aol28Xq+49tprRXp6uti0aVPY87dqZExbbJfmpt2KESGEeOWVV0RmZqYwm81ixIgRYu3atZF2qUkANf69//77IZuKigpx3333iYSEBGG328X1118vcnJyws5z6NAhceWVVwqbzSaSk5PFww8/LHw+X5jNihUrxJAhQ4TZbBbdu3cPu0aQ1tqup4qR9tomX375pRgwYICwWCyiT58+4q233grbr2maePrpp0VqaqqwWCzisssuE7t37w6zKSwsFLfccouIjo4WsbGxYvLkyaKsrCzMZvPmzeKCCy4QFotFdO7cWcydO7eaLx9//LHo1auXMJvNon///uLrr79u/go3AIfDIR588EGRmZkprFar6N69u3jyySfDvlDaerusWLGixufIpEmThBCtq/4N8aW5qKtdDh48WOvzd8WKFW26XZobRYgqKQYlEolEIpFIWph2OWdEIpFIJBJJ60GKEYlEIpFIJBFFihGJRCKRSCQRRYoRiUQikUgkEUWKEYlEIpFIJBFFihGJRCKRSCQRRYoRiUQikUgkEUWKEYlEIpFIJBFFihGJRCKRSCQRRYoRiUQikUgkEUWKEYlEIpFIJBHl/wM4QR3ugt7bjQAAAABJRU5ErkJggg==", + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAjcAAAHHCAYAAABDUnkqAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8g+/7EAAAACXBIWXMAAA9hAAAPYQGoP6dpAADOkUlEQVR4nOzdd3jTVdvA8W92k+69oYyyZJUhFETQB0VUhltxoIAbfRQnisiDeyE4EUUQFTcqvgio7L2RPQqF0r1X2iZp8nv/SBMoHSRt2qTlfK6rV9PkN+5WTO+ec5/7yCRJkhAEQRAEQWgl5O4OQBAEQRAEwZVEciMIgiAIQqsikhtBEARBEFoVkdwIgiAIgtCqiORGEARBEIRWRSQ3giAIgiC0KiK5EQRBEAShVRHJjSAIgiAIrYpIbgRBEARBaFVEciMIF7G4uDjuvfded4fhUWQyGTNmzHB3GIIgNIJIbgShFTpx4gQPPvgg7du3x8vLCz8/PwYPHsycOXMoLy+v87wjR47w7LPP0rt3b3x9fYmMjOS6665j586dLo3v0KFDzJgxg1OnTrn0up7or7/+YuLEiXTv3h2FQkFcXFydx7722muMHj2a8PDwepOsuLg4ZDJZrR/x8fFN840IQguidHcAgiC41rJly7jlllvQaDTcc889dO/eHaPRyMaNG3nmmWc4ePAg8+bNq/XcL774gvnz53PTTTfxyCOPUFRUxGeffcbAgQNZsWIFw4cPd0mMhw4d4n//+x/Dhg2r95d9a7B48WJ++OEH+vTpQ1RUVL3HTps2jYiICBISEli5cmWdx82ePZvS0tJqz50+fZpp06Zx9dVXuyRuQWjJRHIjCK1IcnIyt99+O23btmX16tVERkbaX3v00UdJSkpi2bJldZ5/xx13MGPGDHx8fOzPTZgwga5duzJjxgyXJTcXk9dff53PP/8clUrF9ddfz4EDB+o8Njk5mbi4OHJzcwkNDa3zuLFjx9Z47tVXXwXgzjvvbHTMgtDSiWkpQWhF3n77bUpLS5k/f361xMamY8eO/Pe//63z/L59+1ZLbACCg4MZMmQIhw8fvuD9T58+zSOPPELnzp3RarUEBwdzyy23VJt+WrhwIbfccgsAV1xxhX06Ze3atXVe995778XHx4e0tDTGjh2Lj48PoaGhPP3005jN5mrH6vV6nnrqKWJjY9FoNHTu3Jl3330XSZKqHWcwGHjyyScJDQ3F19eX0aNHk5qaWuv909LSmDBhAuHh4Wg0Gi655BK+/PLLC/48AKKiolCpVA4d25hRrMWLF9OuXTsGDRrU4GsIQmshRm4EoRX5448/aN++vct/wWVmZhISEnLB43bs2MHmzZu5/fbbiYmJ4dSpU3z66acMGzaMQ4cOodPpuPzyy3n88cf54IMPeOGFF+jatSuA/XNdzGYzI0aMYMCAAbz77rv8888/vPfee3To0IGHH34YAEmSGD16NGvWrGHixIn07t2blStX8swzz5CWlsb7779vv96kSZP45ptvGDduHIMGDWL16tVcd911Ne6blZXFwIEDkclkTJ48mdDQUJYvX87EiRMpLi7miSeecOIn2TT27NnD4cOHefHFF90diiB4BkkQhFahqKhIAqQxY8Y4fE7btm2l8ePH13vM+vXrJZlMJr300ksXvF5ZWVmN57Zs2SIB0qJFi+zP/fTTTxIgrVmzxqE4x48fLwHSzJkzqz2fkJAg9e3b1/71b7/9JgHSq6++Wu24m2++WZLJZFJSUpIkSZK0d+9eCZAeeeSRaseNGzdOAqSXX37Z/tzEiROlyMhIKTc3t9qxt99+u+Tv71/r91yX6667Tmrbtu0Fj8vJyakRR32eeuopCZAOHTrkcCyC0JqJaSlBaCWKi4sB8PX1ddk1s7OzGTduHO3atePZZ5+94PFardb+2GQykZeXR8eOHQkICGD37t2Njuehhx6q9vWQIUM4efKk/es///wThULB448/Xu24p556CkmSWL58uf04oMZx54/CSJLEL7/8wqhRo5AkidzcXPvHiBEjKCoqcsn31RgWi4Xvv/+ehISEC45+CcLFQkxLCUIr4efnB0BJSYlLrqfX67n++uspKSlh48aNNWpxalNeXs4bb7zBggULSEtLq1bnUlRU1Kh4vLy8ahTZBgYGUlBQYP/69OnTREVF1UjwbL/0T58+bf8sl8vp0KFDteM6d+5c7eucnBwKCwuZN29enSvMsrOzG/YNuci6detIS0vjySefdGscguBJRHIjCK2En58fUVFR9a7GcZTRaOTGG29k3759rFy5ku7duzt03mOPPcaCBQt44oknSExMxN/fH5lMxu23347FYmlUTAqFolHnN4Qt5rvuuovx48fXekzPnj2bM6Qavv32W+RyOXfccYdb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YcIE/ve//7Fjxw57orZnzx727dvHkiVL7Ne59NJLSU1N5dSpU8TFxTXsm28gh5v4/frrr4SFhTl0rK+vb4MDEgRBEJrOFxtO8uqywwDcNbANNyTEoFbIUSllqBRy1Ao5SoX1se1rlUKGQi6j07TlmMwSheVGtGqtm78Tz/bxxx/z4osv8scffzR6Ouj06dMoFAqHfwefKy0tjX379jFy5EgA5syZwzXXXMOzzz4LQKdOndi8eTMrVqywn9OrVy969epl//qVV17h119/ZenSpUyePJmYmBhGjBjBggUL7MnNggULGDp0KO3bt7efFxUVZY/fI5ObBQsW4O/v7/BFP/vsM8LDwxsclCAIguBakiTx0eok3vv7GAAPDe3Ac9d0dqqviL9WTW6pgcIyE5H+Irmpy88//0x2djabNm2y//JvjPLycjQaTYN6wCxdupTLLrvMvhrq8OHD3HDDDdWOSUxMrJbclJaWMmPGDJYtW0ZGRgaVlZWUl5eTkpJiP+b+++9nwoQJzJo1C7lczuLFi3n//ferXVertf4bKSsrczruxnIouRk/fvwFjzGbzWRlZREVFcW4ceMaHZggCILgGpIk8fbKo3y69gQAT13ViclXdnT6l2WATkVuqYGCMrE7dn0SEhLYvXs3X375Jf369Wt0Y7qQkBDKysowGo1Od0peunQpo0ePduqcp59+mr///pt3332Xjh07otVqufnmm6vtij5q1Cg0Gg2//vorarUak8nEzTffXO06+fn5gHVLhebmsr2lDhw4QJ8+fRrdMlkQBEFwHYtFYub/HWLh5lMATLuuK5OGtK//pDoE6qwFqUVlJleF1yp16NCB9957j2HDhqFQKPjoo48adb3evXsDcOjQIftjR5SWlrJmzZpqK5a6du3Ktm3bqh23devWal9v2rSJe++91z7CU1paWqNoWalUMn78eBYsWIBareb222+3j9TYHDhwAJVKxSWXXOJwzK4iNs4UBEFopcwWialL9vHjzlRkMnhtbA/GDWjT4Ov5a62jBoXlIrm5kE6dOrFmzRqGDRuGUqm097MxGo0cOnTI/jgtLY29e/fi4+NDx44da71WaGgoffr0YePGjdWSm/z8fFJSUkhPTwfg6NGjAERERBAREcGKFSvo1KlTtXqXxx9/nMGDB/Puu+8yZswYVq5cWW1KCiA+Pp4lS5YwatQo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008/odfrSUxMrPUYg8GAl5dXtee0Wi0bN25sUKju5nRyc9NNN7Ft2zbef/99fvvtNwC6du3K9u3bSUhIcHV8giBcpJzpQdOQ4uDmYKvrefDBBzGbzfa6nhKFH5IEYb4aQnw0bo2xMWw1NxfVFgymMng9yj33fiEd1N4OH75//34SExOpqKjAx8eHX3/9lW7dutV67IgRI5g1axaXX345HTp0YNWqVSxZsgSz2eyq6JuV08kNQN++ffnmm29cHYsgCALgfDfgupIId47a2NS2wuqbraeBlj1qA+fsDC6mpTxS586d2bt3L0VFRfz888+MHz+edevW1ZrgzJkzh/vvv58uXbogk8no0KED9913H19++aUbIm88h5Kb4uJi/Pz87I/rYztOEAShoRoyzdTQZdrNISYmplo8raHeBi7SaSmVzjqC4q57O0GtVttHL/v27cuOHTuYM2cOn332WY1jQ0ND+e2336ioqCAvL4+oqCief/552rdv75LQm5tDyU1gYCAZGRmEhYUREBBQ6x4itr1FWuoQliAInqOh00znJxGe6lBGy18pBRfptJRM5tTUkCexWCwYDIZ6j/Hy8iI6OhqTycQvv/zCrbfe2kzRuZZDyc3q1asJCgoCYM2aNU0akCAIgidPMzWW2SJxNLPl97gBCNRZR27EtJTnmTp1KiNHjqRNmzaUlJSwePFi1q5dy8qVKwG45557iI6O5o033gBg27ZtpKWl0bt3b9LS0pgxYwYWi4Vnn33Wnd9GgzmU3AwdOrTWx4IgCE3Fk6eZGuN0np4yoxkvlZx2IS1zBMDG3sSvXOwM7mmys7O55557yMjIwN/fn549e7Jy5UquuuoqAFJSUqrtlVZRUcG0adM4efIkPj4+XHvttXz99dcEBAS46TtonAYVFAOUlZWRkpKC0Vh9OLJnz56NDkoQhNbH0WXd52op00zOsHUm7hzhh0LespMBf601uTFbJEoMlfiJncE9xoWaWK5du7ba10OHDuXQoUNNGFHzcjq5ycnJ4b777quzjbOouREE4XzOLOtu7Wx7SnWL9HVzJI3npVKgVSkoN5kpKjOJ5EbwGE53KH7iiScoLCxk27ZtaLVaVqxYwVdffUV8fDxLly5tihgFQWjBGtM9uDVqDXtKneuiLCoWPJ7TIzerV6/m999/p1+/fsjlctq2bctVV12Fn58fb7zx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xYJnKCkp4YknnqBt27ZotVoGDRrEjh076jw+IyODcePG0alTJ+RyOU888UTzBetiTr+L9OvXj2XLltm/tiU0X3zxBYmJia6LTBCEVimv1MCkr3by8tKDGCstXNkljBVPDOHyTqHuDq112Pg+SBaIvxoie7n++nXuL1U1LaUXIzeeYtKkSfz99998/fXX7N+/n6uvvprhw4eTlpZW6/EGg4HQ0FCmTZtGr15N8G+nGTk9LfX6668zcuRIDh06RGVlJXPmzOHQoUNs3ry5Rt8bQRCEc204nsOUH/8lp8SAWinnhZFdGD8oToz6ukpRKvz7vfXxkKeb5h72guI69pdq5SM3kiQhlZe75d4yrdbh/1fKy8v55Zdf+P3337n88ssBmDFjBn/88Qeffvopr776ao1z4uLimDNnDgBffvml6wJ3A6eTm8suu4y9e/fy5ptv0qNHD/766y/69OnDli1b6NGjR1PEKAhCK/DN1tNM++0AAB3DfPjwjgS6Rvq5OapWZtMHYDFB3BBoM6Bp7mFbCm4sAVM5qLTAxbN5plReztE+fd1y7867dyHTObaje2VlJWazudrCHwCtVsvGjRubIjyP0qAGNR06dODzzz93dSyCILRi8zdaG4De0jeGmWO6o1WLRnwuVZoNu7+yPm6KWhsbL39rx2Oz0To1FdAGODstJQqKPYOvry+JiYm88sordO3alfDwcL777ju2bNlCx44d3R1ek3M6ufnzzz9RKBSMGDGi2vMrV67EYrEwcuRIlwUnCELrIEkS6YXWofzHrowXiU1T2PIxVFZAdF9oP6zp7iOTWetuitOqJzcXybSUTKul8+5dbru3M77++msmTJhAdHQ0CoWCPn36cMcdd7Brl3vib05OFxQ///zzmM3mGs9LksTzzz/vkqAEQWhdCspMGCqtu3eH+4umfC5Xlg875lsfD3nKmoA0JXtR8Tldii+SPjcymQy5TueWD2dr0zp06MC6desoLS3lzJkzbN++HZPJRPv27Zvop+M5nE5ujh8/Trdu3Wo836VLF5KSklwSlCAIrYtt1CbER4NGKUZtXG7TbGsNTHh36NQMo+e25OacLsW2kZsiMS3lcby9vYmMjKSgoICVK1cyZswYd4fU5JyelvL39+fkyZPExcVVez4pKQlvb29XxSUIQiuSUVQBQKS/1wWOFJxWnAHbPrM+vvIl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HDBgALt377Z/bTQaadPm7GZwbdq0oaKiwrXRCYLg8ezLwGvbV8pcae1hA5D4qOt2377ILD6ymApzBd2CuzEwcmCjr1f0yy8A+F41HG3v3qiiopB7e19wmkgda62TMZ05u9N6jRVT9s0za1/yndjBukt4S9yKQWg5HH6n+eijj5g0aRJPPvkker2el19+mb59+zJw4ED69u3LTTfdxGuvvdaUsQqC4IFsIze1LgM/vNS6S7cuBHrd3syRtQ5lpjIWH14MWGttGlunYikvp+iP/wMg4OabnTpX3caa3BhTziY3tqLiGl2K9TVHbsBaVAyw5WQeFkst+4UJggs4PC01YMAAduzYwdtvv03fvn15++23OXr0KNu2bcNsNtO/f3+io0XXSUG42NhqbqLOn5aSJNjykfVx/0mgEh3LG+LnYz9TbCymrV9b/tPmP42+Xslff2EpKUEVHY1uoHOjQKqYquTmTIr9uRqN/GzbZJTlW0fuztv7q2dMADq1gny9kWPZJXSJEG1DBNdzaoxYoVAwdepUli1bxocffsjDDz9M3759GTt2rEhsBOEiVFJhosRQCUDE+dNSKVshbZd15+7+k9wQXctnMptYdGgRAPddch8KuaLR1yz82Tol5X/TjcicnCa0jdyYzqTan6sxLaUNAmSABOX5Na+hlNMvLgiAzUliakpoGk79yz548CC//PILZrOZv//+m9GjRzNkyBA++eSTpopPEAQPZutx4+ulxEdz3kCwbdSm1+1nlwcLTlmWvIyssixCtaGM6jCq0dczJCdTtmMHyOUE3HCD0+erquosTampSBYLcLaRn33kRqEEnXXqqbaiYjg7NbVZ1N0ITcTh5GbWrFn079+fd955h8TERD7//HPGjx/Ptm3b2Lp1K4mJiezfv78pYxUEwcOk11VMnHcCjiyzPk6c3MxRtQ4WyWLfauHubnejVjR+a4qiJdYVV96XDUYV6fympKqICFAqkYxGKrOsyYxtWiq7LBuLZE146lsODmeTm23JeZhF3Y3QBBxObt5++22WLVvG1q1b2b17N7NmzQIgJCSERYsWMXPmTG699dYmC1QQBM+TWdcy8K2fABLEj4DQTs0fWCuw5swakouS8VX5ckunWxp9PclkovC33wDnC4ltZEolqugo4GxRcYguBBkyTBYTBRUF1gPtK6ZqT24uifLH10tJSUUl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3SoQCDRos3r1ajVixAhls9lUv379GpyjXkft2+8nN121Tz744AM1ZMgQZbfbVXZ2tvrzn//c4HFd19VvfvMblZKSoux2u5o8ebLavXt3gzalpaVq7ty5Kjo6WsXGxqobb7xRVVVVNWizdetWNWHCBGW321XPnj3VkiVLTojlzTffVAMGDFA2m02dc8456sMPP2z5H/g03G63uuOOO1Tv3r2Vw+FQ/fr1Uw8++GCDD6eu0CerV69u9H1k/vz5SqmO1QdNiaWlnKpf9u3bd9L339WrV3fqfmlpmlLHLZsphBBCCHGWkzk3QgghhOhUJLkRQgghRKciyY0QQgghOhVJboQQQgjRqUhyI4QQQohORZIbIYQQQnQqktwIIYQQolOR5EYIIU7ihhtuYM6cOe0dhhAiQpLcCCFa3ZEjR7jlllvo3bs3drud1NRUpk+fzpdfftneoQkhOiFLewcghOj8rrzySvx+P3/5y1/o168fxcXFrFq1itLS0vYOTQjRCcmVGyFEq6qoqOCLL77g97//PRdddBF9+vRh7Nix3H///Vx66aXhNj/96U/p3r07sbGxXHzxxWzdurXB63zwwQece+65OBwOunXrxuWXXx5+rLy8nOuvv56EhARcLhczZ84kNzc3/PjLL79MfHw8H3/8MYMGDSI6OpoZM2ZQWFgYbhMKhViwYAHx8fEkJSVx77338v3dad5++22GDh2K0+kkKSmJKVOmUFNT0xrdJoQ4A5LcCCFaVXR0NNHR0bz33nv4fL5G21x99dWUlJTw0UcfsWnTJkaNGsXkyZMpKysD4MMPP+Tyyy9n1qxZbN68mVWrVjF27Njw82+44QY2btzI+++/z7p161BKMWvWLAKBQLiNx+Phscce45VXXuHzzz/n4MGD/L//9//Cjz/++OO8/PLLvPjii6xdu5aysjLefffd8OOFhYXMnTuXm266iZ07d7JmzRquuOKKExIgIUQH0K7bdgohuoS3335bJSQkKIfDoc477zx1//33q61btyqllPriiy9UbGys8nq9DZ7Tv39/9dxzzymllBo/fryaN29eo6+9Z88eBagvv/wyfOzo0aPK6XSqN998Uyml1EsvvaQAlZeXF26zbNkylZKSEr6flpamli5dGr4fCARUr1691GWXXaaUUmrTpk0KUPv37z+DnhBCtAW5ciOEaHVXXnklBQUFvP/++8yYMYM1a9YwatQoXn75ZbZu3Up1dTVJSUnhqzzR0dHs27ePvXv3ArBlyxYmT57c6Gvv3LkTi8XCuHHjwseSkpIYOHAgO3fuDB9zuVz0798/fD8tLY2SkhIAKisrKSwsbPAaFouFMWPGhO8PHz6cyZMnM3ToUK6++mqef/55ysvLW6aDhBAtSiYUCyHahMPhYOrUqUydOpXf/OY3/PSnP2XRokXceuutpKWlsWbNmhOeEx8fD4DT6Tzj81ut1gb3NU2LaEjJbDazcuVKvvrqK/71r3/x9NNP8+CDD7J+/Xr69u17xvEJIVqOXLkRQrSLwYMHU1NTw6hRoygqKsJisZCZmdng1q1bNwCGDRvGqlWrGn2dQYMGEQwGWb9+ffhYaWkpu3fvZvDgwU2KJS4ujrS0tAavEQwG2bRpU4N2mqZx/vnn8/DDD7N582ZsNluDeTlCiI5BrtwIIVpVaWkpV199NTfddBPDhg0jJiaGjRs3snTpUi677DKmTJnC+PHjmTNnDkuXLmXAgAEUFBSEJxGPGTOGRYsWMXnyZPr3788Pf/hDgsEgy5cvZ+HChWRlZXHZZZdx880389xzzxETE8N9991Hz549ueyyy5oc5x133MGSJUvIysoiOzubP/zhD1RUVIQfX79+PatWrWLatGkkJyezfv16jhw5wqBBg1qh14QQZ0KSGyFEq4qOjmbcuHE88cQT7N27l0AgQHp6OjfffDMPPPAAmqaxfPlyHnzwQW688UaOHDlCamoqEydOJCUlBYALL7yQt956i9/+9rcsWbKE2NhYJk6cGD7HSy+9xB133MF//Md/4Pf7mThxIsuXLz9hKOpU7r77bgoLC5k/fz4mk4mbbrqJyy+/nMrKSgBiY2P5/PPPefLJJ3G73fTp04fHH3+cmTNntmyHCSHOmKYiGXQWQgghhOjgZM6NEEIIIToVSW6EEEII0alIciOEEEKITkWSGyGEEEJ0KpLcCCGEEKJTkeRGCCGEEJ2KJDdCCCGE6FQkuRFCCCFEpyLJjRBCCCE6FUluhBBCCNGpSHIjhBBCiE5FkhshhBBCdCr/Hyw6lgBntulcAAAAAElFTkSuQmCC", "text/plain": [ "
      " ] @@ -172,11 +304,13 @@ } ], "source": [ - "res.node[\"T1\"].loc[0:3600*36, query].plot(style='k.:')\n", + "res.node[\"T1\"].loc[0:3600*36, query].plot(style='k.')\n", "for newk, resk in d_k1.items():\n", " resk.node[\"CL2\"].loc[0:3600*36, query].plot()\n", "plt.legend(['Tracer', *[\"{:.1f}\".format(k) for k in d_k1.keys()]], title=\"k1 (1/day)\")\n", - "plt.title(\"Cl2 at node {}\".format(query))" + "plt.title(\"Cl2 at node {}\".format(query))\n", + "plt.xlabel('Seconds')\n", + "plt.ylabel('River Fraction [/100%] // Concentraion [mg/L]')" ] }, { @@ -207,5 +341,5 @@ } }, "nbformat": 4, - "nbformat_minor": 2 + "nbformat_minor": 4 } From 5ba02f3bd49adb6d103548ab9167ba2087dbac72 Mon Sep 17 00:00:00 2001 From: David Hart Date: Tue, 7 May 2024 11:04:54 -0600 Subject: [PATCH 68/75] Update to the MSX demo jupyter notebook. --- examples/demos/multisource-cl-decay.ipynb | 179 ++++++++++++---------- 1 file changed, 97 insertions(+), 82 deletions(-) diff --git a/examples/demos/multisource-cl-decay.ipynb b/examples/demos/multisource-cl-decay.ipynb index eb4877902..943f9e898 100644 --- a/examples/demos/multisource-cl-decay.ipynb +++ b/examples/demos/multisource-cl-decay.ipynb @@ -20,9 +20,23 @@ "metadata": {}, "outputs": [], "source": [ - "import matplotlib.pyplot as plt\n", + "from pprint import pprint" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Load the network model, optionally remove EPANET quality" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ "import wntr\n", - "from wntr.msx.elements import InitialQuality\n", "wn = wntr.network.WaterNetworkModel('../networks/Net3.inp')\n", "wn.options.quality.parameter = 'NONE'" ] @@ -31,12 +45,12 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "### Create a new MSX model" + "### Add a new MSX model to the water network, set options" ] }, { "cell_type": "code", - "execution_count": 2, + "execution_count": 3, "metadata": {}, "outputs": [], "source": [ @@ -53,115 +67,95 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "### Add the species" + "### Add the MSX reaction system information\n", + "This reaction system comes from the EPANET-MSX user manual. There are two species: Free Chlorine and a tracer. The tracer is used to select which decay coefficient is being used. The river is source 1, the lake is source 2.\n", + "\n", + "The amount of free chlorine is based on the rate reaction below, " ] }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 4, "metadata": {}, "outputs": [ { - "data": { - "text/plain": [ - "Species(name='CL2', species_type=, units='MG', atol=None, rtol=None, note='Free Chlorine')" - ] - }, - "execution_count": 3, - "metadata": {}, - "output_type": "execute_result" + "name": "stdout", + "output_type": "stream", + "text": [ + "(\"Species(name='CL2', species_type=, units='MG', \"\n", + " \"atol=None, rtol=None, note='Free Chlorine')\")\n" + ] } ], "source": [ - "# Add the species\n", - "wn.msx.add_species('T1','bulk',units='MG', note='Source 1 Tracer')\n", - "wn.msx.add_species('CL2','bulk', units='MG', note='Free Chlorine')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Add the coefficients" + "T1 = wn.msx.add_species('T1','bulk',units='MG', note='Source 1 Tracer')\n", + "Cl2 = wn.msx.add_species('CL2','bulk', units='MG', note='Free Chlorine')\n", + "pprint(repr(Cl2))" ] }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 5, "metadata": {}, "outputs": [ { - "data": { - "text/plain": [ - "Constant(name='k2', value=17.7, units='1/day')" - ] - }, - "execution_count": 4, - "metadata": {}, - "output_type": "execute_result" + "name": "stdout", + "output_type": "stream", + "text": [ + "\"Constant(name='k2', value=17.7, units='1/day')\"\n" + ] } ], "source": [ - "# Add the constant coefficients\n", "k1 = wn.msx.add_constant('k1', 1.3, units='1/day')\n", "k2 = wn.msx.add_constant('k2', 17.7, units='1/day')\n", - "k2" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Add the recations" + "pprint(repr(k2))" ] }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 6, "metadata": {}, "outputs": [ { - "data": { - "text/plain": [ - "Reaction(species_name='CL2', expression_type=, expression='-(k1*T1 + k2*(1-T1))*CL2')" - ] - }, - "execution_count": 5, - "metadata": {}, - "output_type": "execute_result" + "name": "stdout", + "output_type": "stream", + "text": [ + "(\"Reaction(species_name='CL2', expression_type=, \"\n", + " \"expression='-(k1*T1 + k2*(1-T1))*CL2')\")\n" + ] } ], "source": [ - "# Add the reactions\n", - "wn.msx.add_reaction('T1', 'pipe', 'rate', '0')\n", - "wn.msx.add_reaction('CL2', 'pipe', 'rate', '-(k1*T1 + k2*(1-T1))*CL2')\n" + "rxn_T1 = wn.msx.add_reaction('T1', 'pipe', 'rate', '0')\n", + "rxn_Cl2 = wn.msx.add_reaction('CL2', 'pipe', 'rate', '-(k1*T1 + k2*(1-T1))*CL2')\n", + "pprint(repr(rxn_Cl2))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "### Set up the initial quality" + "### Set up the initial quality\n", + "In this example, the initial quality is based on the two sources: the tracer, indicating which source is which, is set to 1.0 for the river; the chlorine is being boosted at the sources to the same level, 1.2 mg/L." ] }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 13, "metadata": {}, "outputs": [ { - "data": { - "text/plain": [ - "{'T1': InitialQuality(global_value=0.0, node_values=<1 entries>, link_values=<0 entries>),\n", - " 'CL2': InitialQuality(global_value=0.0, node_values=<2 entries>, link_values=<0 entries>)}" - ] - }, - "execution_count": 6, - "metadata": {}, - "output_type": "execute_result" + "name": "stdout", + "output_type": "stream", + "text": [ + "{'CL2': InitialQuality(global_value=0.0, node_values=<2 entries>, link_values=<0 entries>),\n", + " 'T1': InitialQuality(global_value=0.0, node_values=<1 entries>, link_values=<0 entries>)}\n" + ] } ], "source": [ + "from wntr.msx.elements import InitialQuality\n", "net_data = wn.msx.network_data\n", "net_data.initial_quality['T1'] = InitialQuality(\n", " node_values={'River': 1.0}\n", @@ -169,29 +163,48 @@ "net_data.initial_quality['CL2'] = InitialQuality(\n", " node_values={'River':1.2, 'Lake':1.2}\n", ")\n", - "net_data.initial_quality" + "pprint(net_data.initial_quality)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "### Run the simulation and view the results" + "### Run the simulation and view the results\n", + "With the MSX model attached to the WaterNetworkModel, there is nothing different in how the EpanetSimulator is called. Results are saved in keys with the species' name." ] }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 14, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Node results: demand, head, pressure, quality, T1, CL2\n", + "Link results: quality, flowrate, velocity, headloss, status, setting, friction_factor, reaction_rate, T1, CL2\n" + ] + } + ], "source": [ "sim = wntr.sim.EpanetSimulator(wn)\n", - "res = sim.run_sim()\n" + "res = sim.run_sim()\n", + "print('Node results:' , ', '.join([k for k in res.node.keys()]))\n", + "print('Link results:' , ', '.join([k for k in res.link.keys()]))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Generate some graphics that show how the river fraction changes through time." ] }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 9, "metadata": {}, "outputs": [ { @@ -236,6 +249,7 @@ } ], "source": [ + "import matplotlib.pyplot as plt\n", "_=wntr.graphics.plot_network(\n", " wn, node_attribute=res.node['T1'].loc[3600*12,:], \n", " title='12 h', node_colorbar_label='River\\nFraction',\n", @@ -259,19 +273,20 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "### Perform analysis of different k1 values" + "### Look at impact of different k1 values on residuals" ] }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 10, "metadata": {}, "outputs": [], "source": [ "d_k1 = dict()\n", + "k1 = wn.msx.reaction_system.constants['k1']\n", "for i in range(7):\n", " # Increase the reaction rate\n", - " newk = 1.3 + (2*i*1.3)\n", + " newk = 1.3 + i*2.6\n", " k1.value = newk\n", " resk = sim.run_sim()\n", " d_k1[newk] = resk" @@ -279,22 +294,22 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 11, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "Text(0, 0.5, 'River Fraction [/100%] // Concentraion [mg/L]')" + "Text(0, 0.5, 'Concentraion [mg/L]')" ] }, - "execution_count": 10, + "execution_count": 11, "metadata": {}, "output_type": "execute_result" }, { "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAjcAAAHHCAYAAABDUnkqAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8g+/7EAAAACXBIWXMAAA9hAAAPYQGoP6dpAADOkUlEQVR4nOzdd3jTVdvA8W92k+69oYyyZJUhFETQB0VUhltxoIAbfRQnisiDeyE4EUUQFTcqvgio7L2RPQqF0r1X2iZp8nv/SBMoHSRt2qTlfK6rV9PkN+5WTO+ec5/7yCRJkhAEQRAEQWgl5O4OQBAEQRAEwZVEciMIgiAIQqsikhtBEARBEFoVkdwIgiAIgtCqiORGEARBEIRWRSQ3giAIgiC0KiK5EQRBEAShVRHJjSAIgiAIrYpIbgRBEARBaFVEciMIF7G4uDjuvfded4fhUWQyGTNmzHB3GIIgNIJIbgShFTpx4gQPPvgg7du3x8vLCz8/PwYPHsycOXMoLy+v87wjR47w7LPP0rt3b3x9fYmMjOS6665j586dLo3v0KFDzJgxg1OnTrn0up7or7/+YuLEiXTv3h2FQkFcXFydx7722muMHj2a8PDwepOsuLg4ZDJZrR/x8fFN840IQguidHcAgiC41rJly7jlllvQaDTcc889dO/eHaPRyMaNG3nmmWc4ePAg8+bNq/XcL774gvnz53PTTTfxyCOPUFRUxGeffcbAgQNZsWIFw4cPd0mMhw4d4n//+x/Dhg2r95d9a7B48WJ++OEH+vTpQ1RUVL3HTps2jYiICBISEli5cmWdx82ePZvS0tJqz50+fZpp06Zx9dVXuyRuQWjJRHIjCK1IcnIyt99+O23btmX16tVERkbaX3v00UdJSkpi2bJldZ5/xx13MGPGDHx8fOzPTZgwga5duzJjxgyXJTcXk9dff53PP/8clUrF9ddfz4EDB+o8Njk5mbi4OHJzcwkNDa3zuLFjx9Z47tVXXwXgzjvvbHTMgtDSiWkpQWhF3n77bUpLS5k/f361xMamY8eO/Pe//63z/L59+1ZLbACCg4MZMmQIhw8fvuD9T58+zSOPPELnzp3RarUEBwdzyy23VJt+WrhwIbfccgsAV1xxhX06Ze3atXVe995778XHx4e0tDTGjh2Lj48PoaGhPP3005jN5mrH6vV6nnrqKWJjY9FoNHTu3Jl3330XSZKqHWcwGHjyyScJDQ3F19eX0aNHk5qaWuv909LSmDBhAuHh4Wg0Gi655BK+/PLLC/48AKKiolCpVA4d25hRrMWLF9OuXTsGDRrU4GsIQmshRm4EoRX5448/aN++vct/wWVmZhISEnLB43bs2MHmzZu5/fbbiYmJ4dSpU3z66acMGzaMQ4cOodPpuPzyy3n88cf54IMPeOGFF+jatSuA/XNdzGYzI0aMYMCAAbz77rv8888/vPfee3To0IGHH34YAEmSGD16NGvWrGHixIn07t2blStX8swzz5CWlsb7779vv96kSZP45ptvGDduHIMGDWL16tVcd911Ne6blZXFwIEDkclkTJ48mdDQUJYvX87EiRMpLi7miSeecOIn2TT27NnD4cOHefHFF90diiB4BkkQhFahqKhIAqQxY8Y4fE7btm2l8ePH13vM+vXrJZlMJr300ksXvF5ZWVmN57Zs2SIB0qJFi+zP/fTTTxIgrVmzxqE4x48fLwHSzJkzqz2fkJAg9e3b1/71b7/9JgHSq6++Wu24m2++WZLJZFJSUpIkSZK0d+9eCZAeeeSRaseNGzdOAqSXX37Z/tzEiROlyMhIKTc3t9qxt99+u+Tv71/r91yX6667Tmrbtu0Fj8vJyakRR32eeuopCZAOHTrkcCyC0JqJaSlBaCWKi4sB8PX1ddk1s7OzGTduHO3atePZZ5+94PFardb+2GQykZeXR8eOHQkICGD37t2Njuehhx6q9vWQIUM4efKk/es///wThULB448/Xu24p556CkmSWL58uf04oMZx54/CSJLEL7/8wqhRo5AkidzcXPvHiBEjKCoqcsn31RgWi4Xvv/+ehISEC45+CcLFQkxLCUIr4efnB0BJSYlLrqfX67n++uspKSlh48aNNWpxalNeXs4bb7zBggULSEtLq1bnUlRU1Kh4vLy8ahTZBgYGUlBQYP/69OnTREVF1UjwbL/0T58+bf8sl8vp0KFDteM6d+5c7eucnBwKCwuZN29enSvMsrOzG/YNuci6detIS0vjySefdGscguBJRHIjCK2En58fUVFR9a7GcZTRaOTGG29k3759rFy5ku7duzt03mOPPcaCBQt44oknSExMxN/fH5lMxu23347FYmlUTAqFolHnN4Qt5rvuuovx48fXekzPnj2bM6Qavv32W+RyOXfccYdb4xAETyKSG0FoRa6//nrmzZvHli1bSExMbNA1LBYL99xzD6tWreLHH39k6NChDp/7888/M378eN577z37cxUVFRQWFlY7TiaTNSi2C2nbti3//PMPJSUl1UZvjhw5Yn/d9tlisXDixIlqozVHjx6tdj3bSiqz2eyRy+ANBgO//PILw4YNu2APHUG4mIiaG0FoRZ599lm8vb2ZNGkSWVlZNV4/ceIEc+bMqfcajz32GD/88AOffPIJN954o1P3VygUNZZcf/jhhzWWa3t7ewPUSHoa69prr8VsNvPRRx9Ve/79999HJpMxcuRIAPvnDz74oNpxs2fPrva1QqHgpptu4pdffql1RCwnJ8eF0Tvvzz//pLCwUPS2EYTziJEbQWhFOnTowOLFi7ntttvo2rVrtQ7Fmzdv5qeffqp3L6nZs2fzySefkJiYiE6n45tvvqn2+g033GBPTGpz/fXX8/XXX+Pv70+3bt3YsmUL//zzD8HBwdWO6927NwqFgrfeeouioiI0Gg1XXnklYWFhjfr+R40axRVXXMGLL77IqVOn6NWrF3/99Re///47TzzxhL3Gpnfv3txxxx188sknFBUVMWjQIFatWkVSUlKNa7755pusWbOGAQMGcP/999OtWzfy8/PZvXs3//zzD/n5+fXGtG/fPpYuXQpAUlISRUVF9oZ7vXr1YtSoUfZjv/76a06fPk1ZWRkA69evtx97991320eebL799ls0Gg033XRTA39igtBKuXWtliAITeLYsWPS/fffL8XFxUlqtVry9fWVBg8eLH344YdSRUWF/bjzl4LbllzX9ZGcnFzvfQsKCqT77rtPCgkJkXx8fKQRI0ZIR44cqXXJ+eeffy61b99eUigUF1wWPn78eMnb27vG8y+//LJ0/ttYSUmJ9OSTT0pRUVGSSqWS4uPjpXfeeUeyWCzVjisvL5cef/xxKTg4WPL29pZGjRolnTlzptYl2FlZWdKjjz4qxcbGSiqVSoqIiJD+85//SPPmzav35yFJkrRgwYI6f57n/0yGDh1a57Hn/3yKiookLy8v6cYbb7xgDIJwsZFJ0nljyIIgCIIgCC2YqLkRBEEQBKFVEcmNIAiCIAitikhuBEEQBEFoVURyIwiCIAhCqyKSG0EQBEEQWhWR3AiCIAiC0KpcdE38LBYL6enp+Pr6NlkLeEEQBEEQXEuSJEpKSoiKikIur39s5qJLbtLT04mNjXV3GIIgCIIgNMCZM2eIiYmp95iLLrmxbaZ35swZ/Pz83ByNIAiCIAiOKC4uJjY2ttqmuHW56JIb21SUn5+fSG4EQRAEoYVxpKREFBQLgiAIgtCqiORGEARBEIRWRSQ3giAIgiC0KhddzY0gCIIgOMtisWA0Gt0dRqunVqsvuMzbESK5EQRBEIR6GI1GkpOTsVgs7g6l1ZPL5bRr1w61Wt2o64jkRhAEQRDqIEkSGRkZKBQKYmNjXTKqINTO1mQ3IyODNm3aNKrRrkhuBEEQBKEOlZWVlJWVERUVhU6nc3c4rV5oaCjp6elUVlaiUqkafB2RggqCIAhCHcxmM0Cjp0kEx9h+zrafe0OJ5EYQBEEQLkDsRdg8XPVzFsmNIAiCIAitikhuBEEQBMFFhg0bxhNPPNEk17777rt5/fXXXX7dhQsXEhAQ4NJrPv/88zz22GMuvaYzRHIjCIIgCM3k4MGD3HTTTcTFxSGTyZg9e7ZD5/3777/8+eefPP744/bnlixZwtVXX01wcDAymYy9e/fWeX67du34559/Ghm9455++mm++uorTp482Wz3PJdIbgRBEIQaJEnCWGlBb6ikqMxETomB9MJyKs2i10tjlJWV0b59e958800iIiIcPu/DDz/klltuwcfHx/6cXq/nsssu46233qr33H379lFQUMDQoUMbHLezQkJCGDFiBJ9++mmz3fNcDi0FnzJlitMXnjZtGkFBQU6fJwiCIDS9/9uXzidrTlBqqMRktlR9SNUe16ZHtD9/PHZZM0fbci1btoxx48bxySefcOedd9K/f3/69+8PWKduHGE2m/n555/59ttvqz1/9913A3Dq1Kl6z//999+55ppr7EurFy5cyPTp08nNzWXEiBFcdln1/54nTpxgypQpbN26Fb1eT9euXXnjjTcYPnw4ADNnzuTHH3/kwIED1c7r3bs3o0aN4pVXXgFg1KhRvPjii7zzzjsOfZ+u5FByM3v2bBITEx1eCrdx40YmT54skhtBEAQPtHhbCi/+th+p9vylXvvTiig3mtGqFa4PrJVZvHgxDz30EIsXL+b6669v8HX27dtHUVER/fr1a9D5S5cutQ9SbNu2jYkTJ/LGG28wduxYVqxYwcsvv1zt+NLSUq699lpee+01NBoNixYtYtSoURw9epQ2bdowYcIE/ve//7Fjxw57orZnzx727dvHkiVL7Ne59NJLSU1N5dSpU8TFxTXsm28gh5v4/frrr4SFhTl0rK+vb4MDEgRBEJrOFxtO8uqywwDcNbANNyTEoFbIUSllqBRy1Ao5SoX1se1rlUKGQi6j07TlmMwSheVGtGqtm78Tz/bxxx/z4osv8scffzR6Ouj06dMoFAqHfwefKy0tjX379jFy5EgA5syZwzXXXMOzzz4LQKdOndi8eTMrVqywn9OrVy969epl//qVV17h119/ZenSpUyePJmYmBhGjBjBggUL7MnNggULGDp0KO3bt7efFxUVZY/fI5ObBQsW4O/v7/BFP/vsM8LDwxsclCAIguBakiTx0eok3vv7GAAPDe3Ac9d0dqqviL9WTW6pgcIyE5H+Irmpy88//0x2djabNm2y//JvjPLycjQaTYN6wCxdupTLLrvMvhrq8OHD3HDDDdWOSUxMrJbclJaWMmPGDJYtW0ZGRgaVlZWUl5eTkpJiP+b+++9nwoQJzJo1C7lczuLFi3n//ferXVertf4bKSsrczruxnIouRk/fvwFjzGbzWRlZREVFcW4ceMaHZggCILgGpIk8fbKo3y69gQAT13ViclXdnT6l2WATkVuqYGCMrE7dn0SEhLYvXs3X375Jf369Wt0Y7qQkBDKysowGo1Od0peunQpo0ePduqcp59+mr///pt3332Xjh07otVqufnmm6vtij5q1Cg0Gg2//vorarUak8nEzTffXO06+fn5gHVLhebmsr2lDhw4QJ8+fRrdMlkQBEFwHYtFYub/HWLh5lMATLuuK5OGtK//pDoE6qwFqUVlJleF1yp16NCB9957j2HDhqFQKPjoo48adb3evXsDcOjQIftjR5SWlrJmzZpqK5a6du3Ktm3bqh23devWal9v2rSJe++91z7CU1paWqNoWalUMn78eBYsWIBareb222+3j9TYHDhwAJVKxSWXXOJwzK4iNs4UBEFopcwWialL9vHjzlRkMnhtbA/GDWjT4Ov5a62jBoXlIrm5kE6dOrFmzRqGDRuGUqm097MxGo0cOnTI/jgtLY29e/fi4+NDx44da71WaGgoffr0YePGjdWSm/z8fFJSUkhPTwfg6NGjAERERBAREcGKFSvo1KlTtXqXxx9/nMGDB/Puu+8yZswYVq5cWW1KCiA+Pp4lS5YwatQo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008/odfrSUxMrPUYg8GAl5dXtee0Wi0bN25sUKju5nRyc9NNN7Ft2zbef/99fvvtNwC6du3K9u3bSUhIcHV8giBcpJzpQdOQ4uDmYKvrefDBBzGbzfa6nhKFH5IEYb4aQnw0bo2xMWw1NxfVFgymMng9yj33fiEd1N4OH75//34SExOpqKjAx8eHX3/9lW7dutV67IgRI5g1axaXX345HTp0YNWqVSxZsgSz2eyq6JuV08kNQN++ffnmm29cHYsgCALgfDfgupIId47a2NS2wuqbraeBlj1qA+fsDC6mpTxS586d2bt3L0VFRfz888+MHz+edevW1ZrgzJkzh/vvv58uXbogk8no0KED9913H19++aUbIm88h5Kb4uJi/Pz87I/rYztOEAShoRoyzdTQZdrNISYmplo8raHeBi7SaSmVzjqC4q57O0GtVttHL/v27cuOHTuYM2cOn332WY1jQ0ND+e2336ioqCAvL4+oqCief/552rdv75LQm5tDyU1gYCAZGRmEhYUREBBQ6x4itr1FWuoQliAInqOh00znJxGe6lBGy18pBRfptJRM5tTUkCexWCwYDIZ6j/Hy8iI6OhqTycQvv/zCrbfe2kzRuZZDyc3q1asJCgoCYM2aNU0akCAIgidPMzWW2SJxNLPl97gBCNRZR27EtJTnmTp1KiNHjqRNmzaUlJSwePFi1q5dy8qVKwG45557iI6O5o033gBg27ZtpKWl0bt3b9LS0pgxYwYWi4Vnn33Wnd9GgzmU3AwdOrTWx4IgCE3Fk6eZGuN0np4yoxkvlZx2IS1zBMDG3sSvXOwM7mmys7O55557yMjIwN/fn549e7Jy5UquuuoqAFJSUqrtlVZRUcG0adM4efIkPj4+XHvttXz99dcEBAS46TtonAYVFAOUlZWRkpKC0Vh9OLJnz56NDkoQhNbH0WXd52op00zOsHUm7hzhh0LespMBf601uTFbJEoMlfiJncE9xoWaWK5du7ba10OHDuXQoUNNGFHzcjq5ycnJ4b777quzjbOouREE4XzOLOtu7Wx7SnWL9HVzJI3npVKgVSkoN5kpKjOJ5EbwGE53KH7iiScoLCxk27ZtaLVaVqxYwVdffUV8fDxLly5tihgFQWjBGtM9uDVqDXtKneuiLCoWPJ7TIzerV6/m999/p1+/fsjlctq2bctVV12Fn58fb7zx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xYJnKCkp4YknnqBt27ZotVoGDRrEjh076jw+IyODcePG0alTJ+RyOU888UTzBetiTr+L9OvXj2XLltm/tiU0X3zxBYmJia6LTBCEVimv1MCkr3by8tKDGCstXNkljBVPDOHyTqHuDq112Pg+SBaIvxoie7n++nXuL1U1LaUXIzeeYtKkSfz99998/fXX7N+/n6uvvprhw4eTlpZW6/EGg4HQ0FCmTZtGr15N8G+nGTk9LfX6668zcuRIDh06RGVlJXPmzOHQoUNs3ry5Rt8bQRCEc204nsOUH/8lp8SAWinnhZFdGD8oToz6ukpRKvz7vfXxkKeb5h72guI69pdq5SM3kiQhlZe75d4yrdbh/1fKy8v55Zdf+P3337n88ssBmDFjBn/88Qeffvopr776ao1z4uLimDNnDgBffvml6wJ3A6eTm8suu4y9e/fy5ptv0qNHD/766y/69OnDli1b6NGjR1PEKAhCK/DN1tNM++0AAB3DfPjwjgS6Rvq5OapWZtMHYDFB3BBoM6Bp7mFbCm4sAVM5qLTAxbN5plReztE+fd1y7867dyHTObaje2VlJWazudrCHwCtVsvGjRubIjyP0qAGNR06dODzzz93dSyCILRi8zdaG4De0jeGmWO6o1WLRnwuVZoNu7+yPm6KWhsbL39rx2Oz0To1FdAGODstJQqKPYOvry+JiYm88sordO3alfDwcL777ju2bNlCx44d3R1ek3M6ufnzzz9RKBSMGDGi2vMrV67EYrEwcuRIlwUnCELrIEkS6YXWofzHrowXiU1T2PIxVFZAdF9oP6zp7iOTWetuitOqJzcXybSUTKul8+5dbru3M77++msmTJhAdHQ0CoWCPn36cMcdd7Brl3vib05OFxQ///zzmM3mGs9LksTzzz/vkqAEQWhdCspMGCqtu3eH+4umfC5Xlg875lsfD3nKmoA0JXtR8Tldii+SPjcymQy5TueWD2dr0zp06MC6desoLS3lzJkzbN++HZPJRPv27Zvop+M5nE5ujh8/Trdu3Wo836VLF5KSklwSlCAIrYtt1CbER4NGKUZtXG7TbGsNTHh36NQMo+e25OacLsW2kZsiMS3lcby9vYmMjKSgoICVK1cyZswYd4fU5JyelvL39+fkyZPExcVVez4pKQlvb29XxSUIQiuSUVQBQKS/1wWOFJxWnAHbPrM+vvIl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HDBgALt377Z/bTQaadPm7GZwbdq0oaKiwrXRCYLg8ezLwGvbV8pcae1hA5D4qOt2377ILD6ymApzBd2CuzEwcmCjr1f0yy8A+F41HG3v3qiiopB7e19wmkgda62TMZ05u9N6jRVT9s0za1/yndjBukt4S9yKQWg5HH6n+eijj5g0aRJPPvkker2el19+mb59+zJw4ED69u3LTTfdxGuvvdaUsQqC4IFsIze1LgM/vNS6S7cuBHrd3syRtQ5lpjIWH14MWGttGlunYikvp+iP/wMg4OabnTpX3caa3BhTziY3tqLiGl2K9TVHbsBaVAyw5WQeFkst+4UJggs4PC01YMAAduzYwdtvv03fvn15++23OXr0KNu2bcNsNtO/f3+io0XXSUG42NhqbqLOn5aSJNjykfVx/0mgEh3LG+LnYz9TbCymrV9b/tPmP42+Xslff2EpKUEVHY1uoHOjQKqYquTmTIr9uRqN/GzbZJTlW0fuztv7q2dMADq1gny9kWPZJXSJEG1DBNdzaoxYoVAwdepUli1bxocffsjDDz9M3759GTt2rEhsBOEiVFJhosRQCUDE+dNSKVshbZd15+7+k9wQXctnMptYdGgRAPddch8KuaLR1yz82Tol5X/TjcicnCa0jdyYzqTan6sxLaUNAmSABOX5Na+hlNMvLgiAzUliakpoGk79yz548CC//PILZrOZv//+m9GjRzNkyBA++eSTpopPEAQPZutx4+ulxEdz3kCwbdSm1+1nlwcLTlmWvIyssixCtaGM6jCq0dczJCdTtmMHyOUE3HCD0+erquosTampSBYLcLaRn33kRqEEnXXqqbaiYjg7NbVZ1N0ITcTh5GbWrFn079+fd955h8TERD7//HPGjx/Ptm3b2Lp1K4mJiezfv78pYxUEwcOk11VMnHcCjiyzPk6c3MxRtQ4WyWLfauHubnejVjR+a4qiJdYVV96XDUYV6fympKqICFAqkYxGKrOsyYxtWiq7LBuLZE146lsODmeTm23JeZhF3Y3QBBxObt5++22WLVvG1q1b2b17N7NmzQIgJCSERYsWMXPmTG699dYmC1QQBM+TWdcy8K2fABLEj4DQTs0fWCuw5swakouS8VX5ckunWxp9PclkovC33wDnC4ltZEolqugo4GxRcYguBBkyTBYTBRUF1gPtK6ZqT24uifLH10tJSUUl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3SoQCDRos3r1ajVixAhls9lUv379GpyjXkft2+8nN121Tz744AM1ZMgQZbfbVXZ2tvrzn//c4HFd19VvfvMblZKSoux2u5o8ebLavXt3gzalpaVq7ty5Kjo6WsXGxqobb7xRVVVVNWizdetWNWHCBGW321XPnj3VkiVLTojlzTffVAMGDFA2m02dc8456sMPP2z5H/g03G63uuOOO1Tv3r2Vw+FQ/fr1Uw8++GCDD6eu0CerV69u9H1k/vz5SqmO1QdNiaWlnKpf9u3bd9L339WrV3fqfmlpmlLHLZsphBBCCHGWkzk3QgghhOhUJLkRQgghRKciyY0QQgghOhVJboQQQgjRqUhyI4QQQohORZIbIYQQQnQqktwIIYQQolOR5EYIIU7ihhtuYM6cOe0dhhAiQpLcCCFa3ZEjR7jlllvo3bs3drud1NRUpk+fzpdfftneoQkhOiFLewcghOj8rrzySvx+P3/5y1/o168fxcXFrFq1itLS0vYOTQjRCcmVGyFEq6qoqOCLL77g97//PRdddBF9+vRh7Nix3H///Vx66aXhNj/96U/p3r07sbGxXHzxxWzdurXB63zwwQece+65OBwOunXrxuWXXx5+rLy8nOuvv56EhARcLhczZ84kNzc3/PjLL79MfHw8H3/8MYMGDSI6OpoZM2ZQWFgYbhMKhViwYAHx8fEkJSVx77338v3dad5++22GDh2K0+kkKSmJKVOmUFNT0xrdJoQ4A5LcCCFaVXR0NNHR0bz33nv4fL5G21x99dWUlJTw0UcfsWnTJkaNGsXkyZMpKysD4MMPP+Tyyy9n1qxZbN68mVWrVjF27Njw82+44QY2btzI+++/z7p161BKMWvWLAKBQLiNx+Phscce45VXXuHzzz/n4MGD/L//9//Cjz/++OO8/PLLvPjii6xdu5aysjLefffd8OOFhYXMnTuXm266iZ07d7JmzRquuOKKExIgIUQH0K7bdgohuoS3335bJSQkKIfDoc477zx1//33q61btyqllPriiy9UbGys8nq9DZ7Tv39/9dxzzymllBo/fryaN29eo6+9Z88eBagvv/wyfOzo0aPK6XSqN998Uyml1EsvvaQAlZeXF26zbNkylZKSEr6flpamli5dGr4fCARUr1691GWXXaaUUmrTpk0KUPv37z+DnhBCtAW5ciOEaHVXXnklBQUFvP/++8yYMYM1a9YwatQoXn75ZbZu3Up1dTVJSUnhqzzR0dHs27ePvXv3ArBlyxYmT57c6Gvv3LkTi8XCuHHjwseSkpIYOHAgO3fuDB9zuVz0798/fD8tLY2SkhIAKisrKSwsbPAaFouFMWPGhO8PHz6cyZMnM3ToUK6++mqef/55ysvLW6aDhBAtSiYUCyHahMPhYOrUqUydOpXf/OY3/PSnP2XRokXceuutpKWlsWbNmhOeEx8fD4DT6Tzj81ut1gb3NU2LaEjJbDazcuVKvvrqK/71r3/x9NNP8+CDD7J+/Xr69u17xvEJIVqOXLkRQrSLwYMHU1NTw6hRoygqKsJisZCZmdng1q1bNwCGDRvGqlWrGn2dQYMGEQwGWb9+ffhYaWkpu3fvZvDgwU2KJS4ujrS0tAavEQwG2bRpU4N2mqZx/vnn8/DDD7N582ZsNluDeTlCiI5BrtwIIVpVaWkpV199NTfddBPDhg0jJiaGjRs3snTpUi677DKmTJnC+PHjmTNnDkuXLmXAgAEUFBSEJxGPGTOGRYsWMXnyZPr3788Pf/hDgsEgy5cvZ+HChWRlZXHZZZdx880389xzzxETE8N9991Hz549ueyyy5oc5x133MGSJUvIysoiOzubP/zhD1RUVIQfX79+PatWrWLatGkkJyezfv16jhw5wqBBg1qh14QQZ0KSGyFEq4qOjmbcuHE88cQT7N27l0AgQHp6OjfffDMPPPAAmqaxfPlyHnzwQW688UaOHDlCamoqEydOJCUlBYALL7yQt956i9/+9rcsWbKE2NhYJk6cGD7HSy+9xB133MF//Md/4Pf7mThxIsuXLz9hKOpU7r77bgoLC5k/fz4mk4mbbrqJyy+/nMrKSgBiY2P5/PPPefLJJ3G73fTp04fHH3+cmTNntmyHCSHOmKYiGXQWQgghhOjgZM6NEEIIIToVSW6EEEII0alIciOEEEKITkWSGyGEEEJ0KpLcCCGEEKJTkeRGCCGEEJ2KJDdCCCGE6FQkuRFCCCFEpyLJjRBCCCE6FUluhBBCCNGpSHIjhBBCiE5FkhshhBBCdCr/Hyw6lgBntulcAAAAAElFTkSuQmCC", + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAjcAAAHHCAYAAABDUnkqAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8g+/7EAAAACXBIWXMAAA9hAAAPYQGoP6dpAAC91klEQVR4nOzdd3iUVfbA8e/0kt4bgdB7FxURAUURXOy9IZa1YV9dcV3brqL+bKyNXRv2jm1VcEWRKiC910AgPSF1kkx9f3+8mUlCCplkkknC+TxPnkwmbzkJYXJy77nnahRFURBCCCGE6CK0wQ5ACCGEECKQJLkRQgghRJciyY0QQgghuhRJboQQQgjRpUhyI4QQQoguRZIbIYQQQnQpktwIIYQQokuR5EYIIYQQXYokN0IIIYToUiS5EaIRGo2GWbNmHfO4+fPno9FoOHDgQEDvP3HiRCZOnBjQa3Yk1113HWlpacc87sCBA2g0GubPn9+m8aSlpXHddde16T06guZ+34XozCS5Ecedffv2cfPNN9OrVy/MZjPh4eGMGzeOuXPnUllZGezwRBfx1FNP8fXXXwc7jDaXnZ3Ngw8+yKRJkwgLC0Oj0bBkyZIGj/3pp5+44YYbGDJkCDqdrtEk67HHHkOj0TT6tmLFirb7gkSXoA92AEK0p++//55LLrkEk8nEtddey5AhQ3A4HCxfvpz777+fbdu28Z///CfYYQLqL4Ku7I033sDj8QQ7jDbz1FNPcfHFF3P++ecHO5Q2tWvXLp555hn69u3L0KFDWbVqVaPHfvTRR3z66aeMGjWK5OTkRo+78MIL6dOnT73nH3roIcrLyxkzZkxAYhddlyQ34riRnp7O5ZdfTo8ePfjll19ISkryfe72229n7969fP/990GMUFVRUYHVasVoNAY7FJ+qqiqMRiNabeAGew0GQ8CuJYJn9OjRFBYWEh0dzRdffMEll1zS6LFPPfUUb7zxBgaDgT/96U9s3bq1weOGDRvGsGHD6jx36NAhDh8+zI033tih/m+IjkmmpcRx49lnn6W8vJy33nqrTmLj1adPH+666656z3/99dcMGTIEk8nE4MGDWbhwYbPu99prrzF48GBMJhPJycncfvvtFBcX1zlm4sSJDBkyhHXr1nHaaadhtVp56KGHfJ+rXXOzZMkSNBoNn332GU8++STdunXDbDZzxhlnsHfv3nr3X716NWeffTYRERFYrVYmTJjQrOF8730++eQTHn74YVJSUrBarZSWljb7umVlZdx9992kpaVhMpmIj4/nzDPPZP369b5jGqr9KC4u5rrrriMiIoLIyEhmzJhR73vW0PemqWs+99xznHLKKcTExGCxWBg9ejRffPHFMb8PjWnO9TQaDTabjXfffdc3ldJUPY+//7aff/45o0ePxmKxEBsby9VXX01mZma947w/u2azmSFDhvDVV181eH+Px8NLL73E4MGDMZvNJCQkcPPNN1NUVHTM70dYWBjR0dHHPA4gOTm5xUntxx9/jKIoXHXVVS06XxxfZORGHDe+++47evXqxSmnnNLsc5YvX86CBQu47bbbCAsL41//+hcXXXQRGRkZxMTENHreY489xuOPP87kyZO59dZb2bVrF6+//jpr165lxYoVdV7gCwsLmTp1KpdffjlXX301CQkJTcb09NNPo9Vq+ctf/kJJSQnPPvssV111FatXr/Yd88svvzB16lRGjx7No48+ilar5Z133uH0009n2bJlnHjiicf82v/xj39gNBr5y1/+gt1ux2g0Nvu6t9xyC1988QWzZs1i0KBBFBYWsnz5cnbs2MGoUaMavJ+iKJx33nksX76cW265hYEDB/LVV18xY8aMY8balLlz53Luuedy1VVX4XA4+OSTT7jkkkv473//yznnnNMm13v//fe58cYbOfHEE/nzn/8MQO/evY957eb8286fP5+ZM2cyZswY5syZQ25uLnPnzmXFihVs2LCByMhIQJ3WvOiiixg0aBBz5syhsLCQmTNn0q1bt3r3vfnmm33XvfPOO0lPT+eVV15hw4YN9X5eg+XDDz8kNTWV0047LdihiM5AEeI4UFJSogDKeeed1+xzAMVoNCp79+71Pbdp0yYFUF5++WXfc++8844CKOnp6YqiKEpeXp5iNBqVs846S3G73b7jXnnlFQVQ3n77bd9zEyZMUABl3rx59e4/YcIEZcKECb6Pf/31VwVQBg4cqNjtdt/zc+fOVQBly5YtiqIoisfjUfr27atMmTJF8Xg8vuMqKiqUnj17KmeeeWaTX7f3Pr169VIqKip8z/tz3YiICOX2229v8j4zZsxQevTo4fv466+/VgDl2Wef9T3ncrmU8ePHK4DyzjvvNPq9aeya3vhqczgcypAhQ5TTTz+9zvM9evRQZsyY0WTM/lwvJCSkWddTlOb/2zocDiU+Pl4ZMmSIUllZ6Tvuv//9rwIojzzyiO+5ESNGKElJSUpxcbHvuZ9++kkB6nyPli1bpgDKhx9+WCemhQsXNvh8Uz7//HMFUH799ddjHnvOOefU+7dqzNatWxVAeeCBB5odizi+ybSUOC54p1TCwsL8Om/y5Ml1/uIeNmwY4eHh7N+/v9Fzfv75ZxwOB3fffXedGpWbbrqJ8PDwenU9JpOJmTNnNjummTNn1qk5GD9+PIAvpo0bN7Jnzx6uvPJKCgsLKSgooKCgAJvNxhlnnMHSpUubVcg7Y8YMLBaL72N/rhsZGcnq1avJyspq9tf1ww8/oNfrufXWW33P6XQ67rjjjmZfoyG1v4aioiJKSkoYP358nSmyYF6vtmP92/7xxx/k5eVx2223YTabfcedc845DBgwwPezlZ2dzcaNG5kxYwYRERG+484880wGDRpU556ff/45ERERnHnmmb5/04KCAkaPHk1oaCi//vprq7+u1vrwww8BZEpKNJtMS4njQnh4OKDWgvije/fu9Z6Liopqshbh4MGDAPTv37/O80ajkV69evk+75WSkuJXgeTRMUVFRQH4YtqzZw9Ak9M5JSUlvvMa07Nnzzof+3PdZ599lhkzZpCamsro0aOZNm0a1157Lb169Wr03IMHD5KUlERoaGid54/+Pvrrv//9L//85z/ZuHEjdrvd97xGo+kQ16vtWP+2jf1sAQwYMIDly5fXOa5v3771juvfv3+dRGzPnj2UlJQQHx/fYEx5eXn+fhkBpSgKH330EUOGDKlXZCxEYyS5EceF8PBwkpOTG12d0RidTtfg84qiBCIsoO5IQHMcKybv6Mn//d//MWLEiAaPPTqBaE5c/lz30ksvZfz48Xz11Vf89NNP/N///R/PPPMMCxYsYOrUqce897FoNJoG/w3cbnedj5ctW8a5557LaaedxmuvvUZSUhIGg4F33nmHjz76yO/7Bvp6R2uPn7ejeTwe4uPjfaMjR4uLi2uzezfHihUrOHjwIHPmzAlqHKJzkeRGHDf+9Kc/8Z///IdVq1YxduzYNrtPjx49ALX/R+2RCofDQXp6OpMnT26ze0NN4Wp4eHhA7+XvdZOSkrjtttu47bbbyMvLY9SoUTz55JONJjc9evRg8eLFlJeX10m+du3aVe/YqKioBqcGjx4V+/LLLzGbzSxatAiTyeR7/p133jlm/A3x53qBGMk5Wu2frdNPP73O53bt2uX7vPe9d7Tt6ONq6927Nz///DPjxo3zO9FuDx9++CEajYYrr7wy2KGITkRqbsRx44EHHiAkJIQbb7yR3Nzcep/ft28fc+fObfV9Jk+ejNFo5F//+ledv7jfeustSkpKWrRCxx+jR4+md+/ePPfcc5SXl9f7fH5+fpte1+12U1JSUudz8fHxJCcn15nGOdq0adNwuVy8/vrrvufcbjcvv/xyvWN79+7Nzp0763wtmzZtqrckXafTodFo6ozoHDhwoMWdg/25XkhISIPL2FvjhBNOID4+nnnz5tX5Xv7444/s2LHD97OVlJTEiBEjePfdd+v8W/zvf/9j+/btda556aWX4na7+cc//lHvfi6XK+Bfgz+cTieff/45p556aoNTxEI0RkZuxHGjd+/efPTRR1x22WUMHDiwTofilStX8vnnnwdkb6G4uDhmz57N448/ztlnn825557Lrl27eO211xgzZgxXX31167+YJmi1Wt58802mTp3K4MGDmTlzJikpKWRmZvLrr78SHh7Od99912bXLSsro1u3blx88cUMHz6c0NBQfv75Z9auXcvzzz/f6PWnT5/OuHHjePDBBzlw4ACDBg1iwYIF9RIlgOuvv54XXniBKVOmcMMNN5CXl8e8efMYPHiwr3gc1ELbF154gbPPPpsrr7ySvLw8Xn31Vfr06cPmzZv9/h74c73Ro0fz888/88ILL5CcnEzPnj056aST/L5nbQaDgWeeeYaZM2cyYcIErrjiCt9S8LS0NO655x7fsXPmzOGcc87h1FNP5frrr+fIkSO8/PLLDB48uE5yOmHCBG6++WbmzJnDxo0bOeusszAYDOzZs4fPP/+cuXPncvHFFzcZ1z//+U8Atm3bBqhL4b31Pw8//LDvuM2bN/Ptt98CsHfvXkpKSnznDh8+nOnTp9e57qJFiygsLJRCYuG/YC7VEiIYdu/erdx0001KWlqaYjQalbCwMGXcuHHKyy+/rFRVVfmOAxpcznz0kuGjl4J7vfLKK8qAAQMUg8GgJCQkKLfeeqtSVFRU55gJEyYogwcPbjDOxpaCf/7553WOS09Pr7dUWlEUZcOGDcqFF16oxMTEKCaTSenRo4dy6aWXKosXL278m9PEfZp7Xbvdrtx///3K8OHDlbCwMCUkJEQZPny48tprr9W5TkPLtgsLC5VrrrlGCQ8PVyIiIpRrrrlG2bBhQ4Nf3wcffKD06tVLMRqNyogRI5RFixY1eM233npL6du3r2IymZQBAwYo77zzjvLoo48qR7/8NXcpeHOvt3PnTuW0005TLBaLAjR5bX//bT/99FNl5MiRislkUqKjo5WrrrpKOXz4cL3rfvnll8rAgQMVk8mkDBo0SFmwYEGD3yNFUZT//Oc/yujRoxWLxaKEhYUpQ4cOVR544AElKyvrmN8ToNG32rz/Vxp6a+j7c/nllysGg0EpLCw8ZgxC1KZRlDasVBNCCCGEaGdScyOEEEKILkWSGyGEEEJ0KZLcCCGEEKJLkeRGCCGEEF2KJDdCCCGE6FIkuRFCCCFEl3LcNfHzeDxkZWURFhbWJu3RhRBCCBF4iqJQVlZGcnIyWm3TYzPHXXKTlZVFampqsMMQQgghRAscOnSIbt26NXnMcZfchIWFAeo3Jzw8PMjRCCGEEKI5SktLSU1N9f0eb8pxl9x4p6LCw8MluRFCCCE6meaUlEhBsRBCCCG6FEluhBBCCNGlSHIjhBBCiC7luKu5EUIIIdqS2+3G6XQGO4xOyWg0HnOZd3NIciOEEEIEgKIo5OTkUFxcHOxQOi2tVkvPnj0xGo2tuo4kN0IIIUQAeBOb+Ph4rFarNIr1k7fJbnZ2Nt27d2/V90+SGyGEEKKV3G63L7GJiYkJdjidVlxcHFlZWbhcLgwGQ4uvIwXFQgghRCt5a2ysVmuQI+ncvNNRbre7VdeR5EYIIYQIEJmKap1Aff8kuRFCCCFElyLJjRBCCNGGJk6cyN13390m177mmmt46qmnAn7d+fPnExkZGdBrPvjgg9xxxx0BvWZjJLkRQgghgmjbtm1cdNFFpKWlodFoeOmll5p13qZNm/jhhx+48847fc8tWLCAs846i5iYGDQaDRs3bmz0/J49e/Lzzz+3Mvrm+8tf/sK7777L/v372/xektwIIYSoR1EUHC4PNruLkgon+WV2soorcbk9wQ6ty6moqKBXr148/fTTJCYmNvu8l19+mUsuuYTQ0FDfczabjVNPPZVnnnmmyXM3b95MUVEREyZMaHHc/oqNjWXKlCm8/vrrbX4vWQouhBDHof9uzuK1X/dRbnfhdHuq35Q6jxsyNCWC7+44tZ2j7Vq+//57rrzySl577TWuuuoqxowZw5gxYwB16qY53G43X3zxBR9++GGd56+55hoADhw40OT533zzDWeffbZvufX8+fN55JFHKCgoYMqUKZx6at1/43379nHvvffy+++/Y7PZGDhwIHPmzGHy5MkAPPHEE3z22Wds3bq1znkjRoxg+vTp/OMf/wBg+vTp/O1vf+P//u//mvV1tpSM3AghxHHmo9UZ3PHxBrZnl5JxpILskioKyh2UVDqpcLgbTWwAtmSWUOlo3TLd49lHH33EFVdcwYcffshVV13V4uts3ryZkpISTjjhhBad/+2333LeeecBsHr1am644QZmzZrFxo0bmTRpEv/85z/rHF9eXs60adNYvHgxGzZs4Oyzz2b69OlkZGQAcP3117Njxw7Wrl3rO2fDhg1s3ryZmTNn+p478cQTOXz48DGTr9aSkRshhDiOvLlsP//8fgcAV5/cnQtGdsOo02LQazDotBh1WvQ69bH3Y4NOg06rod/DP+J0KxRXOrAYLUH+SjqfV199lb/97W989913rZ4OOnjwIDqdjvj4eL/PzczMZPPmzUydOhWAuXPncvbZZ/PAAw8A0K9fP1auXMnChQt95wwfPpzhw4f7Pv7HP/7BV199xbfffsusWbPo1q0bU6ZM4Z133vGNQr3zzjtMmDCBXr16+c5LTk72xZ+WluZ37M0lyY0QQhwHFEXhlV/28vz/dgNwy4Te/PXs/n71FYmwGCkot1Nc4SQpQpIbf3zxxRfk5eWxYsUK3y//1qisrMRkMrWoL8y3337Lqaee6lsNtWPHDi644II6x4wdO7ZOclNeXs5jjz3G999/T3Z2Ni6Xi8rKSt/IDcBNN93E9ddfzwsvvIBWq+Wjjz7ixRdfrHNdi0X9uamoqPA7bn9IciOEEF2coig8u2gXry/ZB8B9Z/Zj1ul9/P7FGGk1UFBup6jC0RZhdmkjR45k/fr1vP3225xwwgmtblYXGxtLRUUFDofD700mv/32W84991y/zvnLX/7C//73P5577jn69OmDxWLh4osvxuGo+VmYPn06JpOJr776CqPRiNPp5OKLL65znSNHjgDqNgttSZIbIYTowjwehSf+u535Kw8A8PA5A7lxfK+mT2pElFUtPi2pcAYqvONG7969ef7555k4cSI6nY5XXnmlVdcbMWIEANu3b/c9bo7y8nJ+/fXXOiuWBg4cyOrVq+sc9/vvv9f5eMWKFVx33XW+EZ7y8vJ6dTN6vZ4ZM2bwzjvvYDQaufzyy30jNV5bt27FYDAwePDgZsfcEpLcCCFEF+X2KMxesJnP/jiMRgNPnj+UK0/q3uLrRVjUEYLiSkluWqJfv378+uuvTJw4Eb1e7+tn43A42L59u+9xZmYmGzduJDQ0lD59+jR4rbi4OEaNGsXy5cvrJDdHjhwhIyODrKwsAHbt2gVAYmIiiYmJLFy4kH79+tWpd7nzzjsZN24czz33HOeddx6LFi2qMyUF0LdvXxYsWMD06dPRaDT8/e9/x+Op3xbgxhtvZODAgYCaEB1t2bJljB8/vl7SE2iyWkoIIbogp9vD3Z9u5LM/DqPVwAuXDm9VYgM1IzcyLdVy/fv355dffuHjjz/mvvvuAyArK4uRI0cycuRIsrOzee655xg5ciQ33nhjk9e68cYb6y0F//bbbxk5ciTnnHMOAJdffjkjR45k3rx5gLoE/OgpqZNPPpk33niDuXPnMnz4cH766ScefvjhOse88MILREVFccoppzB9+nSmTJnCqFGj6sXUt29fTjnlFAYMGMBJJ51U7/OffPIJN9100zG+S62nURSl8TV/XVBpaSkRERGUlJQQHh4e7HCEECLgqpxuZn20gZ935GLQafjX5SOZOjSp1dd98vvtvLEsnZtP68XsaQMDEGnXUVVVRXp6Oj179sRsNrfLPSsrK+nfvz+ffvopY8eOPebxLpeLhIQEfvzxR0488cQ2iUlRFPr27cttt93GvffeW+dzP/74I/fddx+bN29Gr2944qip76M/v79lWkoIIbqQSoebP7//B8v2FGDUa/n31aOZNMD/5cINibSq01IyctMxWCwW3nvvPQoKCpp1/JEjR7jnnnsCslqrIfn5+XzyySfk5OTU6W3jZbPZeOeddxpNbAIpqNNSS5cuZfr06SQnJ6PRaPj666+Pec6SJUsYNWoUJpOJPn36MH/+/DaPUwghOoOyKicz3l7Dsj0FWI065l83JmCJDairpQCKpaC4w5g4cSLTp09v1rHx8fE8/PDDrV6p1dT1n3jiCf7zn/8QFRVV7/MXX3xxg1NVbSGoyY3NZmP48OG8+uqrzTo+PT2dc845h0mTJrFx40buvvtubrzxRhYtWtTGkQohRMdWXOHg6jdXs+bAEcLMet6/4URO6RMb0HtESkGxaIKiKOTn53PllVcGO5TgTktNnTrV1yGxOebNm0fPnj15/vnnAXX52vLly3nxxReZMmVKW4UphBAdWl5ZFde+tYadOWVEWQ28f8NJDEmJCPh9akZuZFpKdGydarXUqlWrfJt0eU2ZMoVVq1YFKSIhhAiuQ0cquHTeKnbmlBEXZuLTm8e2SWIDMi0lOo9OVVCck5NDQkJCnecSEhIoLS2lsrKywXXzdrsdu93u+7i0tLTN4xRCiPawN6+Mq99cQ05pFanRFj644SR6xIS02f28BcXFlU4URWmz2g0hWqtTjdy0xJw5c4iIiPC9paamBjskIYRotS2HS7j037+TU1pF3/hQPr/5lDZNbAAiLerIjcPlodIpO4OLjqtTJTeJiYnk5ubWeS43N5fw8PBGux3Onj2bkpIS39uhQ4faI1QhhGgzq/cXcsUbv3PE5mBYtwg+vXksiRFt31vFatRh1Km/NmRqSnRknWpaauzYsfzwww91nvvf//7XZPMik8mEyWRq69CEEKJd/LIzl1s/WI/d5eHkXtG8ce0JhJkN7XJvjUZDhNVAfpm6M3hypOwMLjqmoI7clJeXs3HjRjZu3AioS703btzo20J99uzZXHvttb7jb7nlFvbv388DDzzAzp07ee211/jss8+45557ghG+EEK0q283ZfHn99Zhd3mYPDCe+TNPbLfExss7NSUrpkRHFtTk5o8//vDtpwFw7733MnLkSB555BEAsrOzfYkOQM+ePfn+++/53//+x/Dhw3n++ed58803ZRm4EKLL+3D1Qe76ZAMuj8L5I5J5/erRmA26do8jyiq9broif5vqLl++nHHjxhETE4PFYmHAgAG8+OKL7RNsMwR1WmrixIk0tbVVQ92HJ06cyIYNG9owKiGE6FheX7KPZxbuBOCak3vw+LmD0WqDs1IpQpaDd0neprrXX389F1544TGPDwkJYdasWQwbNoyQkBCWL1/OzTffTEhICH/+85/bIeKmdaqaGyGEOJ4oisKzi3bx+pJ9ANw+qTd/Oat/UJdgy87gXZO/TXVrz7oApKWlsWDBApYtWybJjRBCiIa5PQqPfLOVD1erU/MPTRvAn0/rHeSoanrdlMi01DEpihK0JfMWg65dk+ANGzawcuVK/vnPf7bbPZsiyY0QQnQwTreH+z7bxLebstBo4KkLhnLF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mjZtmtqwYYNatmyZysnJUQsWLIiV+eabb5Tb7Vbz589XW7duVc8++6yyWq1q+fLlsTLdsW3XrVunBg0apEaPHq3mzZsXO94b26S2tlYNHDhQ3XbbbWrt2rXqm2++Ue+//77avXt3rMyiRYtUenq6evPNN9WmTZvUNddcowYPHqxaWlpiZWbMmKHGjBmjvvjiC/Xpp5+qoqIidfPNN8fONzQ0qLy8PDVnzhy1ZcsW9ac//Um5XC714osvxsp89tlnymq1qieeeEJt3bpV/exnP1M2m01t3ry5axoj6vHHH1fZ2dnqnXfeUXv27FFLly5Vqamp6t///d9jZXpDmyxbtkw98sgj6vXXX1eAeuONN+LOd6c2aE9duqJd6uvr1bRp09Sf//xntX37drVmzRo1ceJENX78+LhrJGO7dDQJbjrAxIkT1b333ht7HolEVN++fdXChQsTWKuOU11drQD18ccfK6XMX0CbzaaWLl0aK7Nt2zYFqDVr1iilzF9gi8WiKisrY2Wef/555fF4VCAQUEop9eCDD6pzzz037r1uuukmNX369Njz7ta2jY2Nqri4WK1YsUJdcsklseCmt7bJQw89pC6++OITnjcMQ+Xn56t/+7d/ix2rr69XDodD/elPf1JKKbV161YFqL/+9a+xMu+9957SNE0dOnRIKaXUb37zG5WZmRlrp9b3HjZsWOz5d7/7XTVr1qy49580aZL64Q9/eHYf8jTNmjVL3XHHHXHHrr/+ejVnzhylVO9sk29/iXenNmhPXTpLW0Hft61bt04Bat++fUqp3tEuHUGGpc5SMBikrKyMadOmxY5ZLBamTZvGmjVrElizjtPQ0ABAVlYWAGVlZYRCobjPXFJSwoABA2Kfec2aNYwaNYq8vLxYmenTp+P1evnqq69iZY69RmuZ1mt0x7a99957mTVr1nH17q1t8tZbbzFhwgRuvPFGcnNzOe+88/jd734XO79nzx4qKyvj6puens6kSZPi2iUjI4MJEybEykybNg2LxcLatWtjZaZMmYLdbo+VmT59Ojt27KCuri5W5mRt11UuvPBCSktL2blzJwCbNm1i9erVzJw5E+idbfJt3akN2lOXRGpoaEDTNDIyMgBpl/aS4OYsHTlyhEgkEveFBZCXl0dlZWWCatVxDMPg/vvv56KLLmLkyJEAVFZWYrfbY79srY79zJWVlW22Seu5k5Xxer20tLR0u7ZdsmQJf/vb31i4cOFx53prm3zzzTc8//zzFBcX8/7773P33XfzT//0T/z+978Hjn6uk9W3srKS3NzcuPO6rpOVldUhbdfV7fLwww/zve99j5KSEmw2G+eddx73338/c+bMiatvb2qTb+tObdCeuiSK3+/noYce4uabb45thCnt0j69bldwcXruvfdetmzZwurVqxNdlYQ6cOAA8+bNY8WKFTidzkRXp9swDIMJEybwr//6rwCcd955bNmyhRdeeIG5c+cmuHaJ8dprr/HKK6/w6quvcu6557Jx40buv/9++vbt22vbRJy+UCjEd7/7XZRSPP/884muTo8jPTdnKScnB6vVelxWTFVVFfn5+QmqVce47777eOedd1i5ciX9+/ePHc/PzycYDFJfXx9X/tjPnJ+f32abtJ47WRmPx4PL5epWbVtWVkZ1dTXjxo1D13V0Xefjjz/mP/7jP9B1nby8vF7XJgAFBQWMGDEi7tjw4cPZv38/cPRznay++fn5VFdXx50Ph8PU1tZ2SNt1dbs88MADsd6bUaNGccstt/DjH/841uPXG9vk27pTG7SnLl2tNbDZt28fK1asiPXaQO9ul9Mhwc1ZstvtjB8/ntLS0tgxwzAoLS1l8uTJCazZmVNKcd999/HGG2/w0UcfMXjw4Ljz48ePx2azxX3mHTt2sH///thnnjx5Mps3b477JWz9JW39Mpw8eXLcNVrLtF6jO7Xt1KlT2bx5Mxs3bozdJkyYwJw5c2KPe1ubAFx00UXHLROwc+dOBg4cCMDgwYPJz8+Pq6/X62Xt2rVx7VJfX09ZWVmszEcffYRhGEyaNClW5pNPPiEUCsXKrFixgmHDhpGZmRkrc7K26yo+nw+LJf5Pq9VqxTAMoHe2ybd1pzZoT126Umtgs2vXLj788EOys7PjzvfWdjltiZ7RnAyWLFmiHA6HWrx4sdq6dav6h3/4B5WRkRGXFdOT3H333So9PV2tWrVKVVRUxG4+ny9W5kc/+pEaMGCA+uijj9T69evV5MmT1eTJk2PnW9Oer7zySrVx40a1fPly1adPnzbTnh944AG1bds29dxzz7WZ9txd2/bYbCmlemebrFu3Tum6rh5//HG1a9cu9corryi3263++Mc/xsosWrRIZWRkqP/5n/9RX375pbr22mvbTPk977zz1Nq1a9Xq1atVcXFxXGprfX29ysvLU7fccovasmWLWrJkiXK73celtuq6rp588km1bds29dhjjyUkFXzu3LmqX79+sVTw119/XeXk5KgHH3wwVqY3tEljY6PasGGD2rBhgwLU008/rTZs2BDL+ulObdCeunRFuwSDQXXNNdeo/v37q40bN8b9/T028ykZ26WjSXDTQZ599lk1YMAAZbfb1cSJE9UXX3yR6CqdMaDN28svvxwr09LSou655x6VmZmp3G63uu6661RFRUXcdfbu3atmzpypXC6XysnJUT/5yU9UKBSKK7Ny5Uo1duxYZbfb1ZAhQ+Leo1V3bdtvBze9tU3efvttNXLkSOVwOFRJSYn67W9/G3feMAz185//XOXl5SmHw6GmTp2qduzYEVempqZG3XzzzSo1NVV5PB51++23q8bGxrgymzZtUhdffLFyOByqX79+atGiRcfV5bXXXlNDhw5VdrtdnXvuuerdd9/t+A98Cl6vV82bN08NGDBAOZ1ONWTIEPXII4/EfTn1hjZZuXJlm39H5s6dq5TqXm3Qnrp0lJO1y549e07493flypVJ3S4dTVPqmGUzhRBCCCF6OJlzI4QQQoikIsGNEEIIIZKKBDdCCCGESCoS3AghhBAiqUhwI4QQQoikIsGNEEIIIZKKBDdCCCGESCoS3AghxAncdtttzJ49O9HVEEKcJgluhBCd7vDhw9x9990MGDAAh8NBfn4+06dP57PPPkt01YQQSUhPdAWEEMnvhhtuIBgM8vvf/54hQ4ZQVVVFaWkpNTU1ia6aECIJSc+NEKJT1dfX8+mnn/KrX/2Kyy67jIEDBzJx4kQWLFjANddcEytz55130qdPHzweD5dffjmbNm2Ku87bb7/N+eefj9PpJCcnh+uuuy52rq6ujltvvZXMzEzcbjczZ85k165dsfOLFy8mIyOD999/n+HDh5OamsqMGTOoqKiIlYlEIsyfP5+MjAyys7N58MEH+fbuNH/5y18YNWoULpeL7Oxspk2bRnNzc2c0mxDiLEhwI4ToVKmpqaSmpvLmm28SCATaLHPjjTdSXV3Ne++9R1lZGePGjWPq1KnU1tYC8O6773Lddddx1VVXsWHDBkpLS5k4cWLs9bfddhvr16/nrbfeYs2aNSiluOqqqwiFQrEyPp+PJ598kj/84Q988skn7N+/n3/+53+OnX/qqadYvHgxL730EqtXr6a2tpY33ngjdr6iooKbb76ZO+64g23btrFq1Squv/764wIgIUQ3kNBtO4UQvcJf/vIXlZmZqZxOp7rwwgvVggUL1KZNm5RSSn366afK4/Eov98f95pzzjlHvfjii0oppSZPnqzmzJnT5rV37typAPXZZ5/Fjh05ckS5XC712muvKaWUevnllxWgdu/eHSvz3HPPqby8vNjzgoIC9cQTT8Seh0Ih1b9/f3XttdcqpZQqKytTgNq7d+9ZtIQQoitIz40QotPdcMMNlJeX89ZbbzFjxgxWrVrFuHHjWLx4MZs2baKpqYns7OxYL09qaip79uzh66+/BmDjxo1MnTq1zWtv27YNXdeZNGlS7Fh2djbDhg1j27ZtsWNut5tzzjkn9rygoIDq6moAGhoaqKioiLuGrutMmDAh9nzMmDFMnTqVUaNGceONN/K73/2Ourq6jmkgIUSHkgnFQogu4XQ6ueKKK7jiiiv4+c9/zp133sljjz3GPffcQ0FBAatWrTruNRkZGQC4XK6zfn+bzRb3XNO00xpSslqtrFixgs8//5wPPviAZ599lkceeYS1a9cyePDgs66fEKLjSM+NECIhRowYQXNzM+PGjaOyshJd1ykqKoq75eTkADB69GhKS0vbvM7w4cMJh8OsXbs2dqympoYdO3YwYsSIdtUlPT2dgoKCuGuEw2HKysriymmaxkUXXcQvfvELNmzYgN1uj5uXI4ToHqTnRgjRqWpqarjxxhu54447GD16NGlpaaxfv54nnniCa6+9lmnTpjF58mRmz57NE088wdChQykvL49NIp4wYQKPPfYYU6dO5ZxzzuF73/se4XCYZcuW8dBDD1FcXMy1117LXXfdxYsvvkhaWhoPP/ww/fr149prr213PefNm8eiRYsoLi6mpKSEp59+mvr6+tj5tWvXUlpaypVXXklubi5r167l8OHDDB8+vBNaTQhxNiS4EUJ0qtTUVCZNmsSvf/1rvv76a0KhEIWFhdx111389Kc/RdM0li1bxiOPPMLtt9/O4cOHyc/PZ8qUKeTl5QFw6aWXsnTpUn75y1+yaNEiPB4PU6ZMib3Hyy+/zLx58/i7v/s7gsEgU6ZMYdmyZccNRZ3MT37yEyoqKpg7dy4Wi4U77riD6667joaGBgA8Hg+ffPIJzzzzDF6vl4EDB/LUU08xc+bMjm0wIcRZ09TpDDoLIYQQQnRzMudGCCGEEElFghshhBBCJBUJboQQQgiRVCS4EUIIIURSkeBGCCGEEElFghshhBBCJBUJboQQQgiRVCS4EUIIIURSkeBGCCGEEElFghshhBBCJBUJboQQQgiRVCS4EUIIIURS+f+PrDFaymNh7wAAAABJRU5ErkJggg==", "text/plain": [ "
      " ] @@ -304,13 +319,13 @@ } ], "source": [ - "res.node[\"T1\"].loc[0:3600*36, query].plot(style='k.')\n", + "# res.node[\"T1\"].loc[0:3600*36, query].plot(style='k.')\n", "for newk, resk in d_k1.items():\n", " resk.node[\"CL2\"].loc[0:3600*36, query].plot()\n", - "plt.legend(['Tracer', *[\"{:.1f}\".format(k) for k in d_k1.keys()]], title=\"k1 (1/day)\")\n", - "plt.title(\"Cl2 at node {}\".format(query))\n", + "plt.legend([\"{:.1f}\".format(k) for k in d_k1.keys()], title=\"k1 (1/day)\")\n", + "plt.title(\"Chlorine residual at node {}\".format(query))\n", "plt.xlabel('Seconds')\n", - "plt.ylabel('River Fraction [/100%] // Concentraion [mg/L]')" + "plt.ylabel('Concentraion [mg/L]')" ] }, { From 4894e82653bce7b5d3a0e3cd2b02cb4fb249cf7b Mon Sep 17 00:00:00 2001 From: David Hart Date: Tue, 7 May 2024 11:10:12 -0600 Subject: [PATCH 69/75] Update to demo --- examples/demos/multisource-cl-decay.ipynb | 28 ++++++++++++----------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/examples/demos/multisource-cl-decay.ipynb b/examples/demos/multisource-cl-decay.ipynb index 943f9e898..5e9e106da 100644 --- a/examples/demos/multisource-cl-decay.ipynb +++ b/examples/demos/multisource-cl-decay.ipynb @@ -70,7 +70,11 @@ "### Add the MSX reaction system information\n", "This reaction system comes from the EPANET-MSX user manual. There are two species: Free Chlorine and a tracer. The tracer is used to select which decay coefficient is being used. The river is source 1, the lake is source 2.\n", "\n", - "The amount of free chlorine is based on the rate reaction below, " + "The amount of free chlorine is based on the rate reaction:\n", + "\n", + "$$\n", + " \\frac{d}{dt}\\mathrm{Cl_2} = -(k_1 T + k_2(1-T)) \\mathrm{Cl_2}\n", + "$$" ] }, { @@ -82,15 +86,14 @@ "name": "stdout", "output_type": "stream", "text": [ - "(\"Species(name='CL2', species_type=, units='MG', \"\n", - " \"atol=None, rtol=None, note='Free Chlorine')\")\n" + "Species(name='CL2', species_type=, units='MG', atol=None, rtol=None, note='Free Chlorine')\n" ] } ], "source": [ "T1 = wn.msx.add_species('T1','bulk',units='MG', note='Source 1 Tracer')\n", "Cl2 = wn.msx.add_species('CL2','bulk', units='MG', note='Free Chlorine')\n", - "pprint(repr(Cl2))" + "print(repr(Cl2))" ] }, { @@ -102,14 +105,14 @@ "name": "stdout", "output_type": "stream", "text": [ - "\"Constant(name='k2', value=17.7, units='1/day')\"\n" + "Constant(name='k2', value=17.7, units='1/day')\n" ] } ], "source": [ "k1 = wn.msx.add_constant('k1', 1.3, units='1/day')\n", "k2 = wn.msx.add_constant('k2', 17.7, units='1/day')\n", - "pprint(repr(k2))" + "print(repr(k2))" ] }, { @@ -121,15 +124,14 @@ "name": "stdout", "output_type": "stream", "text": [ - "(\"Reaction(species_name='CL2', expression_type=, \"\n", - " \"expression='-(k1*T1 + k2*(1-T1))*CL2')\")\n" + "Reaction(species_name='CL2', expression_type=, expression='-(k1*T1 + k2*(1-T1))*CL2')\n" ] } ], "source": [ "rxn_T1 = wn.msx.add_reaction('T1', 'pipe', 'rate', '0')\n", "rxn_Cl2 = wn.msx.add_reaction('CL2', 'pipe', 'rate', '-(k1*T1 + k2*(1-T1))*CL2')\n", - "pprint(repr(rxn_Cl2))" + "print(repr(rxn_Cl2))" ] }, { @@ -142,7 +144,7 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 7, "metadata": {}, "outputs": [ { @@ -176,15 +178,15 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": 8, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "Node results: demand, head, pressure, quality, T1, CL2\n", - "Link results: quality, flowrate, velocity, headloss, status, setting, friction_factor, reaction_rate, T1, CL2\n" + "Node results: demand, head, pressure, quality, T1, CL2\n", + "Link results: quality, flowrate, velocity, headloss, status, setting, friction_factor, reaction_rate, T1, CL2\n" ] } ], From 8124da7257c32347a2d6cd1d29fe4f2a2f16a0e4 Mon Sep 17 00:00:00 2001 From: David Hart Date: Mon, 20 May 2024 11:06:03 -0600 Subject: [PATCH 70/75] MSX updates * Move library to new directory * Updates to documentation * New ipynb demo * various bug fixes --- MANIFEST.in | 4 +- documentation/advancedsim.rst | 32 +- documentation/references.bib | 21 + documentation/resultsobject.rst | 16 + documentation/waterquality.rst | 6 +- documentation/waterquality_msx.rst | 8 +- examples/data/Net3_arsenic.msx | 1 + examples/demos/multisource-cl-decay.ipynb | 277 +++++- wntr/epanet/msx/io.py | 2 +- wntr/library/msx/__init__.py | 1 + .../library.py => library/msx/_msxlibrary.py} | 14 +- .../msx}/arsenic_chloramine.json | 0 .../msx}/batch_chloramine_decay.json | 0 .../msx}/lead_ppm.json | 0 .../msx}/nicotine.json | 0 .../msx}/nicotine_ri.json | 0 wntr/msx/__init__.py | 3 +- wntr/msx/_library_data/msx.schema.json | 873 ------------------ wntr/msx/base.py | 36 +- wntr/msx/elements.py | 6 +- wntr/msx/io.py | 123 +++ wntr/msx/model.py | 13 +- 22 files changed, 516 insertions(+), 920 deletions(-) create mode 100644 wntr/library/msx/__init__.py rename wntr/{msx/library.py => library/msx/_msxlibrary.py} (98%) rename wntr/{msx/_library_data => library/msx}/arsenic_chloramine.json (100%) rename wntr/{msx/_library_data => library/msx}/batch_chloramine_decay.json (100%) rename wntr/{msx/_library_data => library/msx}/lead_ppm.json (100%) rename wntr/{msx/_library_data => library/msx}/nicotine.json (100%) rename wntr/{msx/_library_data => library/msx}/nicotine_ri.json (100%) delete mode 100644 wntr/msx/_library_data/msx.schema.json create mode 100644 wntr/msx/io.py diff --git a/MANIFEST.in b/MANIFEST.in index 7157c882b..0f6c9b053 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -8,5 +8,5 @@ include wntr/sim/aml/numpy.i include wntr/sim/network_isolation/network_isolation* include wntr/sim/network_isolation/numpy.i include wntr/tests/networks_for_testing/*.inp -include wntr/msx/_library_data/*.json -include wntr/msx/_library_data/*.msx +include wntr/library/msx/*.json +include wntr/library/msx/*.msx diff --git a/documentation/advancedsim.rst b/documentation/advancedsim.rst index cb295bdd3..2235aa640 100644 --- a/documentation/advancedsim.rst +++ b/documentation/advancedsim.rst @@ -252,7 +252,9 @@ The solution for :math:`u` and :math:`v` is then returned and printed to four si Building MSX models ------------------- -The following two examples illustrate how to build :class:`~wntr.msx.model.MsxModel` objects in WNTR +The following two examples illustrate how to build :class:`~wntr.msx.model.MsxModel` objects in WNTR. +There is also a jupyter notebook in the examples/demos source directory called multisource-cl-decay.ipynb +that demonstrates this process with Net3. .. _msx_example1_lead: @@ -260,7 +262,7 @@ Plumbosolvency of lead ^^^^^^^^^^^^^^^^^^^^^^ The following example builds the plumbosolvency of lead model -described in [BWMS20]_. The model represents plumbosolvency +described in :cite:p:`bwms20`. The model represents plumbosolvency in lead pipes within a dwelling. The MSX model is built without a specific water network model in mind. @@ -332,7 +334,7 @@ Type Name Value Units --------------- --------------- --------------- --------------------------------- ------------------------ constant :math:`M` 0.117 :math:`\mathrm{μg~m^{-2}~s^{-1}}` desorption rate constant :math:`E` 140.0 :math:`\mathrm{μg~L^{-1}}` saturation level -parameter :math:`F` 0 `n/a` is pipe made of lead? +parameter :math:`F` 0 `flag` is pipe made of lead? =============== =============== =============== ================================= ======================== These are added to the MsxModel using the using the @@ -344,7 +346,18 @@ methods. >>> msx.add_constant("M", value=0.117, note="Desorption rate (ug/m^2/s)", units="ug * m^(-2) * s^(-1)") >>> msx.add_constant("E", value=140.0, note="saturation/plumbosolvency level (ug/L)", units="ug/L") - >>> msx.add_parameter("F", global_value=0, note="determines which pipes have reactions") + >>> msx.add_parameter("F", global_value=0, note="determines which pipes are made of lead") + +If the value of one of these needs to be modified, then it can be accessed and modified as an object +in the same manner as other WNTR objects. + +.. doctest:: + + >>> M = msx.reaction_system.constants['M'] + >>> M.value = 0.118 + >>> M + Constant(name='M', value=0.118, units='ug * m^(-2) * s^(-1)', note='Desorption rate (ug/m^2/s)') + Note that all models must include both pipe and tank reactions. Since the model only has reactions within @@ -374,16 +387,23 @@ method. .. doctest:: >>> msx.add_reaction("PB2", "pipe", "RATE", expression="F * Av * M * (E - PB2) / E") + + +If the species is saved as an object, as was done above, then it can be passed instead of the species name. + +.. doctest:: + >>> msx.add_reaction(PB2, "tank", "rate", expression="0") + Arsenic oxidation and adsorption ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ This example models monochloramine oxidation of arsenite/arsenate and wall -adsorption/desorption, as given in section 3 of the EPANET-MSX user manual [SRU23]_. +adsorption/desorption, as given in section 3 of the EPANET-MSX user manual :cite:p:`shang2023`. The system of equations for the reaction in pipes is given in Eq. (2.4) through (2.7) -in [SRU23]_. This is a simplified model, taken from [GSCL94]_. +in :cite:p:`shang2023`. This is a simplified model, taken from :cite:p:`gscl94`. .. math:: diff --git a/documentation/references.bib b/documentation/references.bib index e07d3450c..13f609914 100644 --- a/documentation/references.bib +++ b/documentation/references.bib @@ -39,6 +39,18 @@ @misc{bieni19 year = "2019" } +@article{bwms20, + author="Burkhardt, J. B. and Woo, J. and Mason, J. and Shang, F. and Triantafyllidou, S. and Schock, M.R., and Lytle, D., and Murray, R." , + year = 2020, + title="Framework for Modeling Lead in Premise Plumbing Systems Using EPANET", + journal="Journal of Water Resources Planning and Management", + volume=146, + number=12, + doi="10.1061/(asce)wr.1943-5452.0001304", + eprint="33627937", + eprintclass="PMID" +} + @book{crlo02, author = "Crowl, D.A. and Louvar, J.F.", address = "Upper Saddle River, NJ", @@ -79,6 +91,15 @@ @misc{gacl18 year = "2018" } +@article{gscl94, + author = "Gu, B. and Schmitt, J. and Chen, Z. and Liang, L. and McCarthy, J.F.", + title = "Adsorption and desorption of natural organic matter on iron oxide: mechanisms and models", + year = "1994", + journal = "Environmental Science and Technology", + volume = "28", + pages = "38--46" +} + @inproceedings{hass08, author = "Hagberg, Aric A. and Schult, Daniel A. and Swart, Pieter J.", booktitle = "Proceedings of the 7th {Python} in Science Conference ({SciPy2008}), August 19-24, Pasadena, CA, USA", diff --git a/documentation/resultsobject.rst b/documentation/resultsobject.rst index 7ba089176..20c8e0c45 100644 --- a/documentation/resultsobject.rst +++ b/documentation/resultsobject.rst @@ -206,3 +206,19 @@ For example, DataFrames can be saved to Excel files using: .. note:: The Pandas method ``to_excel`` requires the Python package **openpyxl** :cite:p:`gacl18`, which is an optional dependency of WNTR. + + +Water quality results +--------------------- +Water quality metrics are stored under the 'quality' key of the node and link results +if the EpanetSimulator is used. The units of the quality results depend on the quality +parameter that is used (see :ref:`_water_quality_simulation`) and can be the age, +concentration, or the fraction of water that belongs to a tracer. If the parameter +is set to 'NONE', then the quality results will be zero. + +The quality of a link is equal to the average across the length of the link. The quality +at a node is the instantaneous value. + +When using the EPANET-MSX water quality model, each species is given its own key in the +node and link results objects, and the 'quality' results still references the EPANET +water quality results. diff --git a/documentation/waterquality.rst b/documentation/waterquality.rst index 8b8c6ee37..697c83f60 100644 --- a/documentation/waterquality.rst +++ b/documentation/waterquality.rst @@ -18,10 +18,10 @@ Water quality simulation Water quality simulations can only be run using the EpanetSimulator. This includes the ability to run -EPANET 2.00.12 Programmer's Toolkit [Ross00]_ or -EPANET 2.2.0 Programmer's Toolkit [RWTS20]_ for single species, water age, and tracer analysis. +EPANET 2.00.12 Programmer's Toolkit :cite:p:`ross00` or +EPANET 2.2.0 Programmer's Toolkit :cite:p:`rwts20` for single species, water age, and tracer analysis. -WNTR also includes the ability to run EPANET-MSX 2.0 [SRU23]_, see :ref:`msx_water_quality` for more information. +WNTR also includes the ability to run EPANET-MSX 2.0 :cite:p:`shang2023`, see :ref:`msx_water_quality` for more information. After defining water quality options and sources (described in the :ref:`wq_options` and :ref:`sources` sections below), a hydraulic and water quality simulation using the EpanetSimulator is run using the following code: diff --git a/documentation/waterquality_msx.rst b/documentation/waterquality_msx.rst index 3ffcf6145..bbb4826a9 100644 --- a/documentation/waterquality_msx.rst +++ b/documentation/waterquality_msx.rst @@ -18,13 +18,13 @@ Multi-species water quality simulation ======================================= -The EpanetSimulator can use EPANET-MSX 2.0 [SRU23]_ to run +The EpanetSimulator can use EPANET-MSX 2.0 :cite:p:`shang2023` to run multi-species water quality simulations. Additional multi-species simulation options are discussed in :ref:`advanced_simulation`. A multi-species analysis is run if a :class:`~wntr.msx.model.MsxModel` is added to the :class:`~wntr.network.model.WaterNetworkModel`, as shown below. -In this example, the MsxModel is created from a MSX file (see [SRU23]_ for more information on file format). +In this example, the MsxModel is created from a MSX file (see :cite:p:`shang2023` for more information on file format). .. doctest:: @@ -80,9 +80,9 @@ WNTR also contains a library of MSX models that are accessed through the :class:`~wntr.msx.library.ReactionLibrary`. This includes the following models: -* `Arsenic oxidation/adsorption `_ [SRU23]_ +* `Arsenic oxidation/adsorption `_ :cite:p:`shang2023` * `Batch chloramine decay `_ -* `Lead plumbosolvency `_ [BWMS20]_ +* `Lead plumbosolvency `_ :cite:p:`bwms20` * `Nicotine/chlorine reaction `_ * `Nicotine/chlorine reaction with reactive intermediate `_ diff --git a/examples/data/Net3_arsenic.msx b/examples/data/Net3_arsenic.msx index bb01238ae..51c37cafd 100644 --- a/examples/data/Net3_arsenic.msx +++ b/examples/data/Net3_arsenic.msx @@ -48,6 +48,7 @@ Arsenic Oxidation/Adsorption Example ;Initial conditions (= 0 if not specified here) NODE River AS3 10.0 NODE River NH2CL 2.5 + NODE Lake NH2CL 2.5 [REPORT] NODES All ;Report results for nodes C and D diff --git a/examples/demos/multisource-cl-decay.ipynb b/examples/demos/multisource-cl-decay.ipynb index 5e9e106da..da1115d55 100644 --- a/examples/demos/multisource-cl-decay.ipynb +++ b/examples/demos/multisource-cl-decay.ipynb @@ -86,7 +86,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "Species(name='CL2', species_type=, units='MG', atol=None, rtol=None, note='Free Chlorine')\n" + "Species(name='CL2', species_type='BULK', units='MG', atol=None, rtol=None, note='Free Chlorine')\n" ] } ], @@ -124,7 +124,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "Reaction(species_name='CL2', expression_type=, expression='-(k1*T1 + k2*(1-T1))*CL2')\n" + "Reaction(species_name='CL2', expression_type='RATE', expression='-(k1*T1 + k2*(1-T1))*CL2')\n" ] } ], @@ -330,12 +330,281 @@ "plt.ylabel('Concentraion [mg/L]')" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Save the model\n", + "The model is now saved in two formats: the EPANET-MSX style format as Net3.msx and then as a JSON file, Net3-msx.json.\n", + "We also can save the model as in a library format; this strips the JSON file of any network-specific information so that it only contains the species, constants, and reaction dynamics." + ] + }, { "cell_type": "code", - "execution_count": null, + "execution_count": 12, "metadata": {}, "outputs": [], - "source": [] + "source": [ + "from wntr.msx import io as msxio\n", + "msxio.write_msxfile(wn.msx, 'Net3.msx')\n", + "msxio.write_json(wn.msx, 'Net3-msx.json')\n", + "msxio.write_json(wn.msx, 'multisource-cl.json', as_library=True)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We can look at the file that was written out, and we can read in the two JSON files to see how the library format has stripped out the network data." + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "; WNTR-reactions MSX file generated 2024-05-20 07:00:10.969400\n", + "\n", + "[TITLE]\n", + " Multisource Chlorine Decay\n", + "\n", + "[OPTIONS]\n", + " AREA_UNITS FT2\n", + " RATE_UNITS DAY\n", + " SOLVER RK5\n", + " COUPLING NONE\n", + " TIMESTEP 300\n", + " ATOL 0.0001\n", + " RTOL 0.0001\n", + " COMPILER NONE\n", + " SEGMENTS 5000\n", + " PECLET 1000\n", + "\n", + "[SPECIES]\n", + " BULK T1 MG ; Source 1 Tracer\n", + " BULK CL2 MG ; Free Chlorine\n", + "\n", + "[COEFFICIENTS]\n", + " CONSTANT k1 16.900000000000002\n", + " CONSTANT k2 17.7 \n", + "\n", + "[TERMS]\n", + "\n", + "[PIPES]\n", + " RATE T1 0 \n", + " RATE CL2 -(k1*T1 + k2*(1-T1))*CL2 \n", + "\n", + "[TANKS]\n", + "\n", + "[DIFFUSIVITY]\n", + "\n", + "[PARAMETERS]\n", + "\n", + "[PATTERNS]\n", + "\n", + "[REPORT]\n", + "\n", + "[QUALITY]\n", + " NODE River T1 1.0\n", + " NODE River CL2 1.2\n", + " NODE Lake CL2 1.2\n", + "\n", + "[SOURCES]\n", + "\n", + "\n" + ] + } + ], + "source": [ + "with open('Net3.msx', 'r') as fin:\n", + " print(fin.read())" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "With network data:\n", + "{'initial_quality': {'CL2': {'global_value': 0.0,\n", + " 'link_values': {},\n", + " 'node_values': {'Lake': 1.2, 'River': 1.2}},\n", + " 'T1': {'global_value': 0.0,\n", + " 'link_values': {},\n", + " 'node_values': {'River': 1.0}}},\n", + " 'parameter_values': {},\n", + " 'patterns': {},\n", + " 'sources': {}}\n", + "As a library:\n", + "{'initial_quality': {}, 'parameter_values': {}, 'patterns': {}, 'sources': {}}\n" + ] + } + ], + "source": [ + "import json\n", + "with_net: dict = None\n", + "without_net: dict = None\n", + "\n", + "with open('Net3-msx.json', 'r') as fin:\n", + " with_net = json.load(fin)\n", + "with open('multisource-cl.json', 'r') as fin:\n", + " without_net = json.load(fin)\n", + "\n", + "print('With network data:')\n", + "pprint(with_net['network_data'])\n", + "\n", + "print('As a library:')\n", + "pprint(without_net['network_data'])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Using the MSX WNTR library\n", + "WNTR now includes a library functionality that allows a user to access certain objects by name.\n", + "The MSX integration includes adding a library of certain reaction models that are described in\n", + "the EPANET-MSX user manual. This section demonstrates how to use the model that was just saved\n", + "in the library." + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "['arsenic_chloramine',\n", + " 'batch_chloramine_decay',\n", + " 'lead_ppm',\n", + " 'msx.schema',\n", + " 'nicotine',\n", + " 'nicotine_ri',\n", + " 'ms-cl-tmp',\n", + " 'Multisource-Cl',\n", + " 'Net3-msx',\n", + " 'Net3',\n", + " 'Net3_multisource-cl',\n", + " 'temp.check',\n", + " 'temp']" + ] + }, + "execution_count": 15, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "from wntr.library.msx import MsxLibrary\n", + "my_library = MsxLibrary(extra_paths=['.']) # load files from the current directory\n", + "my_library.model_name_list()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Note that this has pulled in a lot more files than might be expected. This is because it is getting the default models (the first five models) followed by all the models in the current directory ('.'). It grabs any file that has the extension .json or .msx, which means that it has pulled in \"temp\", since this demo has run the EpanetSimulator several times, Net3, Net3-msx, and multisource-cl, because they were just created.\n", + "\n", + "The models are accessed by name. To see how they are different, compare the initial quality for the \"Net3\" model (which came from the .msx file created above) and the \"multisource-cl\" model (created with as_library=True)." + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'T1': InitialQuality(global_value=0.0, node_values=<1 entries>, link_values=<0 entries>),\n", + " 'CL2': InitialQuality(global_value=0.0, node_values=<2 entries>, link_values=<0 entries>)}" + ] + }, + "execution_count": 16, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "my_library.get_model('Net3').network_data.initial_quality" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'T1': InitialQuality(global_value=0.0, node_values=<0 entries>, link_values=<0 entries>),\n", + " 'CL2': InitialQuality(global_value=0.0, node_values=<0 entries>, link_values=<0 entries>)}" + ] + }, + "execution_count": 17, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "my_library.get_model('Multisource-Cl').network_data.initial_quality" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now, examine a model that comes from the built-in data." + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "AS3 \t Species(name='AS3', species_type='BULK', units='UG', atol=None, rtol=None, note='Dissolved arsenite')\n", + "AS5 \t Species(name='AS5', species_type='BULK', units='UG', atol=None, rtol=None, note='Dissolved arsenate')\n", + "AStot \t Species(name='AStot', species_type='BULK', units='UG', atol=None, rtol=None, note='Total dissolved arsenic')\n", + "AS5s \t Species(name='AS5s', species_type='WALL', units='UG', atol=None, rtol=None, note='Adsorbed arsenate')\n", + "NH2CL \t Species(name='NH2CL', species_type='BULK', units='MG', atol=None, rtol=None, note='Monochloramine')\n", + "Ka \t Constant(name='Ka', value=10.0, units='1 / (MG * HR)', note='Arsenite oxidation rate coefficient')\n", + "Kb \t Constant(name='Kb', value=0.1, units='1 / HR', note='Monochloramine decay rate coefficient')\n", + "K1 \t Constant(name='K1', value=5.0, units='M^3 / (UG * HR)', note='Arsenate adsorption coefficient')\n", + "K2 \t Constant(name='K2', value=1.0, units='1 / HR', note='Arsenate desorption coefficient')\n", + "Smax \t Constant(name='Smax', value=50.0, units='UG / M^2', note='Arsenate adsorption limit')\n", + "Ks \t Term(name='Ks', expression='K1/K2', note='Equil. adsorption coeff.')\n", + "AS3 \t Reaction(species_name='AS3', expression_type='RATE', expression='-Ka*AS3*NH2CL', note='Arsenite oxidation')\n", + "AS5 \t Reaction(species_name='AS5', expression_type='RATE', expression='Ka*AS3*NH2CL - Av*(K1*(Smax-AS5s)*AS5 - K2*AS5s)', note='Arsenate production less adsorption')\n", + "NH2CL \t Reaction(species_name='NH2CL', expression_type='RATE', expression='-Kb*NH2CL', note='Monochloramine decay')\n", + "AS5s \t Reaction(species_name='AS5s', expression_type='EQUIL', expression='Ks*Smax*AS5/(1+Ks*AS5) - AS5s', note='Arsenate adsorption')\n", + "AStot \t Reaction(species_name='AStot', expression_type='FORMULA', expression='AS3 + AS5', note='Total arsenic')\n", + "AS3 \t Reaction(species_name='AS3', expression_type='RATE', expression='-Ka*AS3*NH2CL', note='Arsenite oxidation')\n", + "AS5 \t Reaction(species_name='AS5', expression_type='RATE', expression='Ka*AS3*NH2CL', note='Arsenate production')\n", + "NH2CL \t Reaction(species_name='NH2CL', expression_type='RATE', expression='-Kb*NH2CL', note='Monochloramine decay')\n", + "AStot \t Reaction(species_name='AStot', expression_type='FORMULA', expression='AS3 + AS5', note='Total arsenic')\n" + ] + } + ], + "source": [ + "arsenic = my_library.get_model('arsenic_chloramine')\n", + "for key,value in arsenic.reaction_system.variables(): print(key, '\\t', repr(value))\n", + "for key,value in arsenic.reaction_system.reactions(): print(key, '\\t', repr(value))" + ] } ], "metadata": { diff --git a/wntr/epanet/msx/io.py b/wntr/epanet/msx/io.py index 5ac252e09..47e35d5c6 100644 --- a/wntr/epanet/msx/io.py +++ b/wntr/epanet/msx/io.py @@ -847,7 +847,7 @@ def _write_report(self, fout): fout.write("\n") -def MsxBinFile(filename, wn: wntr.network.WaterNetworkModel, res = None): +def MsxBinFile(filename, wn, res = None): duration = int(wn.options.time.duration) if res is None: from wntr.sim.results import SimulationResults diff --git a/wntr/library/msx/__init__.py b/wntr/library/msx/__init__.py new file mode 100644 index 000000000..403cb8c23 --- /dev/null +++ b/wntr/library/msx/__init__.py @@ -0,0 +1 @@ +from ._msxlibrary import MsxLibrary diff --git a/wntr/msx/library.py b/wntr/library/msx/_msxlibrary.py similarity index 98% rename from wntr/msx/library.py rename to wntr/library/msx/_msxlibrary.py index 62ce4d1ea..117be0c82 100644 --- a/wntr/msx/library.py +++ b/wntr/library/msx/_msxlibrary.py @@ -5,7 +5,7 @@ .. rubric:: Environment Variable -.. envvar:: WNTR_RXN_LIBRARY_PATH +.. envvar:: WNTR_LIBRARY_PATH This environment variable, if set, will add additional folder(s) to the path to search for multi-species water quality model files, @@ -23,8 +23,8 @@ from pkg_resources import resource_filename -from .base import ExpressionType, ReactionType, SpeciesType -from .model import MsxModel +from wntr.msx.base import ExpressionType, ReactionType, SpeciesType +from wntr.msx.model import MsxModel try: import yaml @@ -45,7 +45,7 @@ logger = logging.getLogger(__name__) -class ReactionLibrary: +class MsxLibrary: """Library of multi-species water quality models This object can be accessed and treated like a dictionary, where keys are @@ -78,7 +78,7 @@ def __init__(self, extra_paths: List[str] = None, include_builtins=True, Load files built-in with WNTR, by default True include_envvar_paths : bool, optional Load files from the paths specified in - :envvar:`WNTR_RXN_LIBRARY_PATH`, by default True + :envvar:`WNTR_LIBRARY_PATH`, by default True load : bool or str, optional Load the files immediately on creation, by default True. If a string, then it will be passed as the `duplicates` argument @@ -99,12 +99,12 @@ def __init__(self, extra_paths: List[str] = None, include_builtins=True, self.__data = dict() if include_builtins: - default_path = os.path.abspath(resource_filename(__name__, "_library_data")) + default_path = os.path.abspath(resource_filename(__name__, '.')) if default_path not in self.__library_paths: self.__library_paths.append(default_path) if include_envvar_paths: - environ_path = os.environ.get("WNTR_RXN_LIBRARY_PATH", None) + environ_path = os.environ.get("WNTR_LIBRARY_PATH", None) if environ_path: lib_folders = environ_path.split(";") for folder in lib_folders: diff --git a/wntr/msx/_library_data/arsenic_chloramine.json b/wntr/library/msx/arsenic_chloramine.json similarity index 100% rename from wntr/msx/_library_data/arsenic_chloramine.json rename to wntr/library/msx/arsenic_chloramine.json diff --git a/wntr/msx/_library_data/batch_chloramine_decay.json b/wntr/library/msx/batch_chloramine_decay.json similarity index 100% rename from wntr/msx/_library_data/batch_chloramine_decay.json rename to wntr/library/msx/batch_chloramine_decay.json diff --git a/wntr/msx/_library_data/lead_ppm.json b/wntr/library/msx/lead_ppm.json similarity index 100% rename from wntr/msx/_library_data/lead_ppm.json rename to wntr/library/msx/lead_ppm.json diff --git a/wntr/msx/_library_data/nicotine.json b/wntr/library/msx/nicotine.json similarity index 100% rename from wntr/msx/_library_data/nicotine.json rename to wntr/library/msx/nicotine.json diff --git a/wntr/msx/_library_data/nicotine_ri.json b/wntr/library/msx/nicotine_ri.json similarity index 100% rename from wntr/msx/_library_data/nicotine_ri.json rename to wntr/library/msx/nicotine_ri.json diff --git a/wntr/msx/__init__.py b/wntr/msx/__init__.py index d563c9a97..3daaa7e4b 100644 --- a/wntr/msx/__init__.py +++ b/wntr/msx/__init__.py @@ -8,6 +8,5 @@ from .elements import Species, Constant, Parameter, Term, Reaction, HydraulicVariable, MathFunction from .model import MsxModel from .options import MsxSolverOptions -from .library import ReactionLibrary -from . import base, elements, library, model, options +from . import base, elements, model, options, io diff --git a/wntr/msx/_library_data/msx.schema.json b/wntr/msx/_library_data/msx.schema.json deleted file mode 100644 index 24feef0e2..000000000 --- a/wntr/msx/_library_data/msx.schema.json +++ /dev/null @@ -1,873 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "type": "object", - "properties": { - "wntr-version": { - "type": "string" - }, - "name": { - "type": "string" - }, - "title": { - "type": "string" - }, - "description": { - "type": [ - "null", - "string" - ] - }, - "references": { - "type": "array", - "items": { - "type": "string" - } - }, - "reaction_system": { - "type": "object", - "properties": { - "species": { - "type": "array", - "items": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "species_type": { - "type": "string" - }, - "units": { - "type": "string" - }, - "atol": { - "type": "null" - }, - "rtol": { - "type": "null" - }, - "note": { - "type": "string" - } - }, - "required": [ - "atol", - "name", - "note", - "rtol", - "species_type", - "units" - ] - } - }, - "constants": { - "type": "array", - "items": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "value": { - "type": "number" - }, - "units": { - "type": "string" - }, - "note": { - "type": "string" - } - }, - "required": [ - "name", - "note", - "units", - "value" - ] - } - }, - "parameters": { - "type": "array", - "items": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "global_value": { - "type": "number" - }, - "note": { - "type": "string" - } - }, - "required": [ - "global_value", - "name" - ] - } - }, - "terms": { - "type": "array", - "items": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "expression": { - "type": "string" - }, - "note": { - "type": "string" - } - }, - "required": [ - "expression", - "name" - ] - } - }, - "pipe_reactions": { - "type": "array", - "items": { - "type": "object", - "properties": { - "species_name": { - "type": "string" - }, - "expression_type": { - "type": "string" - }, - "expression": { - "type": "string" - }, - "note": { - "type": "string" - } - }, - "required": [ - "expression", - "expression_type", - "species_name" - ] - } - }, - "tank_reactions": { - "type": "array", - "items": { - "type": "object", - "properties": { - "species_name": { - "type": "string" - }, - "expression_type": { - "type": "string" - }, - "expression": { - "type": "string" - }, - "note": { - "type": "string" - } - }, - "required": [ - "expression", - "expression_type", - "species_name" - ] - } - } - }, - "required": [ - "constants", - "parameters", - "pipe_reactions", - "species", - "tank_reactions", - "terms" - ] - }, - "network_data": { - "type": "object", - "properties": { - "initial_quality": { - "type": "object", - "properties": { - "AS3": { - "type": "object", - "properties": { - "global_value": { - "type": "number" - }, - "node_values": { - "type": "object" - }, - "link_values": { - "type": "object" - } - }, - "required": [ - "global_value", - "link_values", - "node_values" - ] - }, - "AS5": { - "type": "object", - "properties": { - "global_value": { - "type": "number" - }, - "node_values": { - "type": "object" - }, - "link_values": { - "type": "object" - } - }, - "required": [ - "global_value", - "link_values", - "node_values" - ] - }, - "AStot": { - "type": "object", - "properties": { - "global_value": { - "type": "number" - }, - "node_values": { - "type": "object" - }, - "link_values": { - "type": "object" - } - }, - "required": [ - "global_value", - "link_values", - "node_values" - ] - }, - "AS5s": { - "type": "object", - "properties": { - "global_value": { - "type": "number" - }, - "node_values": { - "type": "object" - }, - "link_values": { - "type": "object" - } - }, - "required": [ - "global_value", - "link_values", - "node_values" - ] - }, - "NH2CL": { - "type": "object", - "properties": { - "global_value": { - "type": "number" - }, - "node_values": { - "type": "object" - }, - "link_values": { - "type": "object" - } - }, - "required": [ - "global_value", - "link_values", - "node_values" - ] - }, - "HOCL": { - "type": "object", - "properties": { - "global_value": { - "type": "number" - }, - "node_values": { - "type": "object" - }, - "link_values": { - "type": "object" - } - }, - "required": [ - "global_value", - "link_values", - "node_values" - ] - }, - "NH3": { - "type": "object", - "properties": { - "global_value": { - "type": "number" - }, - "node_values": { - "type": "object" - }, - "link_values": { - "type": "object" - } - }, - "required": [ - "global_value", - "link_values", - "node_values" - ] - }, - "NHCL2": { - "type": "object", - "properties": { - "global_value": { - "type": "number" - }, - "node_values": { - "type": "object" - }, - "link_values": { - "type": "object" - } - }, - "required": [ - "global_value", - "link_values", - "node_values" - ] - }, - "I": { - "type": "object", - "properties": { - "global_value": { - "type": "number" - }, - "node_values": { - "type": "object" - }, - "link_values": { - "type": "object" - } - }, - "required": [ - "global_value", - "link_values", - "node_values" - ] - }, - "OCL": { - "type": "object", - "properties": { - "global_value": { - "type": "number" - }, - "node_values": { - "type": "object" - }, - "link_values": { - "type": "object" - } - }, - "required": [ - "global_value", - "link_values", - "node_values" - ] - }, - "NH4": { - "type": "object", - "properties": { - "global_value": { - "type": "number" - }, - "node_values": { - "type": "object" - }, - "link_values": { - "type": "object" - } - }, - "required": [ - "global_value", - "link_values", - "node_values" - ] - }, - "ALK": { - "type": "object", - "properties": { - "global_value": { - "type": "number" - }, - "node_values": { - "type": "object" - }, - "link_values": { - "type": "object" - } - }, - "required": [ - "global_value", - "link_values", - "node_values" - ] - }, - "H": { - "type": "object", - "properties": { - "global_value": { - "type": "number" - }, - "node_values": { - "type": "object" - }, - "link_values": { - "type": "object" - } - }, - "required": [ - "global_value", - "link_values", - "node_values" - ] - }, - "OH": { - "type": "object", - "properties": { - "global_value": { - "type": "number" - }, - "node_values": { - "type": "object" - }, - "link_values": { - "type": "object" - } - }, - "required": [ - "global_value", - "link_values", - "node_values" - ] - }, - "CO3": { - "type": "object", - "properties": { - "global_value": { - "type": "number" - }, - "node_values": { - "type": "object" - }, - "link_values": { - "type": "object" - } - }, - "required": [ - "global_value", - "link_values", - "node_values" - ] - }, - "HCO3": { - "type": "object", - "properties": { - "global_value": { - "type": "number" - }, - "node_values": { - "type": "object" - }, - "link_values": { - "type": "object" - } - }, - "required": [ - "global_value", - "link_values", - "node_values" - ] - }, - "H2CO3": { - "type": "object", - "properties": { - "global_value": { - "type": "number" - }, - "node_values": { - "type": "object" - }, - "link_values": { - "type": "object" - } - }, - "required": [ - "global_value", - "link_values", - "node_values" - ] - }, - "chloramine": { - "type": "object", - "properties": { - "global_value": { - "type": "number" - }, - "node_values": { - "type": "object" - }, - "link_values": { - "type": "object" - } - }, - "required": [ - "global_value", - "link_values", - "node_values" - ] - }, - "PB2": { - "type": "object", - "properties": { - "global_value": { - "type": "number" - }, - "node_values": { - "type": "object" - }, - "link_values": { - "type": "object" - } - }, - "required": [ - "global_value", - "link_values", - "node_values" - ] - }, - "Nx": { - "type": "object", - "properties": { - "global_value": { - "type": "number" - }, - "node_values": { - "type": "object" - }, - "link_values": { - "type": "object" - } - }, - "required": [ - "global_value", - "link_values", - "node_values" - ] - }, - "NX2": { - "type": "object", - "properties": { - "global_value": { - "type": "number" - }, - "node_values": { - "type": "object" - }, - "link_values": { - "type": "object" - } - }, - "required": [ - "global_value", - "link_values", - "node_values" - ] - } - } - }, - "parameter_values": { - "type": "object", - "properties": { - "k1": { - "type": "object", - "properties": { - "pipe_values": { - "type": "object" - }, - "tank_values": { - "type": "object" - } - }, - "required": [ - "pipe_values", - "tank_values" - ] - }, - "k2": { - "type": "object", - "properties": { - "pipe_values": { - "type": "object" - }, - "tank_values": { - "type": "object" - } - }, - "required": [ - "pipe_values", - "tank_values" - ] - }, - "k3": { - "type": "object", - "properties": { - "pipe_values": { - "type": "object" - }, - "tank_values": { - "type": "object" - } - }, - "required": [ - "pipe_values", - "tank_values" - ] - }, - "k4": { - "type": "object", - "properties": { - "pipe_values": { - "type": "object" - }, - "tank_values": { - "type": "object" - } - }, - "required": [ - "pipe_values", - "tank_values" - ] - }, - "k6": { - "type": "object", - "properties": { - "pipe_values": { - "type": "object" - }, - "tank_values": { - "type": "object" - } - }, - "required": [ - "pipe_values", - "tank_values" - ] - }, - "k7": { - "type": "object", - "properties": { - "pipe_values": { - "type": "object" - }, - "tank_values": { - "type": "object" - } - }, - "required": [ - "pipe_values", - "tank_values" - ] - }, - "k8": { - "type": "object", - "properties": { - "pipe_values": { - "type": "object" - }, - "tank_values": { - "type": "object" - } - }, - "required": [ - "pipe_values", - "tank_values" - ] - }, - "k9": { - "type": "object", - "properties": { - "pipe_values": { - "type": "object" - }, - "tank_values": { - "type": "object" - } - }, - "required": [ - "pipe_values", - "tank_values" - ] - }, - "k10": { - "type": "object", - "properties": { - "pipe_values": { - "type": "object" - }, - "tank_values": { - "type": "object" - } - }, - "required": [ - "pipe_values", - "tank_values" - ] - }, - "F": { - "type": "object", - "properties": { - "pipe_values": { - "type": "object" - }, - "tank_values": { - "type": "object" - } - }, - "required": [ - "pipe_values", - "tank_values" - ] - } - } - }, - "sources": { - "type": "object" - }, - "patterns": { - "type": "object" - } - }, - "required": [ - "initial_quality", - "parameter_values", - "patterns", - "sources" - ] - }, - "options": { - "type": "object", - "properties": { - "timestep": { - "type": "integer" - }, - "area_units": { - "type": "string" - }, - "rate_units": { - "type": "string" - }, - "solver": { - "type": "string" - }, - "coupling": { - "type": "string" - }, - "rtol": { - "type": "number" - }, - "atol": { - "type": "number" - }, - "compiler": { - "type": "string" - }, - "segments": { - "type": "integer" - }, - "peclet": { - "type": "integer" - }, - "report": { - "type": "object", - "properties": { - "pagesize": { - "type": "null" - }, - "report_filename": { - "type": "null" - }, - "species": { - "type": "object", - "properties": { - "PB2": { - "type": "string" - } - } - }, - "species_precision": { - "type": "object", - "properties": { - "PB2": { - "type": "integer" - } - } - }, - "nodes": { - "type": [ - "null", - "string" - ] - }, - "links": { - "type": [ - "null", - "string" - ] - } - }, - "required": [ - "links", - "nodes", - "pagesize", - "report_filename", - "species", - "species_precision" - ] - } - }, - "required": [ - "area_units", - "atol", - "compiler", - "coupling", - "peclet", - "rate_units", - "report", - "rtol", - "segments", - "solver", - "timestep" - ] - } - }, - "required": [ - "description", - "name", - "network_data", - "options", - "reaction_system", - "references", - "title", - "wntr-version" - ] -} diff --git a/wntr/msx/base.py b/wntr/msx/base.py index bee6b727d..74d30a6e8 100644 --- a/wntr/msx/base.py +++ b/wntr/msx/base.py @@ -209,6 +209,9 @@ class VariableType(Enum): C = CONST = CONSTANT R = RES = RESERVED + def __repr__(self): + return repr(self.name) + @add_get(abbrev=True) class SpeciesType(Enum): @@ -238,6 +241,9 @@ class SpeciesType(Enum): B = BULK W = WALL + def __repr__(self): + return repr(self.name) + @add_get(abbrev=True) class ReactionType(Enum): @@ -266,6 +272,9 @@ class ReactionType(Enum): P = PIPE T = TANK + def __repr__(self): + return repr(self.name) + @add_get(abbrev=True) class ExpressionType(Enum): @@ -303,6 +312,9 @@ class ExpressionType(Enum): R = RATE F = FORMULA + def __repr__(self): + return repr(self.name) + class ReactionBase(ABC): """Water quality reaction class @@ -374,7 +386,8 @@ def species_name(self) -> str: """Name of the species that has a reaction being defined.""" return self._species_name - @abstractproperty + @property + @abstractmethod def reaction_type(self) -> Enum: """Reaction type (reaction location).""" raise NotImplementedError @@ -450,15 +463,15 @@ def __init__(self, name: str, *, note: NoteType = None) -> None: """Optional note regarding the variable (see :class:`~wntr.epanet.util.NoteType`) """ - @abstractproperty + @property + @abstractmethod def var_type(self) -> Enum: """Type of reaction variable""" raise NotImplementedError - @abstractmethod def to_dict(self) -> Dict[str, Any]: """Represent the object as a dictionary""" - raise NotImplementedError + return dict(name=self.name) def __str__(self) -> str: """Return the name of the variable""" @@ -573,7 +586,8 @@ class VariableValuesBase(ABC): and methods documented here must be defined by a subclass. """ - @abstractproperty + @property + @abstractmethod def var_type(self) -> Enum: """Type of variable this object holds data for.""" raise NotImplementedError @@ -650,7 +664,8 @@ def __init__(self, filename=None): self._wn = None """Protected water network object""" - @abstractproperty + @property + @abstractmethod def options(self): """Model options structure @@ -659,7 +674,8 @@ def options(self): """ raise NotImplementedError - @abstractproperty + @property + @abstractmethod def reaction_system(self) -> ReactionSystemBase: """Reaction variables defined for this model @@ -667,7 +683,8 @@ def reaction_system(self) -> ReactionSystemBase: """ raise NotImplementedError - @abstractproperty + @property + @abstractmethod def network_data(self) -> NetworkDataBase: """Network-specific values added to this model @@ -680,7 +697,8 @@ def to_dict(self) -> dict: """Represent the object as a dictionary""" raise NotImplementedError - @abstractclassmethod + @classmethod + @abstractmethod def from_dict(self, data: dict) -> "QualityModelBase": """Create a new model from a dictionary diff --git a/wntr/msx/elements.py b/wntr/msx/elements.py index 3499a59ef..0c923df9d 100644 --- a/wntr/msx/elements.py +++ b/wntr/msx/elements.py @@ -464,9 +464,9 @@ def var_type(self) -> VariableType: """Type of variable, :attr:`~wntr.msx.base.VariableType.RESERVED`.""" return VariableType.RESERVED - def to_dict(self) -> Dict[str, Any]: - """Dictionary representation of the object""" - return "{}({})".format(self.__class__.__name__, ", ".join(["name={}".format(repr(self.name)), "note={}".format(repr(self.note))])) + # def to_dict(self) -> Dict[str, Any]: + # """Dictionary representation of the object""" + # return "{}({})".format(self.__class__.__name__, ", ".join(["name={}".format(repr(self.name)), "note={}".format(repr(self.note))])) class HydraulicVariable(ReservedName): diff --git a/wntr/msx/io.py b/wntr/msx/io.py new file mode 100644 index 000000000..900f21e92 --- /dev/null +++ b/wntr/msx/io.py @@ -0,0 +1,123 @@ +""" +The wntr.msx.io module includes functions that convert the MSX reaction +model to other data formats, create an MSX model from a file, and write +the MSX model to a file. +""" +import logging +import json + + +logger = logging.getLogger(__name__) + +def to_dict(msx) -> dict: + """ + Convert a MsxModel into a dictionary + + Parameters + ---------- + msx : MsxModel + The MSX reaction model. + + Returns + ------- + dict + Dictionary representation of the MsxModel + """ + return msx.to_dict() + +def from_dict(d: dict): + """ + Create or append a MsxModel from a dictionary + + Parameters + ---------- + d : dict + Dictionary representation of the water network model. + + Returns + ------- + MsxModel + + """ + from wntr.msx.model import MsxModel + return MsxModel.from_dict(d) + +def write_json(msx, path_or_buf, as_library=False, **kw_json): + """ + Write the MSX model to a JSON file + + Parameters + ---------- + msx : MsxModel + The model to output. + path_or_buf : str or IO stream + Name of the file or file pointer. + as_library : bool, optional + Strip out network-specific elements if True, by default False. + kw_json : keyword arguments + Arguments to pass directly to :meth:`json.dump`. + """ + d = to_dict(msx) + if as_library: + d.get('network_data', {}).get('initial_quality',{}).clear() + d.get('network_data', {}).get('parameter_values',{}).clear() + d.get('network_data', {}).get('sources',{}).clear() + d.get('network_data', {}).get('patterns',{}).clear() + d.get('options', {}).get('report',{}).setdefault('nodes', None) + d.get('options', {}).get('report',{}).setdefault('links', None) + if isinstance(path_or_buf, str): + with open(path_or_buf, "w") as fout: + json.dump(d, fout, **kw_json) + else: + json.dump(d, path_or_buf, **kw_json) + +def read_json(path_or_buf, **kw_json): + """ + Create or append a WaterNetworkModel from a JSON file + + Parameters + ---------- + f : str + Name of the file or file pointer. + kw_json : keyword arguments + Keyword arguments to pass to `json.load`. + + Returns + ------- + MsxModel + + """ + if isinstance(path_or_buf, str): + with open(path_or_buf, "r") as fin: + d = json.load(fin, **kw_json) + else: + d = json.load(path_or_buf, **kw_json) + return from_dict(d) + +def write_msxfile(msx, filename): + """ + Write an EPANET-MSX input file (.msx) + + Parameters + ---------- + msx : MsxModel + The model to write + filename : str + The filename to use for output + """ + from wntr.epanet.msx.io import MsxFile + MsxFile.write(filename, msx) + +def read_msxfile(filename, append=None): + """ + Read in an EPANET-MSX input file (.msx) + + Parameters + ---------- + filename : str + The filename to read in. + append : MsxModel + An existing model to add data into, by default None. + """ + from wntr.epanet.msx.io import MsxFile + return MsxFile.read(filename, append) diff --git a/wntr/msx/model.py b/wntr/msx/model.py index be46e2201..bf3b9b3ed 100644 --- a/wntr/msx/model.py +++ b/wntr/msx/model.py @@ -133,13 +133,14 @@ def variables(self) -> Generator[tuple, None, None]: # FIXME: rename without "all_" for this """Generator looping through all variables""" for k, v in self._vars.items(): - yield k, v.var_type.name.lower(), v + if v.var_type.name.lower() not in ['reserved']: + yield k, v def reactions(self) -> Generator[tuple, None, None]: """Generator looping through all reactions""" for k2, v in self._rxns.items(): for k1, v1 in v.items(): - yield k1, k2, v1 + yield k1, v1 def to_dict(self) -> dict: """Dictionary representation of the MsxModel.""" @@ -724,14 +725,14 @@ def remove_reaction(self, species_name: str, reaction_type: ReactionType) -> Non """ reaction_type = ReactionType.get(reaction_type, allow_none=False) species_name = str(species_name) - del self.reaction_system.reactions[reaction_type.name.lower()][species_name] + del self.reaction_system._rxns[reaction_type.name.lower()][species_name] def to_dict(self) -> dict: """Dictionary representation of the MsxModel""" from wntr import __version__ return { - "wntr-version": "{}".format(__version__), + "version": "wntr-{}".format(__version__), "name": self.name, "title": self.title, "description": self.description if self.description is None or "\n" not in self.description else self.description.splitlines(), @@ -752,8 +753,8 @@ def from_dict(cls, data) -> "MsxModel": """ from wntr import __version__ - ver = data.get("wntr-version", None) - if ver != __version__: + ver = data.get("version", None) + if ver != 'wntr-{}'.format(__version__): logger.warn("Importing from a file created by a different version of wntr, compatibility not guaranteed") # warnings.warn("Importing from a file created by a different version of wntr, compatibility not guaranteed") new = cls() From 366b7d7f743bbda807f14bee938206216c01309c Mon Sep 17 00:00:00 2001 From: David Hart Date: Tue, 2 Jul 2024 16:48:05 -0600 Subject: [PATCH 71/75] Reverting --- wntr/network/base.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/wntr/network/base.py b/wntr/network/base.py index 6cdc50e20..7bf9c6a4b 100644 --- a/wntr/network/base.py +++ b/wntr/network/base.py @@ -589,8 +589,8 @@ class Registry(MutableMapping): """ def __init__(self, wn): - # if not isinstance(wn, AbstractModel): - # raise ValueError('Registry must be initialized with a model') + if not isinstance(wn, AbstractModel): + raise ValueError('Registry must be initialized with a model') # self._m = model self._data = OrderedDict() self._usage = OrderedDict() From 2469acb5b9f1b546b1f3841eb98d0240f79fd4fb Mon Sep 17 00:00:00 2001 From: David Hart Date: Mon, 15 Jul 2024 09:28:59 -0600 Subject: [PATCH 72/75] Revert documentation config changes --- documentation/_templates/autosummary/base.rst | 5 ++--- documentation/_templates/autosummary/class.rst | 8 +++----- documentation/_templates/autosummary/exception.rst | 8 +++----- 3 files changed, 8 insertions(+), 13 deletions(-) diff --git a/documentation/_templates/autosummary/base.rst b/documentation/_templates/autosummary/base.rst index 52bf10b46..3ba1e3144 100644 --- a/documentation/_templates/autosummary/base.rst +++ b/documentation/_templates/autosummary/base.rst @@ -4,8 +4,7 @@ {{ objname | escape | underline}} -.. - rubric:: *module* :mod:`{{ module }}` +.. rubric:: *module* :mod:`{{ module }}` .. currentmodule:: {{ module }} @@ -13,4 +12,4 @@ property {% endif %} -.. auto{{ objtype }}:: {{ fullname | replace(module + ".", module + "::") }} +.. auto{{ objtype }}:: {{ fullname | replace(module + ".", module + "::") }} \ No newline at end of file diff --git a/documentation/_templates/autosummary/class.rst b/documentation/_templates/autosummary/class.rst index 757961130..615c3519b 100644 --- a/documentation/_templates/autosummary/class.rst +++ b/documentation/_templates/autosummary/class.rst @@ -1,12 +1,10 @@ {{ objname | escape | underline}} -.. - rubric:: *module* :mod:`{{ module }}` +.. rubric:: *module* :mod:`{{ module }}` .. currentmodule:: {{ module }} -.. autoclass:: {{ fullname }} - :exclude-members: __new__ +.. autoclass:: {{ objname }} {% block methods %} {% if methods %} @@ -36,4 +34,4 @@ {% if methods or attributes %} ~~~~~~~~~~~~~~~~~~~~~~~~~~~ - {% endif %} + {% endif %} \ No newline at end of file diff --git a/documentation/_templates/autosummary/exception.rst b/documentation/_templates/autosummary/exception.rst index e3504e253..e0d9dc9b7 100644 --- a/documentation/_templates/autosummary/exception.rst +++ b/documentation/_templates/autosummary/exception.rst @@ -1,13 +1,11 @@ {{ objname | escape | underline}} -.. - rubric:: *module* :mod:`{{ module }}` +.. rubric:: *module* :mod:`{{ module }}` .. currentmodule:: {{ module }} -.. autoexception:: {{ fullname }} +.. autoexception:: {{ objname }} :no-inherited-members: - :exclude-members: __new__ {% block methods %} {% if methods %} @@ -33,4 +31,4 @@ {%- endif -%} {%- endfor %} {% endif %} -{% endblock %} +{% endblock %} \ No newline at end of file From 891d33c5dfcfa354bdf342727469da1b577b7b4a Mon Sep 17 00:00:00 2001 From: David Hart Date: Mon, 15 Jul 2024 09:34:18 -0600 Subject: [PATCH 73/75] Revert conf.py --- documentation/conf.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/documentation/conf.py b/documentation/conf.py index 97bb83072..b921adb78 100644 --- a/documentation/conf.py +++ b/documentation/conf.py @@ -45,7 +45,7 @@ ] add_function_parentheses = True -add_module_names = True +add_module_names = False python_display_short_literal_types = True toc_object_entries = True @@ -53,7 +53,7 @@ napoleon_google_docstring = True napoleon_numpy_docstring = True -napoleon_include_init_with_doc = False +napoleon_include_init_with_doc = True napoleon_include_private_with_doc = False napoleon_include_special_with_doc = False napoleon_use_admonition_for_examples = False @@ -69,7 +69,7 @@ # viewcode_import = False autodoc_default_options = { - 'undoc-members': False, + 'undoc-members': True, 'private-members': False, 'special-members': False, 'inherited-members': True, @@ -77,13 +77,13 @@ 'member-order': 'groupwise', } -autodoc_class_signature = 'mixed' +autodoc_class_signature = 'separated' autodoc_typehints = 'description' autodoc_typehints_format = 'short' autodoc_typehints_description_target = 'documented' -autodoc_type_aliases = {'DataFrame': 'pandas.DataFrame',} +autodoc_type_aliases = {'DataFrame': 'pandas DataFrame',} -autoclass_content = 'both' +autoclass_content = 'class' numfig=True numfig_format = {'figure': 'Figure %s', 'table': 'Table %s', 'code-block': 'Listing %s'} From fe5ca2974b541bc75126ce747be928388927d593 Mon Sep 17 00:00:00 2001 From: David Hart Date: Mon, 15 Jul 2024 09:35:39 -0600 Subject: [PATCH 74/75] Finish revert erroneous commits --- documentation/_templates/autosummary/base.rst | 2 +- documentation/_templates/autosummary/class.rst | 2 +- documentation/_templates/autosummary/exception.rst | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/documentation/_templates/autosummary/base.rst b/documentation/_templates/autosummary/base.rst index 3ba1e3144..667f19687 100644 --- a/documentation/_templates/autosummary/base.rst +++ b/documentation/_templates/autosummary/base.rst @@ -12,4 +12,4 @@ property {% endif %} -.. auto{{ objtype }}:: {{ fullname | replace(module + ".", module + "::") }} \ No newline at end of file +.. auto{{ objtype }}:: {{ fullname | replace(module + ".", module + "::") }} diff --git a/documentation/_templates/autosummary/class.rst b/documentation/_templates/autosummary/class.rst index 615c3519b..9e9adf167 100644 --- a/documentation/_templates/autosummary/class.rst +++ b/documentation/_templates/autosummary/class.rst @@ -34,4 +34,4 @@ {% if methods or attributes %} ~~~~~~~~~~~~~~~~~~~~~~~~~~~ - {% endif %} \ No newline at end of file + {% endif %} diff --git a/documentation/_templates/autosummary/exception.rst b/documentation/_templates/autosummary/exception.rst index e0d9dc9b7..8d05ab977 100644 --- a/documentation/_templates/autosummary/exception.rst +++ b/documentation/_templates/autosummary/exception.rst @@ -31,4 +31,4 @@ {%- endif -%} {%- endfor %} {% endif %} -{% endblock %} \ No newline at end of file +{% endblock %} From 2ec9b81ece2dcc3550d78cf7d35ae4484016bf70 Mon Sep 17 00:00:00 2001 From: David Hart Date: Sat, 20 Jul 2024 12:45:09 -0600 Subject: [PATCH 75/75] CrowdStrike mess backup --- examples/demos/multisource-cl-decay.ipynb | 90 +++++++++++------------ 1 file changed, 45 insertions(+), 45 deletions(-) diff --git a/examples/demos/multisource-cl-decay.ipynb b/examples/demos/multisource-cl-decay.ipynb index da1115d55..b4fbb930b 100644 --- a/examples/demos/multisource-cl-decay.ipynb +++ b/examples/demos/multisource-cl-decay.ipynb @@ -16,7 +16,7 @@ }, { "cell_type": "code", - "execution_count": 1, + "execution_count": 2, "metadata": {}, "outputs": [], "source": [ @@ -32,7 +32,7 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": 3, "metadata": {}, "outputs": [], "source": [ @@ -50,7 +50,7 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 4, "metadata": {}, "outputs": [], "source": [ @@ -79,7 +79,7 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 5, "metadata": {}, "outputs": [ { @@ -98,7 +98,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 6, "metadata": {}, "outputs": [ { @@ -117,7 +117,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 7, "metadata": {}, "outputs": [ { @@ -144,7 +144,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 8, "metadata": {}, "outputs": [ { @@ -178,7 +178,7 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 9, "metadata": {}, "outputs": [ { @@ -206,7 +206,7 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 10, "metadata": {}, "outputs": [ { @@ -280,7 +280,7 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 11, "metadata": {}, "outputs": [], "source": [ @@ -296,7 +296,7 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 12, "metadata": {}, "outputs": [ { @@ -305,7 +305,7 @@ "Text(0, 0.5, 'Concentraion [mg/L]')" ] }, - "execution_count": 11, + "execution_count": 12, "metadata": {}, "output_type": "execute_result" }, @@ -341,7 +341,7 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 13, "metadata": {}, "outputs": [], "source": [ @@ -360,14 +360,14 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 14, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "; WNTR-reactions MSX file generated 2024-05-20 07:00:10.969400\n", + "; WNTR-reactions MSX file generated 2024-05-20 16:04:15.375087\n", "\n", "[TITLE]\n", " Multisource Chlorine Decay\n", @@ -426,7 +426,7 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": 15, "metadata": {}, "outputs": [ { @@ -478,7 +478,7 @@ }, { "cell_type": "code", - "execution_count": 15, + "execution_count": 16, "metadata": {}, "outputs": [ { @@ -499,7 +499,7 @@ " 'temp']" ] }, - "execution_count": 15, + "execution_count": 16, "metadata": {}, "output_type": "execute_result" } @@ -521,7 +521,7 @@ }, { "cell_type": "code", - "execution_count": 16, + "execution_count": 17, "metadata": {}, "outputs": [ { @@ -531,7 +531,7 @@ " 'CL2': InitialQuality(global_value=0.0, node_values=<2 entries>, link_values=<0 entries>)}" ] }, - "execution_count": 16, + "execution_count": 17, "metadata": {}, "output_type": "execute_result" } @@ -542,7 +542,7 @@ }, { "cell_type": "code", - "execution_count": 17, + "execution_count": 18, "metadata": {}, "outputs": [ { @@ -552,7 +552,7 @@ " 'CL2': InitialQuality(global_value=0.0, node_values=<0 entries>, link_values=<0 entries>)}" ] }, - "execution_count": 17, + "execution_count": 18, "metadata": {}, "output_type": "execute_result" } @@ -570,40 +570,40 @@ }, { "cell_type": "code", - "execution_count": 18, + "execution_count": 19, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "AS3 \t Species(name='AS3', species_type='BULK', units='UG', atol=None, rtol=None, note='Dissolved arsenite')\n", - "AS5 \t Species(name='AS5', species_type='BULK', units='UG', atol=None, rtol=None, note='Dissolved arsenate')\n", - "AStot \t Species(name='AStot', species_type='BULK', units='UG', atol=None, rtol=None, note='Total dissolved arsenic')\n", - "AS5s \t Species(name='AS5s', species_type='WALL', units='UG', atol=None, rtol=None, note='Adsorbed arsenate')\n", - "NH2CL \t Species(name='NH2CL', species_type='BULK', units='MG', atol=None, rtol=None, note='Monochloramine')\n", - "Ka \t Constant(name='Ka', value=10.0, units='1 / (MG * HR)', note='Arsenite oxidation rate coefficient')\n", - "Kb \t Constant(name='Kb', value=0.1, units='1 / HR', note='Monochloramine decay rate coefficient')\n", - "K1 \t Constant(name='K1', value=5.0, units='M^3 / (UG * HR)', note='Arsenate adsorption coefficient')\n", - "K2 \t Constant(name='K2', value=1.0, units='1 / HR', note='Arsenate desorption coefficient')\n", - "Smax \t Constant(name='Smax', value=50.0, units='UG / M^2', note='Arsenate adsorption limit')\n", - "Ks \t Term(name='Ks', expression='K1/K2', note='Equil. adsorption coeff.')\n", - "AS3 \t Reaction(species_name='AS3', expression_type='RATE', expression='-Ka*AS3*NH2CL', note='Arsenite oxidation')\n", - "AS5 \t Reaction(species_name='AS5', expression_type='RATE', expression='Ka*AS3*NH2CL - Av*(K1*(Smax-AS5s)*AS5 - K2*AS5s)', note='Arsenate production less adsorption')\n", - "NH2CL \t Reaction(species_name='NH2CL', expression_type='RATE', expression='-Kb*NH2CL', note='Monochloramine decay')\n", - "AS5s \t Reaction(species_name='AS5s', expression_type='EQUIL', expression='Ks*Smax*AS5/(1+Ks*AS5) - AS5s', note='Arsenate adsorption')\n", - "AStot \t Reaction(species_name='AStot', expression_type='FORMULA', expression='AS3 + AS5', note='Total arsenic')\n", - "AS3 \t Reaction(species_name='AS3', expression_type='RATE', expression='-Ka*AS3*NH2CL', note='Arsenite oxidation')\n", - "AS5 \t Reaction(species_name='AS5', expression_type='RATE', expression='Ka*AS3*NH2CL', note='Arsenate production')\n", - "NH2CL \t Reaction(species_name='NH2CL', expression_type='RATE', expression='-Kb*NH2CL', note='Monochloramine decay')\n", - "AStot \t Reaction(species_name='AStot', expression_type='FORMULA', expression='AS3 + AS5', note='Total arsenic')\n" + "Species(name='AS3', species_type='BULK', units='UG', atol=None, rtol=None, note='Dissolved arsenite')\n", + "Species(name='AS5', species_type='BULK', units='UG', atol=None, rtol=None, note='Dissolved arsenate')\n", + "Species(name='AStot', species_type='BULK', units='UG', atol=None, rtol=None, note='Total dissolved arsenic')\n", + "Species(name='AS5s', species_type='WALL', units='UG', atol=None, rtol=None, note='Adsorbed arsenate')\n", + "Species(name='NH2CL', species_type='BULK', units='MG', atol=None, rtol=None, note='Monochloramine')\n", + "Constant(name='Ka', value=10.0, units='1 / (MG * HR)', note='Arsenite oxidation rate coefficient')\n", + "Constant(name='Kb', value=0.1, units='1 / HR', note='Monochloramine decay rate coefficient')\n", + "Constant(name='K1', value=5.0, units='M^3 / (UG * HR)', note='Arsenate adsorption coefficient')\n", + "Constant(name='K2', value=1.0, units='1 / HR', note='Arsenate desorption coefficient')\n", + "Constant(name='Smax', value=50.0, units='UG / M^2', note='Arsenate adsorption limit')\n", + "Term(name='Ks', expression='K1/K2', note='Equil. adsorption coeff.')\n", + "Reaction(species_name='AS3', expression_type='RATE', expression='-Ka*AS3*NH2CL', note='Arsenite oxidation')\n", + "Reaction(species_name='AS5', expression_type='RATE', expression='Ka*AS3*NH2CL - Av*(K1*(Smax-AS5s)*AS5 - K2*AS5s)', note='Arsenate production less adsorption')\n", + "Reaction(species_name='NH2CL', expression_type='RATE', expression='-Kb*NH2CL', note='Monochloramine decay')\n", + "Reaction(species_name='AS5s', expression_type='EQUIL', expression='Ks*Smax*AS5/(1+Ks*AS5) - AS5s', note='Arsenate adsorption')\n", + "Reaction(species_name='AStot', expression_type='FORMULA', expression='AS3 + AS5', note='Total arsenic')\n", + "Reaction(species_name='AS3', expression_type='RATE', expression='-Ka*AS3*NH2CL', note='Arsenite oxidation')\n", + "Reaction(species_name='AS5', expression_type='RATE', expression='Ka*AS3*NH2CL', note='Arsenate production')\n", + "Reaction(species_name='NH2CL', expression_type='RATE', expression='-Kb*NH2CL', note='Monochloramine decay')\n", + "Reaction(species_name='AStot', expression_type='FORMULA', expression='AS3 + AS5', note='Total arsenic')\n" ] } ], "source": [ "arsenic = my_library.get_model('arsenic_chloramine')\n", - "for key,value in arsenic.reaction_system.variables(): print(key, '\\t', repr(value))\n", - "for key,value in arsenic.reaction_system.reactions(): print(key, '\\t', repr(value))" + "for key,value in arsenic.reaction_system.variables(): print(repr(value))\n", + "for key,value in arsenic.reaction_system.reactions(): print(repr(value))" ] } ],