package org.openlca.core.results; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import org.openlca.core.database.EntityCache; import org.openlca.core.model.Location; import org.openlca.core.model.descriptors.FlowDescriptor; import org.openlca.core.model.descriptors.ImpactCategoryDescriptor; import org.openlca.core.model.descriptors.ProcessDescriptor; /** * Calculates the contributions of the single process results in an analysis * result grouped by their locations. */ public class LocationContribution { private ContributionResultProvider<?> result; private Map<Location, List<ProcessDescriptor>> index = new HashMap<>(); public LocationContribution(ContributionResultProvider<?> result) { this.result = result; initProcessIndex(); } private void initProcessIndex() { if (result == null) return; EntityCache cache = result.cache; for (ProcessDescriptor process : result.getProcessDescriptors()) { Location loc = null; if (process.getLocation() != null) loc = cache.get(Location.class, process.getLocation()); List<ProcessDescriptor> list = index.get(loc); if (list == null) { list = new ArrayList<>(); index.put(loc, list); } list.add(process); } } /** Calculates contributions to an inventory flow. */ public ContributionSet<Location> calculate(FlowDescriptor flow) { if (flow == null || result == null) return ContributionSet.empty(); double total = result.getTotalFlowResult(flow).value; return Contributions.calculate(index.keySet(), total, location -> { double amount = 0; for (ProcessDescriptor p : index.get(location)) amount += result.getSingleFlowResult(p, flow).value; return amount; }); } /** Calculates contributions to an impact category. */ public ContributionSet<Location> calculate(ImpactCategoryDescriptor impact) { if (impact == null || result == null) return ContributionSet.empty(); double total = result.getTotalImpactResult(impact).value; return Contributions.calculate(index.keySet(), total, location -> { double amount = 0; for (ProcessDescriptor p : index.get(location)) amount += result.getSingleImpactResult(p, impact).value; return amount; }); } /** Calculates added values aggregated by location. */ public ContributionSet<Location> addedValues() { if (result == null) return ContributionSet.empty(); double total = result.getTotalCostResult(); total = total == 0 ? 0 : -total; return Contributions.calculate(index.keySet(), total, location -> { double amount = 0; for (ProcessDescriptor p : index.get(location)) { double r = result.getSingleCostResult(p); r = r == 0 ? 0 : -r; amount += r; } return amount; }); } /** Calculates net-costs aggregated by location. */ public ContributionSet<Location> netCosts() { if (result == null) return ContributionSet.empty(); double total = result.getTotalCostResult(); return Contributions.calculate(index.keySet(), total, location -> { double amount = 0; for (ProcessDescriptor p : index.get(location)) { amount += result.getSingleCostResult(p); } return amount; }); } }