Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add param default and type to math docs #690

Merged
merged 2 commits into from
Sep 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

### User-facing changes

|new| (non-NaN) Default values and data types for parameters appear in math documentation (if they appear in the model definition schema) (#677).

|changed| `data_sources` -> `data_tables` and `data_sources.source` -> `data_tables.data`.
This change has occurred to avoid confusion between data "sources" and model energy "sources" (#673).

Expand Down
2 changes: 2 additions & 0 deletions src/calliope/backend/backend_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ class BackendModelGenerator(ABC):
"description",
"unit",
"default",
"type",
"title",
"math_repr",
"original_dtype",
Expand All @@ -74,6 +75,7 @@ class BackendModelGenerator(ABC):
_PARAM_TITLES = extract_from_schema(MODEL_SCHEMA, "title")
_PARAM_DESCRIPTIONS = extract_from_schema(MODEL_SCHEMA, "description")
_PARAM_UNITS = extract_from_schema(MODEL_SCHEMA, "x-unit")
_PARAM_TYPE = extract_from_schema(MODEL_SCHEMA, "x-type")

def __init__(self, inputs: xr.Dataset, **kwargs):
"""Abstract base class to build a representation of the optimisation problem.
Expand Down
25 changes: 21 additions & 4 deletions src/calliope/backend/latex_backend_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

import jinja2
import numpy as np
import pandas as pd
import xarray as xr

from calliope.backend import backend_model, parsing
Expand Down Expand Up @@ -224,6 +225,10 @@ class LatexBackendModel(backend_model.BackendModelGenerator):

**Default**: {{ equation.default }}
{% endif %}
{% if equation.type is not none %}

**Type**: {{ equation.type }}
{% endif %}
{% if equation.expression != "" %}

.. container:: scrolling-wrapper
Expand Down Expand Up @@ -299,6 +304,10 @@ class LatexBackendModel(backend_model.BackendModelGenerator):

\textbf{Default}: {{ equation.default }}
{% endif %}
{% if equation.type is not none %}

\textbf{Type}: {{ equation.type }}
{% endif %}
{% if equation.expression != "" %}

\begin{equation}
Expand Down Expand Up @@ -371,6 +380,10 @@ class LatexBackendModel(backend_model.BackendModelGenerator):

**Default**: {{ equation.default }}
{% endif %}
{% if equation.type is not none %}

**Type**: {{ equation.type }}
{% endif %}
{% if equation.expression != "" %}
{% if mkdocs_features and yaml_snippet is not none%}

Expand Down Expand Up @@ -421,14 +434,17 @@ def add_parameter( # noqa: D102, override
"title": self._PARAM_TITLES.get(parameter_name, None),
"description": self._PARAM_DESCRIPTIONS.get(parameter_name, None),
"unit": self._PARAM_UNITS.get(parameter_name, None),
"type": self._PARAM_TYPE.get(parameter_name, None),
irm-codebase marked this conversation as resolved.
Show resolved Hide resolved
"math_repr": rf"\textit{{{parameter_name}}}"
+ self._dims_to_var_string(parameter_values),
}
if pd.notna(default):
attrs["default"] = default

self._add_to_dataset(parameter_name, parameter_values, "parameters", attrs)

def add_constraint( # noqa: D102, override
self, name: str, constraint_dict: parsing.UnparsedConstraint | None = None
self, name: str, constraint_dict: parsing.UnparsedConstraint
) -> None:
equation_strings: list = []

Expand Down Expand Up @@ -488,7 +504,7 @@ def _constraint_setter(where: xr.DataArray, references: set) -> xr.DataArray:
)

def add_global_expression( # noqa: D102, override
self, name: str, expression_dict: parsing.UnparsedExpression | None = None
self, name: str, expression_dict: parsing.UnparsedExpression
) -> None:
equation_strings: list = []

Expand All @@ -515,7 +531,7 @@ def _expression_setter(
)

def add_variable( # noqa: D102, override
self, name: str, variable_dict: parsing.UnparsedVariable | None = None
self, name: str, variable_dict: parsing.UnparsedVariable
) -> None:
domain_dict = {"real": r"\mathbb{R}\;", "integer": r"\mathbb{Z}\;"}
bound_refs: set = set()
Expand Down Expand Up @@ -544,7 +560,7 @@ def _variable_setter(where: xr.DataArray, references: set) -> xr.DataArray:
)

def add_objective( # noqa: D102, override
self, name: str, objective_dict: parsing.UnparsedObjective | None = None
self, name: str, objective_dict: parsing.UnparsedObjective
) -> None:
sense_dict = {
"minimize": r"\min{}",
Expand Down Expand Up @@ -623,6 +639,7 @@ def generate_math_doc(
),
"uses": sorted(list(uses[name] - set([name]))),
"default": da.attrs.get("default", None),
"type": da.attrs.get("type", None),
"unit": da.attrs.get("unit", None),
"yaml_snippet": da.attrs.get("yaml_snippet", None),
}
Expand Down
4 changes: 4 additions & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -289,9 +289,13 @@ def dummy_model_data(config_defaults, model_defaults):
"all_nan": np.nan,
"with_inf": 100,
"only_techs": 5,
"no_dims": 0,
**model_defaults,
}
)
# This value is set on the parameter directly to ensure it finds its way through to the LaTex math.
model_data.no_dims.attrs["default"] = 0

model_data.attrs["math"] = AttrDict(
{"constraints": {}, "variables": {}, "global_expressions": {}, "objectives": {}}
)
Expand Down
58 changes: 58 additions & 0 deletions tests/test_backend_latex_backend.py
Original file line number Diff line number Diff line change
Expand Up @@ -383,6 +383,8 @@ def test_create_obj_list(self, dummy_latex_backend_model):
\begin{itemize}
\item expr
\end{itemize}

\textbf{Default}: 0
\end{document}"""
),
),
Expand Down Expand Up @@ -421,6 +423,8 @@ def test_create_obj_list(self, dummy_latex_backend_model):
**Used in**:

* expr

**Default**: 0
"""
),
),
Expand Down Expand Up @@ -454,6 +458,8 @@ def test_create_obj_list(self, dummy_latex_backend_model):
**Used in**:

* [expr](#expr)

**Default**: 0
"""
),
),
Expand Down Expand Up @@ -589,6 +595,8 @@ def test_generate_math_doc_mkdocs_features_admonition(self, dummy_model_data):
??? info "Used in"

* [expr](#expr)

**Default**: 0
"""
)

Expand Down Expand Up @@ -709,3 +717,53 @@ def test_get_variable_bounds_string(self, dummy_latex_backend_model):
"expression": r"\textbf{multi_dim_var}_\text{node,tech} \leq 2\mathord{\times}10^{+06}"
}
assert refs == {"multi_dim_var"}

def test_param_type(self, dummy_model_data):
backend_model = latex_backend_model.LatexBackendModel(dummy_model_data)
backend_model.add_global_expression(
"expr",
{
"equations": [{"expression": "1 + flow_cap_max"}],
"description": "foobar",
"default": 0,
},
)
doc = backend_model.generate_math_doc(format="md")
assert doc == textwrap.dedent(
r"""

## Where

### expr

foobar

**Uses**:

* [flow_cap_max](#flow_cap_max)

**Default**: 0

$$
\begin{array}{l}
\quad 1 + \textit{flow\_cap\_max}\\
\end{array}
$$

## Parameters

### flow_cap_max

Limits `flow_cap` to a maximum.

**Used in**:

* [expr](#expr)

**Unit**: power.

**Default**: inf

**Type**: float
"""
)