package org.openlca.core.math.data_quality; import java.sql.SQLException; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; import org.openlca.core.database.IDatabase; import org.openlca.core.database.NativeSql; import org.openlca.core.matrix.LongPair; import org.slf4j.Logger; import org.slf4j.LoggerFactory; class DQData { private static Logger log = LoggerFactory.getLogger(DQData.class); Map<Long, double[]> processData = new HashMap<>(); Map<LongPair, double[]> exchangeData = new HashMap<>(); DQStatistics statistics = new DQStatistics(); private Set<Long> relevantFlowIds = new HashSet<>(); public static DQData load(IDatabase db, DQCalculationSetup setup, long[] relevantFlowIds) { DQData data = new DQData(); for (long id : relevantFlowIds) { data.relevantFlowIds.add(id); } if (setup.processDqSystem != null) { data.loadProcessEntries(db, setup); } if (setup.exchangeDqSystem != null) { data.loadExchangeEntries(db, setup); } return data; } private DQData() { // hide constructor } private void loadProcessEntries(IDatabase db, DQCalculationSetup setup) { String query = "SELECT id, dq_entry FROM tbl_processes"; query += " INNER JOIN tbl_product_system_processes ON tbl_processes.id = tbl_product_system_processes.f_process "; query += " WHERE tbl_product_system_processes.f_product_system = " + setup.productSystemId; try { NativeSql.on(db).query(query.toString(), (res) -> { long processId = res.getLong("id"); String dqEntry = res.getString("dq_entry"); int[] values = setup.processDqSystem.toValues(dqEntry); processData.put(processId, toDouble(values)); increaseCounter(statistics.processCounts, 0); for (int i = 0; i < values.length; i++) { if (values[i] == 0) continue; increaseCounter(statistics.processCounts, i + 1); } return true; }); } catch (SQLException e) { log.error("Error loading process data quality entries", e); } } private <T> void increaseCounter(Map<T, Integer> map, T key) { if (!map.containsKey(key)) { map.put(key, 1); return; } map.put(key, map.get(key) + 1); } private void loadExchangeEntries(IDatabase db, DQCalculationSetup setup) { String query = "SELECT f_owner, f_flow, dq_entry FROM tbl_exchanges"; query += " INNER JOIN tbl_product_system_processes ON tbl_exchanges.f_owner = tbl_product_system_processes.f_process "; query += " WHERE tbl_product_system_processes.f_product_system = " + setup.productSystemId; try { NativeSql.on(db).query(query.toString(), (res) -> { long processId = res.getLong("f_owner"); long flowId = res.getLong("f_flow"); if (!relevantFlowIds.contains(flowId)) return true; String dqEntry = res.getString("dq_entry"); int[] values = setup.exchangeDqSystem.toValues(dqEntry); exchangeData.put(new LongPair(processId, flowId), toDouble(values)); increaseCounter(getMap(statistics.exchangeCounts, 0l), 0); increaseCounter(getMap(statistics.exchangeCounts, processId), 0); for (int i = 0; i < values.length; i++) { if (values[i] == 0) continue; increaseCounter(getMap(statistics.exchangeCounts, 0l), i + 1); increaseCounter(getMap(statistics.exchangeCounts, processId), i + 1); } return true; }); } catch (SQLException e) { log.error("Error loading process data quality entries", e); } } private Map<Integer, Integer> getMap(Map<Long, Map<Integer, Integer>> map, long id) { if (!map.containsKey(id)) { map.put(id, new HashMap<>()); } return map.get(id); } private double[] toDouble(int[] values) { double[] result = new double[values.length]; for (int i = 0; i < values.length; i++) { result[i] = values[i]; } return result; } }