package org.openlca.core.matrix; import org.openlca.core.math.NumberGenerator; import org.openlca.core.model.UncertaintyType; import org.openlca.expressions.FormulaInterpreter; import org.openlca.expressions.Scope; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * The cell value is negative if the factor is related to an input flow. */ class ImpactFactorCell { private final long methodId; private final boolean inputFlow; private final CalcImpactFactor factor; private NumberGenerator generator; ImpactFactorCell(CalcImpactFactor factor, long methodId, boolean inputFlow) { this.factor = factor; this.methodId = methodId; this.inputFlow = inputFlow; } void eval(FormulaInterpreter interpreter) { if (interpreter == null) return; try { Scope scope = interpreter.getScope(methodId); if (scope == null) scope = interpreter.getGlobalScope(); tryEval(scope); } catch (Exception e) { Logger log = LoggerFactory.getLogger(getClass()); log.error("Formula evaluation failed, impact factor " + factor, e); } } private void tryEval(Scope scope) throws Exception { if (factor.getAmountFormula() != null) { double v = scope.eval(factor.getAmountFormula()); factor.setAmount(v); } if (factor.getParameter1Formula() != null) { double v = scope.eval(factor.getParameter1Formula()); factor.setParameter1(v); } if (factor.getParameter2Formula() != null) { double v = scope.eval(factor.getParameter2Formula()); factor.setParameter2(v); } if (factor.getParameter3Formula() != null) { double v = scope.eval(factor.getParameter3Formula()); factor.setParameter3(v); } } double getMatrixValue() { if (factor == null) return 0; double amount = factor.getAmount() * factor.getConversionFactor(); return inputFlow ? -amount : amount; } double getNextSimulationValue() { UncertaintyType type = factor.getUncertaintyType(); if (type == null || type == UncertaintyType.NONE) return getMatrixValue(); if (generator == null) generator = createGenerator(type); double amount = generator.next() * factor.getConversionFactor(); return inputFlow ? -amount : amount; } private NumberGenerator createGenerator(UncertaintyType type) { final CalcImpactFactor f = factor; switch (type) { case LOG_NORMAL: return NumberGenerator.logNormal(f.getParameter1(), f.getParameter2()); case NORMAL: return NumberGenerator.normal(f.getParameter1(), f.getParameter2()); case TRIANGLE: return NumberGenerator.triangular(f.getParameter1(), f.getParameter2(), f.getParameter3()); case UNIFORM: return NumberGenerator .uniform(f.getParameter1(), f.getParameter2()); default: return NumberGenerator.discrete(f.getAmount()); } } }