package org.openlca.core.math.data_quality; import java.math.RoundingMode; import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.openlca.core.Tests; import org.openlca.core.database.DQSystemDao; import org.openlca.core.database.FlowDao; import org.openlca.core.database.FlowPropertyDao; import org.openlca.core.database.ImpactMethodDao; import org.openlca.core.database.ProcessDao; import org.openlca.core.database.ProductSystemDao; import org.openlca.core.database.UnitGroupDao; import org.openlca.core.math.CalculationSetup; import org.openlca.core.math.SystemCalculator; import org.openlca.core.matrix.cache.MatrixCache; import org.openlca.core.model.DQIndicator; import org.openlca.core.model.DQScore; import org.openlca.core.model.DQSystem; import org.openlca.core.model.Exchange; import org.openlca.core.model.Flow; import org.openlca.core.model.FlowProperty; import org.openlca.core.model.FlowPropertyFactor; import org.openlca.core.model.FlowType; import org.openlca.core.model.ImpactCategory; import org.openlca.core.model.ImpactFactor; import org.openlca.core.model.ImpactMethod; import org.openlca.core.model.Process; import org.openlca.core.model.ProcessLink; import org.openlca.core.model.ProductSystem; import org.openlca.core.model.Unit; import org.openlca.core.model.UnitGroup; import org.openlca.core.model.descriptors.Descriptors; import org.openlca.core.results.ContributionResult; public class DQResultTest { private DQSystem dqSystem; private ProductSystem system; private Process process1; private Process process2; private Flow pFlow1; private Flow pFlow2; private Flow eFlow1; private Flow eFlow2; private FlowProperty property; private UnitGroup unitGroup; private ImpactMethod method; @Before public void setup() { createUnitGroup(); createProperty(); pFlow1 = createFlow(FlowType.PRODUCT_FLOW); pFlow2 = createFlow(FlowType.PRODUCT_FLOW); eFlow1 = createFlow(FlowType.ELEMENTARY_FLOW); eFlow2 = createFlow(FlowType.ELEMENTARY_FLOW); createDQSystem(); process1 = process( exchange(1, "(1;2;3;4;5)", pFlow1, false), exchange(2, null, pFlow2, true), exchange(3, "(1;2;3;4;5)", eFlow1, true), exchange(4, "(5;4;3;2;1)", eFlow2, true)); process2 = process( exchange(1, "(5;4;3;2;1)", pFlow2, false), exchange(5, "(5;4;3;2;1)", eFlow1, true), exchange(6, "(1;2;3;4;5)", eFlow2, true)); createProductSystem(); createImpactMethod(); } @After public void shutdown() { new ImpactMethodDao(Tests.getDb()).delete(method); new ProductSystemDao(Tests.getDb()).delete(system); new ProcessDao(Tests.getDb()).delete(process1); new ProcessDao(Tests.getDb()).delete(process2); new DQSystemDao(Tests.getDb()).delete(dqSystem); new FlowDao(Tests.getDb()).delete(pFlow1); new FlowDao(Tests.getDb()).delete(pFlow2); new FlowDao(Tests.getDb()).delete(eFlow1); new FlowDao(Tests.getDb()).delete(eFlow2); new FlowPropertyDao(Tests.getDb()).delete(property); new UnitGroupDao(Tests.getDb()).delete(unitGroup); } private void createDQSystem() { dqSystem = new DQSystem(); for (int i = 1; i <= 5; i++) { DQIndicator indicator = new DQIndicator(); indicator.position = i; dqSystem.indicators.add(indicator); for (int j = 1; j <= 5; j++) { DQScore score = new DQScore(); score.position = j; indicator.scores.add(score); } } dqSystem = new DQSystemDao(Tests.getDb()).insert(dqSystem); } private void createProductSystem() { system = new ProductSystem(); system.getProcesses().add(process1.getId()); system.getProcesses().add(process2.getId()); ProcessLink link = new ProcessLink(); link.flowId = pFlow2.getId(); link.providerId = process2.getId(); for (Exchange e : process1.getExchanges()) { if (e.getFlow().getId() == pFlow2.getId()) link.exchangeId = e.getId(); } link.processId = process1.getId(); system.getProcessLinks().add(link); system.setReferenceProcess(process1); system.setReferenceExchange(process1.getQuantitativeReference()); system.setTargetAmount(1); system.setTargetFlowPropertyFactor(pFlow1.getReferenceFactor()); system.setTargetUnit(unitGroup.getReferenceUnit()); system = new ProductSystemDao(Tests.getDb()).insert(system); } /** The first exchange is the reference product. */ private Process process(Exchange... exchanges) { Process p = new Process(); p.dqSystem = dqSystem; p.dqEntry = exchanges[0].getDqEntry(); p.exchangeDqSystem = dqSystem; p.setQuantitativeReference(exchanges[0]); for (Exchange e : exchanges) p.getExchanges().add(e); return new ProcessDao(Tests.getDb()).insert(p); } private Exchange exchange(double amount, String dqEntry, Flow flow, boolean input) { Exchange e = new Exchange(); e.setDqEntry(dqEntry); e.setFlow(flow); e.setInput(input); e.setFlowPropertyFactor(flow.getReferenceFactor()); e.setUnit(unitGroup.getReferenceUnit()); e.setAmountValue(amount); return e; } private Flow createFlow(FlowType type) { Flow flow = new Flow(); flow.setFlowType(type); FlowPropertyFactor factor = new FlowPropertyFactor(); factor.setConversionFactor(1d); factor.setFlowProperty(property); flow.getFlowPropertyFactors().add(factor); flow.setReferenceFlowProperty(property); return new FlowDao(Tests.getDb()).insert(flow); } private void createUnitGroup() { unitGroup = new UnitGroup(); Unit unit = new Unit(); unit.setName("unit"); unit.setConversionFactor(1); unitGroup.getUnits().add(unit); unitGroup.setReferenceUnit(unit); unitGroup = new UnitGroupDao(Tests.getDb()).insert(unitGroup); } private void createProperty() { property = new FlowProperty(); property.setUnitGroup(unitGroup); property = new FlowPropertyDao(Tests.getDb()).insert(property); } private void createImpactMethod() { method = new ImpactMethod(); ImpactCategory c = new ImpactCategory(); c.getImpactFactors().add(createFactor(2, eFlow1)); c.getImpactFactors().add(createFactor(8, eFlow2)); method.getImpactCategories().add(c); method = new ImpactMethodDao(Tests.getDb()).insert(method); } private ImpactFactor createFactor(double factor, Flow flow) { ImpactFactor f = new ImpactFactor(); f.setValue(factor); f.setFlow(flow); f.setFlowPropertyFactor(flow.getReferenceFactor()); f.setUnit(unitGroup.getReferenceUnit()); return f; } @Test public void test() { SystemCalculator calculator = new SystemCalculator( MatrixCache.createEager(Tests.getDb()), Tests.getDefaultSolver()); CalculationSetup setup = new CalculationSetup(system); setup.setAmount(1); setup.impactMethod = Descriptors.toDescriptor(method); ContributionResult cResult = calculator.calculateContributions(setup); DQCalculationSetup dqSetup = new DQCalculationSetup(); dqSetup.productSystemId = system.getId(); dqSetup.aggregationType = AggregationType.WEIGHTED_AVERAGE; dqSetup.roundingMode = RoundingMode.HALF_UP; dqSetup.processingType = ProcessingType.EXCLUDE; dqSetup.exchangeDqSystem = dqSystem; dqSetup.processDqSystem = dqSystem; DQResult result = DQResult.calculate(Tests.getDb(), cResult, dqSetup); ImpactCategory impact = method.getImpactCategories().get(0); checkResults(result, impact); } private void checkResults(DQResult result, ImpactCategory impact) { Assert.assertArrayEquals(a(4, 4, 3, 2, 2), getResult(result, eFlow1), 0.5); Assert.assertArrayEquals(a(2, 3, 3, 4, 4), getResult(result, eFlow2), 0.5); Assert.assertArrayEquals(a(2, 3, 3, 3, 4), getResult(result, impact), 0.5); Assert.assertArrayEquals(a(1, 2, 3, 4, 5), getResult(result, process1, eFlow1), 0.5); Assert.assertArrayEquals(a(5, 4, 3, 2, 1), getResult(result, process2, eFlow1), 0.5); Assert.assertArrayEquals(a(5, 4, 3, 2, 1), getResult(result, process1, eFlow2), 0.5); Assert.assertArrayEquals(a(1, 2, 3, 4, 5), getResult(result, process2, eFlow2), 0.5); Assert.assertArrayEquals(a(4, 4, 3, 2, 2), getResult(result, process1, impact), 0.5); Assert.assertArrayEquals(a(2, 2, 3, 4, 4), getResult(result, process2, impact), 0.5); Assert.assertArrayEquals(a(1, 2, 3, 4, 5), getResult(result, process1), 0.5); Assert.assertArrayEquals(a(5, 4, 3, 2, 1), getResult(result, process2), 0.5); } private double[] a(double... vals) { return vals; } private double[] getResult(DQResult result, Flow flow) { return result.get(Descriptors.toDescriptor(flow)); } private double[] getResult(DQResult result, Process process) { return result.get(Descriptors.toDescriptor(process)); } private double[] getResult(DQResult result, ImpactCategory impact) { return result.get(Descriptors.toDescriptor(impact)); } private double[] getResult(DQResult result, Process process, Flow flow) { return result.get(Descriptors.toDescriptor(process), Descriptors.toDescriptor(flow)); } private double[] getResult(DQResult result, Process process, ImpactCategory impact) { return result.get(Descriptors.toDescriptor(process), Descriptors.toDescriptor(impact)); } }