Skip to content

aeromaps.models.impacts.life_cycle_assessment.io.common

Credits: lca_algebraic-web-app from Raphael Jolivet (Mines ParisTech). https://git.sophia.minesparis.psl.eu/oie/lca_algebraic-web-app/

ParamType

Bases: str, Enum

Parameter type enumeration for the LCA algebraic model.

FunctionalUnit

FunctionalUnit(quantity, unit)

Functional unit with a quantity expression and a unit string.

Source code in aeromaps/models/impacts/life_cycle_assessment/io/common.py
33
34
35
def __init__(self, quantity, unit):
    self.quantity = quantity
    self.unit = unit

Lambda

Lambda(expr, all_params)

This class represents a compiled (lambdified) expression together with the list of requirement parameters and the source expression

Source code in aeromaps/models/impacts/life_cycle_assessment/io/common.py
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
def __init__(self, expr, all_params):
    if isinstance(expr, dict):
        self.lambd = dict()

        # First, gather all expanded parameters
        all_expanded_params = set()
        for key, sub_expr in expr.items():
            if not is_expr(sub_expr):
                continue
            expanded_params = list(str(symbol) for symbol in sub_expr.free_symbols)
            all_expanded_params.update(expanded_params)

        all_expanded_params = list(all_expanded_params)

        # Transform them into list of params
        self.params = unexpand_param_names(all_params, all_expanded_params)
        reexpanded_params = expand_param_names(all_params, self.params)

        # Lambdify with all expanded params
        for key, sub_expr in expr.items():
            self.lambd[key] = _lambdify(sub_expr, reexpanded_params)

    else:
        if not isinstance(expr, Expr):
            expr = Float(expr)

        expanded_params = list(str(symbol) for symbol in expr.free_symbols)
        self.params = unexpand_param_names(all_params, expanded_params)

        # Reexpend symbols, to ensure all enum values are present as a parameter
        reexpanded_params = expand_param_names(all_params, self.params)

        self.lambd = _lambdify(expr, reexpanded_params)

    self.expr = expr

Param

Param(name, type, unit, default, values=None, min=None, max=None, description=None, label=None, group=None)

Parameter definition for the LCA algebraic model.

Source code in aeromaps/models/impacts/life_cycle_assessment/io/common.py
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
def __init__(
    self,
    name: str,
    type: ParamType,
    unit: str,
    default: float,
    values: List[str] = None,
    min: float = None,
    max: float = None,
    description: str = None,
    label: str = None,
    group: str = None,
):
    self.name: str = name
    self.label: str = label
    self.type: ParamType = type
    self.default: Float = default
    self.unit: str = unit
    self.group: str = group
    self.description: str = description
    if values:
        self.values = values
    else:
        self.min = min
        self.max = max

Impact

Impact(name, unit)

Impact metadata with name and unit.

Source code in aeromaps/models/impacts/life_cycle_assessment/io/common.py
200
201
202
def __init__(self, name, unit):
    self.name = (name,)
    self.unit = unit

Model

Model(params, expressions, functional_units, impacts)

Container for parameters, expressions, functional units, and impacts.

:param params: List of all parameters :param expressions: Dict of Dict {axis => {method => Lambda}} :param functional_units: Dict of function unit name => formula :param impacts : Dict of impacts with their units

Source code in aeromaps/models/impacts/life_cycle_assessment/io/common.py
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
def __init__(
    self,
    params: Dict,
    expressions: Dict[str, Dict[str, Lambda]],
    functional_units: Dict[str, FunctionalUnit],
    impacts: Dict[str, Impact],
):
    """
    :param params: List of all parameters
    :param expressions: Dict of Dict {axis => {method => Lambda}}
    :param functional_units: Dict of function unit name => formula
    :param impacts : Dict of impacts with their units
    """
    self.params: Dict[str, Param] = params
    self.expressions: Dict[str, Dict[str, Lambda]] = expressions
    self.functional_units: Dict[str, FunctionalUnit] = functional_units
    self.impacts: Dict[str, Impact] = impacts

evaluate

evaluate(impact, functional_unit=FUNCTIONAL_UNIT_KEY, axis=TOTAL_AXIS_KEY, **param_values)

:param axis: Axis to consider :param impact: Impact to consider :param functional_unit: Function unit :param param_values: List of parameters :return: ,

Source code in aeromaps/models/impacts/life_cycle_assessment/io/common.py
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
def evaluate(
    self, impact, functional_unit=FUNCTIONAL_UNIT_KEY, axis=TOTAL_AXIS_KEY, **param_values
):
    """
    :param axis: Axis to consider
    :param impact: Impact to consider
    :param functional_unit: Function unit
    :param param_values: List of parameters
    :return: <Value of impact, or dict of values, in case one axis is used>, <unit>
    """

    if axis not in self.expressions:
        raise Exception(
            "Wrong axis '%s'. Expected one of %s" % (axis, list(self.expressions.keys()))
        )

    expressions_by_impact = self.expressions[axis]

    if impact not in expressions_by_impact:
        raise Exception(
            "Wrong impact '%s'. Expected one of %s"
            % (impact, list(expressions_by_impact.keys()))
        )

    lambd = expressions_by_impact[impact]
    impact_obj = self.impacts[impact]
    functional_unit = self.functional_units[functional_unit]

    # Compute value of functional unit
    fu_val = functional_unit.quantity.evaluate(self.params, param_values)

    # Compute value of impacts
    impacts = lambd.evaluate(self.params, param_values)

    # Filter out "null"=zero axis

    unit = impact_obj.unit

    if functional_unit.unit is not None:
        unit += "/" + functional_unit.unit

    # Divide the two
    if isinstance(impacts, dict):
        # Filter out "null"=zero axis
        impacts = {
            key: val for key, val in impacts.items() if not (key == "null" and val == 0.0)
        }

        vals = {key: val / fu_val for key, val in impacts.items()}
    else:
        vals = impacts / fu_val

    return vals, unit

unexpand_param_names

unexpand_param_names(all_params, expanded_param_names)

Build a dict of expended_param => param

Source code in aeromaps/models/impacts/life_cycle_assessment/io/common.py
189
190
191
192
193
194
def unexpand_param_names(all_params, expanded_param_names):
    """Build a dict of expended_param => param"""
    expanded_params_to_params = {
        name: param.name for param in all_params.values() for name in param.expand_names()
    }
    return list(set(expanded_params_to_params[name] for name in expanded_param_names))