All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.github.qudtlib.tools.contributions.CheckConversionMultipliers Maven / Gradle / Ivy

There is a newer version: 6.8.0
Show newest version
package io.github.qudtlib.tools.contributions;

import static java.lang.String.format;
import static java.util.stream.Collectors.joining;

import io.github.qudtlib.Qudt;
import io.github.qudtlib.math.BigDec;
import io.github.qudtlib.model.FactorUnit;
import io.github.qudtlib.model.QudtNamespaces;
import io.github.qudtlib.model.Unit;
import io.github.qudtlib.tools.contribute.QudtEntityGenerator;
import io.github.qudtlib.tools.contribute.support.FormattingHelper;
import io.github.qudtlib.tools.contribute.support.IndentedOutputStream;
import io.github.qudtlib.tools.contribute.support.tree.UnitTree;
import io.github.qudtlib.vocab.QUDT;
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class CheckConversionMultipliers {
    public static void main(String[] args) {
        QudtEntityGenerator entityGenerator = new QudtEntityGenerator();
        GlobalData globalData = new GlobalData();
        ByteArrayOutputStream ttlOut = new ByteArrayOutputStream();
        PrintStream ttlPrintStream = new PrintStream(ttlOut);
        entityGenerator.unitOfWork(
                tool -> {
                    List unitsToCheck =
                            Qudt.allUnits().stream()
                                    .filter(u -> !u.isCurrencyUnit() && !u.isDeprecated())
                                    .sorted(Comparator.comparing(u -> u.getIri()))
                                    .collect(Collectors.toList());
                    int correctUnits = -1;
                    while (correctUnits < globalData.correctUnits.size()) {
                        correctUnits = globalData.correctUnits.size();
                        unitsToCheck.stream()
                                .filter(u -> !globalData.correctUnits.contains(u))
                                .forEach(unit -> checkUnit(unit, globalData, ttlPrintStream));
                        System.out.println(
                                String.format(
                                        "was incorrect: \n%s\n",
                                        globalData.wasIncorrect.stream()
                                                .map(Unit::getIriAbbreviated)
                                                .collect(Collectors.joining("\n"))));
                        System.out.println(
                                String.format(
                                        "was missing: \n%s\n",
                                        globalData.wasMissing.stream()
                                                .map(Unit::getIriAbbreviated)
                                                .collect(Collectors.joining("\n"))));
                    }
                });
        globalData.missingData.entrySet().stream()
                .sorted(
                        Comparator.comparing((Map.Entry> e) -> e.getValue().size())
                                .reversed())
                .forEach(
                        missing -> {
                            System.out.println(
                                    format(
                                            "MISSING MULTIPLIER: %s - therefore cannot calculate multiplier of %s",
                                            missing.getKey().getIriAbbreviated(),
                                            missing.getValue().stream()
                                                    .map(Unit::getIriAbbreviated)
                                                    .collect(Collectors.joining(", "))));
                        });
        printStatements(ttlOut);
        printDeleteQuery(globalData);
    }

    private static void printStatements(ByteArrayOutputStream ttlOut) {
        System.out.println("STATEMENTS TO ADD:\n\n");
        System.out.println(ttlOut.toString());
    }

    private static void printDeleteQuery(GlobalData globalData) {
        System.out.println("\n\n\nSTATEMENTS TO DELETE\n\n");
        System.out.println("PREFIX qudt: ");
        System.out.println("PREFIX unit: ");
        System.out.println("DELETE { ?u qudt:conversionMultiplier ?m } ");
        System.out.println("WHERE { ?u qudt:conversionMultiplier ?m .");
        System.out.println("VALUES  ?u {");
        System.out.println(
                Stream.concat(globalData.wasMissing.stream(), globalData.wasIncorrect.stream())
                        .map(Unit::getIriAbbreviated)
                        .collect(joining("\n\t")));
        System.out.println("}}");
    }

    private static void checkUnit(Unit unit, GlobalData globalData, PrintStream ttlPrintStream) {
        PrintStream commentsForTTl = new IndentedOutputStream(ttlPrintStream, "  # ").printStream();
        if (!globalData.trustCalculationForUnit(unit)) {
            return;
        }
        Optional calculatedMultiplier =
                unit.getFactorUnits().getConversionMultiplierOpt();
        if (calculatedMultiplier.isEmpty()) {
            return;
        } else {
            if (unit.getConversionMultiplier().isPresent()) {
                BigDecimal actualMultiplier = unit.getConversionMultiplier().get();
                boolean isRelevantDifference =
                        BigDec.isRelativeDifferenceGreaterThan(
                                calculatedMultiplier.get(),
                                actualMultiplier,
                                new BigDecimal(globalData.relativeDifferenceThreshold));
                if (isRelevantDifference) {
                    commentsForTTl.println(
                            format(
                                    "WRONG MULTIPLIER  : %s - calculated from factors: %s, actual: %s\n",
                                    unit.getIriAbbreviated(),
                                    calculatedMultiplier.get().toString(),
                                    actualMultiplier.toString()));
                    printConversionMultiplierTriple(
                            ttlPrintStream, commentsForTTl, unit, calculatedMultiplier.get());
                    setMultiplier(unit, calculatedMultiplier);
                    globalData.correctUnits.add(unit);
                    globalData.wasIncorrect.add(unit);
                } else {
                    globalData.correctUnits.add(unit);
                }
            } else {
                commentsForTTl.println(
                        format(
                                "MISSING MULTIPLIER: %s - calculated from factors: %s\n",
                                unit.getIriAbbreviated(), calculatedMultiplier.get().toString()));
                printConversionMultiplierTriple(
                        ttlPrintStream, commentsForTTl, unit, calculatedMultiplier.get());
                setMultiplier(unit, calculatedMultiplier);
                globalData.correctUnits.add(unit);
                globalData.wasMissing.add(unit);
            }
        }
    }

    private static void setMultiplier(Unit unit, Optional calculatedMultiplier) {
        try {
            Field conversionMultiplierField = Unit.class.getDeclaredField("conversionMultiplier");
            conversionMultiplierField.setAccessible(true);
            conversionMultiplierField.set(unit, calculatedMultiplier.get());
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    private static void collectEffectsOfMissingMultiplier(Unit unit, GlobalData globalData) {
        unit.getFactorUnits()
                .streamAllFactorUnitsRecursively(
                        fu -> fu.getUnit().getConversionMultiplier().isEmpty())
                .map(FactorUnit::getUnit)
                .forEach(
                        causeUnit ->
                                globalData.missingData.compute(
                                        causeUnit,
                                        (u, missing) -> {
                                            if (missing == null) {
                                                missing = new HashSet<>();
                                            }
                                            missing.add(unit);
                                            return missing;
                                        }));
    }

    private static void printConversionMultiplierTriple(
            PrintStream printStream,
            PrintStream commentStream,
            Unit nonBaseUnit,
            BigDecimal conversionFactorToBase) {
        String factorUnitTree =
                UnitTree.makeFactorUnitTreeShowingConversionMultipliers(nonBaseUnit);
        commentStream.print(factorUnitTree);
        printStream.format(
                "%s %s %s .\n\n",
                nonBaseUnit.getIriAbbreviated(),
                QudtNamespaces.qudt.abbreviate(QUDT.conversionMultiplier.toString()),
                FormattingHelper.format(conversionFactorToBase));
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy