eu.crydee.alignment.aligner.ae.MetricsSummaryAE.java Source code

Java tutorial

Introduction

Here is the source code for eu.crydee.alignment.aligner.ae.MetricsSummaryAE.java

Source

/*
 * Copyright 2014 Hugo m09? Mougard.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package eu.crydee.alignment.aligner.ae;

import com.google.common.collect.HashBasedTable;
import com.google.common.collect.Lists;
import com.google.common.collect.Table;
import eu.crydee.alignment.aligner.ts.Document;
import eu.crydee.alignment.metricslab.model.Alignment;
import eu.crydee.alignment.metricslab.model.Complete;
import eu.crydee.alignment.metricslab.model.annotations.Metric;
import eu.crydee.alignment.metricslab.model.exceptions.TAFParseException;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang3.tuple.Pair;
import org.apache.commons.math3.stat.descriptive.SummaryStatistics;
import org.apache.commons.math3.stat.inference.TestUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.uima.UimaContext;
import org.apache.uima.analysis_engine.AnalysisEngineProcessException;
import org.apache.uima.fit.component.JCasAnnotator_ImplBase;
import org.apache.uima.fit.descriptor.ConfigurationParameter;
import org.apache.uima.fit.util.JCasUtil;
import org.apache.uima.jcas.JCas;
import org.apache.uima.resource.ResourceInitializationException;

/**
 *
 * @author Hugo m09? Mougard
 */
public class MetricsSummaryAE extends JCasAnnotator_ImplBase {

    private static final Logger logger = LogManager.getLogger(MetricsSummaryAE.class);

    public static final String PARAM_TAF_FOLDER = "TAF_FOLDER";
    @ConfigurationParameter(name = PARAM_TAF_FOLDER, mandatory = true)
    private String tafFolder;

    public static final String PARAM_HTML_OUTPUT_FILEPATH = "HTML_OUTPUT_FILEPATH";
    @ConfigurationParameter(name = PARAM_HTML_OUTPUT_FILEPATH, mandatory = true)
    private String htmlFilepath;

    public static final String PARAM_METRICS_TO_SUMMARIZE = "METRICS_TO_SUMMARIZE";
    @ConfigurationParameter(name = PARAM_METRICS_TO_SUMMARIZE, mandatory = true)
    String[] keysArray;

    private Table<String, String, Samples> results;
    private Map<String, Pair<Method, String>> methodsMetadata;
    private List<String> keys;

    private class Samples {

        public double mu;
        public Set<Double> samples = new HashSet<>();
    }

    @Override
    public void initialize(UimaContext context) throws ResourceInitializationException {
        super.initialize(context);
        results = HashBasedTable.create();
        keys = Lists.newArrayList(keysArray);
        methodsMetadata = Arrays.stream(Complete.class.getMethods())
                .map(m -> Pair.of(m, m.getAnnotation(Metric.class)))
                .filter(p -> p.getRight() != null && keys.contains(p.getRight().key()))
                .collect(Collectors.toMap(p -> p.getRight().key(), p -> Pair.of(p.getLeft(), p.getRight().name())));
    }

    @Override
    public void process(JCas jcas) throws AnalysisEngineProcessException {
        String name = JCasUtil.selectSingle(jcas, Document.class).getName();
        try {
            Alignment alignment = Alignment.fromTAF(
                    FileUtils.readFileToString(new File(tafFolder, name + ".taf"), StandardCharsets.UTF_8));
            String[] cities = name.split("-");
            for (String k : keys) {
                if (!results.contains(cities[0], k)) {
                    results.put(cities[0], k, new Samples());
                }
                double r = (double) methodsMetadata.get(k).getLeft().invoke(alignment.complete);
                if (cities[0].equals(cities[1])) {
                    results.get(cities[0], k).mu = r;
                } else {
                    results.get(cities[0], k).samples.add(r);
                }
            }
        } catch (TAFParseException ex) {
            logger.error("Couldn't parse the TAF when trying to compute graph " + "metrics.");
            throw new AnalysisEngineProcessException(ex);
        } catch (IOException ex) {
            logger.error("Couldn't read the TAF when trying to compute graph " + "metrics.");
            throw new AnalysisEngineProcessException(ex);
        } catch (IllegalArgumentException | IllegalAccessException | InvocationTargetException ex) {
            logger.error("Couldn't compute one of the metrics.");
            throw new AnalysisEngineProcessException(ex);
        }
    }

    @Override
    public void collectionProcessComplete() throws AnalysisEngineProcessException {
        try {
            String template = IOUtils.toString(getClass()
                    .getResourceAsStream("/eu/crydee/alignment/aligner/ae/" + "metrics-summarizer-template.html"));
            String titledTemplate = template.replace("@@TITLE@@",
                    "Metrics summarizer" + LocalDateTime.now().format(DateTimeFormatter.ISO_DATE_TIME));
            StringBuilder sb = new StringBuilder();
            sb.append("<table class=\"table table-striped ").append("table-condensed\">\n")
                    .append("            <thead>\n").append("                <tr>\n")
                    .append("                    <th>City\\Metric</th>\n");
            for (String key : keys) {
                sb.append("                    <th>").append(methodsMetadata.get(key).getRight()).append("</th>\n");
            }
            sb.append("                <tr>\n").append("            </thead>\n").append("            <tbody>\n");
            for (String ele : results.rowKeySet()) {
                sb.append("                <tr>\n").append("                    <td>").append(ele)
                        .append("</td>\n");
                Map<String, Samples> metricResults = results.row(ele);
                for (String key : keys) {
                    Samples samples = metricResults.get(key);
                    SummaryStatistics ss = new SummaryStatistics();
                    samples.samples.forEach(d -> ss.addValue(d));
                    double mean = ss.getMean();
                    boolean significant = TestUtils.tTest(samples.mu,
                            ArrayUtils.toPrimitive(samples.samples.toArray(new Double[0])), 0.05),
                            above = samples.mu > mean;
                    String summary = String.format("%.3f", samples.mu) + " <small class=\"text-muted\">"
                            + String.format("%.3f", ss.getMean()) + ""
                            + String.format("%.3f", ss.getStandardDeviation()) + "</small>";
                    logger.info(ele + "\t" + key + "\t" + summary + "\t" + significant);
                    sb.append("                    <td class=\"")
                            .append(significant ? (above ? "success" : "danger") : "warning").append("\">")
                            .append(summary).append("</td>\n");
                }
                sb.append("                </tr>\n");
            }
            sb.append("            </tbody>\n").append("        </table>");
            FileUtils.write(new File(htmlFilepath), titledTemplate.replace("@@TABLE@@", sb.toString()),
                    StandardCharsets.UTF_8);
        } catch (IOException ex) {
            logger.error("IO problem with the HTML output.");
            throw new AnalysisEngineProcessException(ex);
        }
    }
}