:py:mod:`idaes_flowsheet_processor.api` ======================================= .. py:module:: idaes_flowsheet_processor.api .. autoapi-nested-parse:: Simple flowsheet interface API Module Contents --------------- Classes ~~~~~~~ .. autoapisummary:: idaes_flowsheet_processor.api.ModelExport idaes_flowsheet_processor.api.KPI idaes_flowsheet_processor.api.ModelOption idaes_flowsheet_processor.api.FlowsheetExport idaes_flowsheet_processor.api.Actions idaes_flowsheet_processor.api.FlowsheetCategory idaes_flowsheet_processor.api.FlowsheetReport idaes_flowsheet_processor.api.FlowsheetInterface idaes_flowsheet_processor.api.FlowsheetKPIReport idaes_flowsheet_processor.api.Layout Functions ~~~~~~~~~ .. autoapisummary:: idaes_flowsheet_processor.api.ensure_supported Attributes ~~~~~~~~~~ .. autoapisummary:: idaes_flowsheet_processor.api.FSI idaes_flowsheet_processor.api.WAFFLE idaes_flowsheet_processor.api.DONUT .. py:data:: FSI .. py:exception:: UnsupportedObjType(obj: Any, supported=None) Inappropriate argument type. .. py:function:: ensure_supported(obj: object) -> None Raise UnsupportedObjType if object type is not supported as an input/output .. py:class:: ModelExport(/, **data: Any) A variable, expression, or parameter. .. py:attribute:: obj :type: Optional[object] .. py:attribute:: name :type: str :value: '' .. py:attribute:: value :type: float :value: 0.0 .. py:attribute:: ui_units :type: object .. py:attribute:: display_units :type: str :value: '' .. py:attribute:: rounding :type: float :value: 0 .. py:attribute:: description :type: str :value: '' .. py:attribute:: is_input :type: bool :value: True .. py:attribute:: is_output :type: bool :value: True .. py:attribute:: is_readonly :type: Union[None, bool] .. py:attribute:: input_category :type: Optional[str] .. py:attribute:: output_category :type: Optional[str] .. py:attribute:: chart_type :type: Optional[str] .. py:attribute:: chart_group :type: Optional[str] .. py:attribute:: obj_key :type: Union[None, str] .. py:attribute:: fixed :type: bool :value: True .. py:attribute:: lb :type: Union[None, float] :value: 0.0 .. py:attribute:: ub :type: Union[None, float] :value: 0.0 .. py:attribute:: num_samples :type: int :value: 2 .. py:attribute:: has_bounds :type: bool :value: True .. py:attribute:: is_sweep :type: bool :value: False .. py:attribute:: model_config .. py:method:: validate_obj(v: object) -> object :classmethod: .. py:method:: validate_value(v: float, info: pydantic.ValidationInfo) -> float :classmethod: .. py:method:: validate_units(v: str, info: pydantic.ValidationInfo) -> str :classmethod: .. py:method:: validate_name(v: str, info: pydantic.ValidationInfo) -> str :classmethod: .. py:method:: set_readonly_default(v: Optional[bool], info: pydantic.ValidationInfo) -> bool :classmethod: .. py:method:: set_obj_key_default(v: Optional[str], info: pydantic.ValidationInfo) -> str :classmethod: .. py:class:: KPI(/, **data: Any) Key Performance Indicator .. py:attribute:: is_table :type: bool .. py:attribute:: has_total :type: bool .. py:attribute:: name :type: str .. py:attribute:: title :type: str .. py:attribute:: units :type: List[str] :value: [] .. py:attribute:: values :type: List[float] :value: [] .. py:attribute:: labels :type: List[str] :value: [] .. py:attribute:: xlab :type: str :value: '' .. py:attribute:: ylab :type: str :value: '' .. py:attribute:: total :type: float :value: 0.0 .. py:attribute:: total_label :type: str :value: '' .. py:class:: ModelOption(/, **data: Any) An option for building/running the model. .. py:attribute:: name :type: str .. py:attribute:: category :type: str :value: 'Build Options' .. py:attribute:: display_name :type: Union[None, str] .. py:attribute:: description :type: Union[None, str] .. py:attribute:: display_values :type: List[Any] :value: [] .. py:attribute:: values_allowed :type: Union[str, List[Any]] .. py:attribute:: min_val :type: Union[None, int, float] .. py:attribute:: max_val :type: Union[None, int, float] .. py:attribute:: value :type: Any .. py:method:: validate_display_name(v: Optional[str], info: pydantic.ValidationInfo) -> str :classmethod: .. py:method:: validate_description(v: Optional[str], info: pydantic.ValidationInfo) -> str :classmethod: .. py:method:: validate_value(v: Any, info: pydantic.ValidationInfo) -> Any :classmethod: .. py:class:: FlowsheetExport(/, **data: Any) A flowsheet and its contained exported model objects. .. py:attribute:: m :type: object .. py:attribute:: obj :type: object .. py:attribute:: name :type: Union[None, str] .. py:attribute:: description :type: Union[None, str] .. py:attribute:: exports :type: Dict[str, ModelExport] .. py:attribute:: kpis :type: Dict[str, KPI] .. py:attribute:: kpi_order :type: list[str] :value: [] .. py:attribute:: kpi_options :type: Dict .. py:attribute:: kpi_figures :type: Dict .. py:attribute:: version :type: int :value: 2 .. py:attribute:: requires_idaes_solver :type: bool :value: False .. py:attribute:: dof :type: int :value: 0 .. py:attribute:: sweep_results :type: Union[None, dict] .. py:attribute:: build_options :type: Dict[str, ModelOption] .. py:method:: validate_name(v: str, info: pydantic.ValidationInfo) -> str :classmethod: .. py:method:: validate_description(v: str, info: pydantic.ValidationInfo) -> str :classmethod: .. py:method:: add(*args: object, data: Union[dict, ModelExport] = None, **kwargs: object) -> object Add a new variable (or other model object). There are a few different ways of invoking this function. Users will typically use this form:: add(obj=, name="My value name", ..etc..) where the keywords after `obj` match the non-computed names in :class:`ModelExport`. If these same name/value pairs are already in a dictionary, this form is more convenient:: add(data=my_dict_of_name_value_pairs) If you have an existing ModelExport object, you can add it more directly with:: add(my_object) # -- OR -- add(data=my_object) :param \*args: If present, should be a single non-named argument, which is a ModelExport object. Create by adding it. :param data: If present, create from this argument. If it's a dict, create from its values just as from the kwargs. Otherwise, it should be a ModelExport object, and create by adding it. :param kwargs: Name/value pairs to create a ModelExport object. Accepted names and default values are in the ModelExport. :raises KeyError: If the name of the Pyomo object is the same as an existing one, i.e. refuse to overwrite. .. py:method:: clear_kpis() -> None .. py:method:: add_kpi_values(name: str, values: List[float], labels: List[str], units: Optional[List[str]], title: str = '') -> None Add a Key Performance Indicator (KPI) for a table of names and values. :param name: Name of the KPI :param values: Numeric values :param labels: Labels corresponding to values :param title: Overall description :param units: Descriptive units for the values (optional) .. py:method:: add_kpi_barchart(name: str, values: List[float], labels: List[str], title: str, xlab: Optional[str] = None, ylab: Optional[str] = None, units: SyntaxWarning = 'none') -> None Add a KeyPerformance Indicator (KPI) vector for a barchart. :param name: Name of the KPI :param values: Numeric values :param labels: Labels corresponding to values :param title: Chart title :param xlab: Label for x axis :param ylab: Label for y axis :param units: Units for the values, e.g., "%" if they are percentages adding to 100 .. py:method:: add_kpi_total(name: str, values: List[float], labels: List[str], title: str, total_label: str, units: str = '%') -> None Add a Key Performance Indicator (KPI) vector with multiple values and a total :param name: Name of the KPI :param values: Numeric values :param labels: Labels corresponding to values :param total_label: Label for the 'total' to which the values sum. :param units: Units for the values, e.g., "%" if they are percentages adding to 100 .. py:method:: set_kpi_default_options(**options: object) -> None .. py:method:: from_csv(file: Union[str, pathlib.Path], flowsheet: object) -> int Load multiple exports from the given CSV file. CSV file format rules: * Always use a header row. The names are case-insensitive, order is not important. The 'name', 'obj', and 'ui_units' columns are required. * Columns names should match the non-computed names in :class:`ModelExport`. See `.add()` for a list. * The object to export should be in a column named 'obj', prefixed with 'fs.' * For units, use Pyomo units module as 'units', e.g., 'mg/L' is `units.mg / units.L` For example:: name,obj,description,ui_units,display_units,rounding,is_input,input_category,is_output,output_category Leach liquid feed rate,fs.leach_liquid_feed.flow_vol[0],Leach liquid feed volumetric flow rate,units.L/units.hour,L/h,2,TRUE,Liquid feed,FALSE, Leach liquid feed H,"fs.leach_liquid_feed.conc_mass_comp[0,'H']",Leach liquid feed hydrogen mass composition,units.mg/units.L,mg/L,3,TRUE,Liquid feed,FALSE, .......etc....... :param file: Filename or path. If not an absolute path, start from the directory of the caller's file. :param flowsheet: Flowsheet used to evaluate the exported objects. :returns: Number of exports added :rtype: int :raises IOError: if input file doesn't exist :raises ValueError: Invalid data in input file (error message will have details) .. py:method:: to_csv(output: Union[io.TextIOBase, pathlib.Path, str] = None) -> int Write wrapped objects as CSV. :param output: Where to write CSV file. Can be a stream, path, or filename. :returns: Number of objects written into file. :raises IOError: If path is given, and not writable .. py:method:: add_option(name: str, **kwargs: object) -> ModelOption Add an 'option' to the flowsheet that can be displayed and manipulated from the UI. Constructs a :class:`ModelOption` instance with provided args and adds it to the dict of options, keyed by its `name`. :param name: Name of option (internal, for accessing the option) :param kwargs: Fields of :class:`ModelOption` .. py:class:: Actions Known actions that can be run. Actions that users should not run directly (unless they know what they are doing) are prefixed with an underscore. .. py:attribute:: build :value: 'build' .. py:attribute:: solve :value: 'solve' .. py:attribute:: export :value: '_export' .. py:attribute:: diagram :value: 'diagram' .. py:attribute:: initialize :value: 'initialize' .. py:attribute:: kpis :value: 'kpis' .. py:class:: FlowsheetCategory Flowsheet Categories .. py:attribute:: wastewater :value: 'Wasterwater Recovery' .. py:attribute:: desalination :value: 'Desalination' .. py:class:: FlowsheetReport Abstract base class for flowsheet reports. This class defines the interface for generating reports from a flowsheet. Subclasses should implement the `to_html` method to generate the report in HTML format. .. py:method:: to_html(**kwargs: object) -> str :abstractmethod: Return report as an HTML string. .. py:class:: FlowsheetInterface(fs: Optional[FlowsheetExport] = None, do_build: Optional[Callable] = None, do_export: Optional[Callable] = None, do_solve: Optional[Callable] = None, do_initialize: Optional[Callable] = None, do_kpis: Optional[Callable] = None, get_diagram: Optional[Callable] = None, category: Optional[FlowsheetCategory] = None, custom_do_param_sweep_kwargs: Optional[Dict] = None, **kwargs: object) Interface between users, UI developers, and flowsheet models. .. py:attribute:: UI_HOOK :value: 'export_to_ui' .. py:attribute:: MissingObject .. py:method:: build(quiet=False, **kwargs: object) -> None Build flowsheet :param quiet: If true, suppress output from the build function :param \*\*kwargs: User-defined values :returns: None :raises RuntimeError: If the build fails .. py:method:: solve(**kwargs: object) -> Any Solve flowsheet. :param \*\*kwargs: User-defined values :returns: Return value of the underlying solve function :raises RuntimeError: if the solver did not terminate in an optimal solution .. py:method:: get_diagram(**kwargs: object) -> Optional[Any] Return diagram image name. :param \*\*kwargs: User-defined values :returns: Return image file name if get_diagram function is callable. Otherwise, return none .. py:method:: initialize(*args: object, **kwargs: object) -> Any Run initialize function. :param \*\*kwargs: User-defined values :returns: Return value of the underlying initialization function. Otherwise, return none .. py:method:: dict() -> Dict Serialize. :returns: Serialized contained FlowsheetExport object .. py:method:: load(data: Dict) -> None Load values from the data into corresponding variables in this instance's FlowsheetObject. :param data: The input flowsheet (probably deserialized from JSON) .. py:method:: select_option(option_name: str, new_option: str) -> None Update flowsheet with selected option. :param data: The input flowsheet :param option_name: Name of selected option :returns: None .. py:method:: add_action(action_name: str, action_func: Callable) -> None Add an action for the flowsheet. :param action_name: Name of the action to take (see :class:`Actions`) :param action_func: Function to call for the action :returns: None .. py:method:: get_action(name: str) -> Optional[Callable] Get the function for an ``add()``-ed action. :param name: Name of the action (see :class:`Actions`) :returns: Function for this action :raises KeyError, if no such action is defined: .. py:method:: run_action(name: str, *args: object, **kwargs: object) -> Any Run the named action. .. py:method:: export_values() -> None Copy current values in underlying Pyomo model into exported model. Side-effects: Attribute ``fs_exp`` is modified. .. py:method:: from_installed_packages(group_name: str = 'watertap.flowsheets') -> Dict[str, FlowsheetInterface] :classmethod: Get all flowsheet interfaces defined as entry points within the Python packages installed in the environment. This uses the :func:`importlib.metadata.entry_points` function to fetch the list of flowsheets declared as part of a Python package distribution's `entry points `_ under the group ``group_name``. To set up a flowsheet interface for discovery, locate your Python package distribution's file (normally :file:`setup.py`, :file:`pyproject.toml`, or equivalent) and add an entry in the ``entry_points`` section. For example, to add a flowsheet defined in :file:`watertap/flowsheets/flowsheets/my_flowsheet.py` so that it can be discovered with the name ``my_flowsheet`` wherever the ``watertap`` package is installed, the following should be added to WaterTAP's :file:`setup.py`:: setup( name="watertap", # other setup() sections entry_points={ "watertap.flowsheets": [ # other flowsheet entry points "my_flowsheet = watertap.flowsheets.flowsheets.my_flowsheet", ] } ) :param group_name: The entry_points group from which the flowsheet interface modules will be populated. :returns: Mapping with keys the module names and values FlowsheetInterface objects .. py:method:: from_module(module: Union[str, types.ModuleType]) -> Optional[FlowsheetInterface] :classmethod: Get a a flowsheet interface for module. :param module: The module :returns: A flowsheet interface or None if it failed .. py:method:: report(rtype=_KPI_REPORT, **kwargs: object) -> FlowsheetReport Generate and return a report for the flowsheet. :param report_type: Type of report to generate (any unique prefix of the report type). :param kwargs: Additional keywords passed to the given report type. :raises ValueError: If a report argument is invalid :returns: A flowsheet report, which will display automatically in Jupyter Notebooks. :rtype: FlowsheetReport .. py:data:: WAFFLE .. py:data:: DONUT .. py:class:: FlowsheetKPIReport(flowsheet_export: FlowsheetExport, total_type: Optional[_ChartTypes] = None, bgcolor: str = '#ffffff', **kwargs: object) Report of the Key Performance Indicators (KPIs) for a flowsheet. The specification of the report is extracted from the FlowsheetExport object that is passed to the class constructor. .. py:attribute:: VALUE_FONT_NAME_SIZE :value: '150%' .. py:attribute:: VALUE_FONT_VAL_SIZE :value: '180%' .. py:attribute:: VALUE_FONT_NAME_COLOR :value: '#666' .. py:attribute:: VALUE_FONT_VAL_COLOR :value: '#66F' .. py:attribute:: VALUE_SEP_WIDTH :value: '7px' .. py:method:: to_html(layout: Optional[Any] = None, **kwargs: object) -> str Build the report and return as a complete element. :param layout: Layout specification. See :class:`Layout` for format. If not given, lay out in one column. :param kwargs: Options for the `create_*` methods. :returns: HTML for the report .. py:method:: get_kpi_figures(**kwargs: object) -> dict[str, plotly.graph_objects.Figure] "Get figures for each KPI. :param kwargs: Options for the `create_*` methods. Returns: .. py:method:: create_kpi_values(kpi, font_size: int = 24, width: int = 800, margin: Optional[int] = None, **ignore: object) -> plotly.graph_objects.Figure :classmethod: Create a table with values for each KPI. :param kpi: :param font_size: Font size for the table, in points :param width: Width of the table in pixels :param margin: Margin around the table, as a dict with keys 't', 'b', 'l', 'r'. Values in pixels. :returns: Plotly Figure object with values in a table .. py:method:: create_kpi_barchart(kpi: KPI, **ignore: object) -> plotly.graph_objects.Figure :classmethod: Create a barchart from a vector of values :param kpi: Key performance indicator :returns: Plotly Figure object with the bar chart .. py:method:: create_kpi_total(kpi: KPI, total_type: _ChartTypes = WAFFLE, **ignore: object) -> plotly.graph_objects.Figure :classmethod: Create diagram for a vector that should be represented as parts of a total. This will be either a pie (donut) chart or waffle chart. :param kpi: Key performance indicator :returns: Plotly Figure object with the pie or waffle chart .. py:class:: Layout(spec, kpis: dict[str, str]) Translate a simple layout specification into an HTML flex layout. The specification takes the form of a (possibly nested) list of names of the KPIs to display, where the outer list is a single column and the next level are rows, then columns within each row, etc. Some examples: * `[ "kpi_one", "kpi_two", "kpi_three" ]` will display 4 rows, each the full column width. * `[["kpi_one", "kpi_two", "kpi_three"]]` will display 1 row with items laid out horizontally * `[["kpi_one", "kpi_two"], ["kpi_three", "kpi_four"]]` will display a 2x2 grid .. py:property:: body .. py:property:: css