fr.inrialpes.exmo.align.cli.GroupOutput.java Source code

Java tutorial

Introduction

Here is the source code for fr.inrialpes.exmo.align.cli.GroupOutput.java

Source

/*
 * $Id: GroupOutput.java 2001 2014-11-26 11:06:52Z euzenat $
 *
 * Copyright (C) 2003-2014, INRIA
 * Copyright (C) 2004, Universit de Montral
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public License
 * as published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public
 * License along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
 * USA.
 */

/* This program evaluates the results of several ontology aligners
   and generates a LaTeX diagram for each of these
*/

package fr.inrialpes.exmo.align.cli;

import org.semanticweb.owl.align.Alignment;
import org.semanticweb.owl.align.AlignmentException;
import org.semanticweb.owl.align.Evaluator;

import fr.inrialpes.exmo.align.impl.eval.PRecEvaluator;

import fr.inrialpes.exmo.ontowrap.OntologyFactory;
import fr.inrialpes.exmo.ontowrap.OntowrapException;

import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.BufferedWriter;
import java.io.OutputStreamWriter;
import java.io.IOException;
import java.lang.Integer;
import java.util.Hashtable;
import java.util.Vector;
import java.util.Enumeration;
import java.util.Properties;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.Option;
import org.apache.commons.cli.ParseException;

import fr.inrialpes.exmo.align.parser.AlignmentParser;

/**
 * A basic class for synthesizing the alignment results of an algorithm with
 * regard to the ontology characteristics as a colored module.
 *
 * These modules are however computed on averaging the precision recall/graphs
 * on test directories instead of recording the actual precision recall graphs
 * which would amount at recoding all the valid and invalid alignment cells and
 * their level.
 *  
 *  <pre>
 *  java -cp procalign.jar fr.inrialpes.exmo.align.util.GroupOutput [options]
 *  </pre>
 *
 *  where the options are:
 *  <pre>
 *  -o filename --output=filename
 *  -c --color
 *  -v --values
 *  -e --labels
 *  -m --measure
 *  -l list of compared algorithms
 *  -t output --type=output: tex/html
 * </pre>
 *
 * The input is taken in the current directory in a set of subdirectories (one per
 * test) each directory contains a the alignment files (one per algorithm) for that test and the
 * reference alignment file.
 *
 * If output is
 * requested (<CODE>-o</CODE> flags), then output will be written to
 *  <CODE>output</CODE> if present, stdout by default. In case of the Latex output, there are numerous files generated (regardless the <CODE>-o</CODE> flag).
 *
 *
 * <pre>
 * $Id: GroupOutput.java 2001 2014-11-26 11:06:52Z euzenat $
 * </pre>
 *
 * @author Jrme Euzenat
 */

/*
Generating Spider/Radar view in TikZ is very easy.
The code below works.
But it is less informative than the above presentation.
    
\begin{tikzpicture}
    
% JE: experiment to draw radar/spider plots in TikZ
% n= number of dimensions (here 5)
% w=radius if the graph (here 2)
% p=number of isovalue lines (here 2)
    
% grid 
% (for i=1 to n do \draw[black!50] (0,0) -- (i*360/n:w);
\draw[black!50] (0,0) -- (0:2) node {instances};
\draw[black!50] (0,0) -- (72:2) node {properties};
\draw[black!50] (0,0) -- (144:2) node {label};
\draw[black!50] (0,0) -- (216:2) node {hierarchy};
\draw[black!50] (0,0) -- (288:2);
% (for i=1 to p do \draw[black!50] (0,0) -- (i*360/n:w/i);
\draw[black!50] (0:2) -- (72:2) -- (144:2) -- (216:2) -- (288:2) -- (360:2);
\draw[black!50] (0:1) -- (72:1) -- (144:1) -- (216:1) -- (288:1) -- (360:1);
    
% any curve can be displayed in the same way
\draw (0:1) -- (72:1.22) -- (144:1.56) -- (216:.78) -- (288:.6) -- (360:1);
    
\end{tikzpicture} 
*/

public class GroupOutput extends CommonCLI {
    final static Logger logger = LoggerFactory.getLogger(GroupOutput.class);

    static int SIZE = 16;// Nb of cells = 2^ = 16
    static int cellSpec[][] = { { 101 }, //liph=0
            { 201, 202, 203, 204, 205, 206, 207, 208, 209, 210 }, //phi=1
            { 221 }, //lip=2
            { 224 }, //lph=3
            { 225, 228, 230, 231 }, //hil=4
            { 232, 237, 238 }, //lp=5
            { 233, 239, 240 }, //li=6
            { 236 }, //lh=7
            { 249 }, //ph=8
            { 248, 251, 252 }, //ip=9
            { 250 }, //hi=10
            { 241, 246, 247 }, //l=11
            { 253, 258, 259 }, //p=12
            { 257 }, //h=13
            { 254, 260, 261 }, //i=14
            { 262, 265, 266 } };//emptyset=15
    String[] listAlgo;
    String type = "tex";
    String color = "blue";
    boolean labels = false;
    boolean values = false;
    int measure = 0;
    PrintWriter output = null;
    String ontoDir = null;
    String prefix = null;

    public GroupOutput() {
        super();
        options.addOption(createListOption("l", "list", "List of FILEs to be included in the results (required)",
                "FILE", ','));
        options.addOption(createOption("v", "values", "Displays the values"));
        options.addOption(createOption("e", "labels", "Displays graph labels"));
        options.addOption(
                createRequiredOption("c", "color", "Use COLOR to fill cells (default: " + color + ")", "COLOR"));
        options.addOption(
                createRequiredOption("t", "type", "Output TYPE (html|tex; default: " + type + ")", "TYPE"));
        options.addOption(createRequiredOption("f", "format", "Display MEASure (prof; default: f)", "MEAS (prof)"));
        options.addOption(
                createRequiredOption("w", "directory", "The DIRectory containing the data to match", "DIR"));
    }

    public static void main(String[] args) {
        try {
            new GroupOutput().run(args);
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        ;
    }

    public void run(String[] args) throws Exception {

        try {
            CommandLine line = parseCommandLine(args);
            if (line == null)
                return; // --help

            // Here deal with command specific arguments
            if (line.hasOption('v'))
                values = true;
            if (line.hasOption('e'))
                labels = true;
            if (line.hasOption('c'))
                color = line.getOptionValue('c', "blue");
            if (line.hasOption('t'))
                type = line.getOptionValue('t');
            if (line.hasOption('l'))
                listAlgo = line.getOptionValues('l');
            if (line.hasOption('f')) {
                String s = line.getOptionValue('f');
                if (s.equals("p"))
                    measure = 1;
                else if (s.equals("r"))
                    measure = 2;
                else if (s.equals("o"))
                    measure = 3;
            }
            if (line.hasOption('w'))
                ontoDir = line.getOptionValue('w');
        } catch (ParseException exp) {
            logger.error(exp.getMessage());
            usage();
            System.exit(-1);
        }

        parameters.setProperty("step", Integer.toString(SIZE));

        try {
            File dir = null;
            if (ontoDir == null) {
                dir = new File(System.getProperty("user.dir"));
            } else {
                dir = new File(ontoDir);
            }
            prefix = dir.toURI().toString();
        } catch (Exception e) {
            logger.error("Cannot stat dir ", e);
            usage();
            System.exit(-1);
        }

        // Set output file
        OutputStream stream;
        if (outputfilename == null) {
            stream = System.out;
        } else {
            stream = new FileOutputStream(outputfilename);
        }
        output = new PrintWriter(new BufferedWriter(new OutputStreamWriter(stream, "UTF-8")), true);

        // Header
        if (type.equals("tex")) {
            output.println("\\documentclass[11pt]{book}");
            output.println();
            output.println("\\usepackage{pgf}");
            output.println("\\usepackage{tikz}");
            output.println("\\usepackage{pgflibraryshapes}");
            output.println();
            output.println("\\begin{document}");
            output.println("\\date{today}");
            output.println("");
        }
        // Process
        iterateAlgorithm();
        // Trailer
        if (type.equals("tex")) {
            output.println("\\end{document}");
            output.println();
        }

    }

    public void iterateAlgorithm() {
        // for all alignments there,
        for (String algo : listAlgo) {
            //logger.trace("Algorithm: {}", algo);
            // type
            if (type.equals("tex")) {
                printPGFTeX(algo, iterateCells(algo));
            } else {
                logger.warn("Flag -t {} : not implemented yet", type);
            }
        }
    }

    public double[] iterateCells(String algo) {
        double[] cells = new double[SIZE];
        for (int i = 0; i < SIZE; i++) {
            cells[i] = iterateTests(algo, cellSpec[i]);
        }
        return cells;
    }

    public double iterateTests(String algo, int[] tests) {
        double result = 0.0;
        int nbtests = 0;
        for (int i = 0; i < tests.length; i++) {//size() or length
            //logger.trace("    tests: {}", tests[i]);
            String testdir = prefix + "/" + tests[i] + "/";
            try {
                PRecEvaluator evaluator = (PRecEvaluator) eval(testdir + "refalign.rdf", testdir + algo + ".rdf");
                result += getMeasure(evaluator);
                nbtests++; // Only the tests that succeed
            } catch (AlignmentException aex) {
                logger.debug("IGNORED Exception", aex);
            }
        }
        // Unload the ontologies.
        try {
            OntologyFactory.clear();
        } catch (OntowrapException owex) {
            logger.debug("IGNORED Exception", owex);
        }
        return result / (double) nbtests;
    }

    public Evaluator eval(String alignName1, String alignName2) throws AlignmentException {
        Evaluator eval = null;
        // Load alignments
        Alignment align1 = null, align2 = null;
        try {
            AlignmentParser aparser = new AlignmentParser();
            align1 = aparser.parse(alignName1);
            //logger.trace(" Alignment structure1 parsed");
            aparser.initAlignment(null);
            align2 = aparser.parse(alignName2);
            //logger.trace(" Alignment structure2 parsed");
        } catch (Exception ex) {
            throw new AlignmentException("Cannot parse ", ex);
        }
        // Create evaluator object
        eval = new PRecEvaluator(align1, align2);
        // Compare
        eval.eval(parameters);
        return eval;
    }

    public void printPGFTeX(String algo, double[] cells) {
        output.println("\n%% Plot generated by GroupOutput of alignapi");
        output.println("\\begin{figure}[!h]");
        output.println("\\begin{center}");
        output.println("\\begin{tikzpicture}");

        output.println("\\begin{scope}[minimum size=1cm]");
        if (labels) {
            output.println("\\draw (-.5,2.) node[anchor=east] {labels};");
            output.println("\\draw (2.5,0.) node[anchor=west] {hierarchy};");
            output.println("\\draw (-.5,0.) node[anchor=east] {properties};");
            output.println("\\draw (2.5,2.0) node[anchor=west] {instances};");
        }

        output.println("\\draw (0,2.) node[diamond" + colorFormat(cells[11]) + "] {}; % l");
        if (values)
            output.println("\\draw (0,2.) node {" + stringFormat(cells[11]) + "}; % l");
        output.println("\\draw (0,1.) node[diamond" + colorFormat(cells[5]) + "] {}; % lp");
        if (values)
            output.println("\\draw (0,1.) node {" + stringFormat(cells[5]) + "}; % lp");
        output.println("\\draw (0.5,1.5) node[diamond" + colorFormat(cells[2]) + "] {}; % lip");
        if (values)
            output.println("\\draw (0.5,1.5) node {" + stringFormat(cells[2]) + "}; % lip");
        output.println("\\draw (1.,2.) node[diamond" + colorFormat(cells[6]) + "] {}; %li");
        if (values)
            output.println("\\draw (1.,2.) node {" + stringFormat(cells[6]) + "}; %li");
        output.println("\\draw (-0.5,-0.5) node[diamond" + colorFormat(cells[9]) + "] {}; % ip");
        if (values)
            output.println("\\draw (-0.5,-0.5) node {" + stringFormat(cells[9]) + "}; % ip");
        output.println("\\draw (0,0) node[diamond" + colorFormat(cells[12]) + "] {}; %p");
        if (values)
            output.println("\\draw (0,0) node {" + stringFormat(cells[12]) + "}; %p");
        output.println("\\draw (.5,.5) node[diamond" + colorFormat(cells[3]) + "] {}; % lph");
        if (values)
            output.println("\\draw (.5,.5) node {" + stringFormat(cells[3]) + "}; % lph");
        output.println("\\draw (1.,1.) node[diamond" + colorFormat(cells[0]) + "] {}; % liph");
        if (values)
            output.println("\\draw (1.,1.) node {" + stringFormat(cells[0]) + "}; % liph");
        output.println("\\draw (1.5,1.5) node[diamond" + colorFormat(cells[4]) + "] {}; %hil");
        if (values)
            output.println("\\draw (1.5,1.5) node {" + stringFormat(cells[4]) + "}; %hil");
        output.println("\\draw (2.,2.) node[diamond" + colorFormat(cells[14]) + "] {}; %i");
        if (values)
            output.println("\\draw (2.,2.) node {" + stringFormat(cells[14]) + "}; %i");
        output.println("\\draw (2.,1.) node[diamond" + colorFormat(cells[10]) + "] {}; % hi");
        if (values)
            output.println("\\draw (2.,1.) node {" + stringFormat(cells[10]) + "}; % hi");
        output.println("\\draw (1.5,0.5) node[diamond" + colorFormat(cells[1]) + "] {}; % phi");
        if (values)
            output.println("\\draw (1.5,0.5) node {" + stringFormat(cells[1]) + "}; % phi");
        output.println("\\draw (1.,0) node[diamond" + colorFormat(cells[8]) + "] {}; % ph");
        if (values)
            output.println("\\draw (1.,0) node {" + stringFormat(cells[8]) + "}; % ph");
        output.println("\\draw (2.,0) node[diamond" + colorFormat(cells[13]) + "] {}; % h");
        if (values)
            output.println("\\draw (2.,0) node {" + stringFormat(cells[13]) + "}; % h");
        output.println("\\draw (2.5,-0.5) node[diamond" + colorFormat(cells[7]) + "] {}; % hl");
        if (values)
            output.println("\\draw (2.5,-0.5) node {" + stringFormat(cells[7]) + "}; % hl");

        output.println("\\end{scope}");

        output.println("\\end{tikzpicture} ");
        output.println("\\caption{" + algo + " evaluation on F-measure (the darkest the best).}\\label{fig:diag"
                + algo + "}");
        output.println("\\end{center}");
        output.println("\\end{figure}");
    }

    public void printTSV(double[][] result) {
    }

    public String stringFormat(double f) {
        String result;
        // JE: Must add the test is the value is Not a number, print NaN.
        if (f != f)
            result = "N";
        else {
            int tmp = (int) (f * 100);
            int dec = tmp % 100;
            if ((int) (f * 1000) % 10 >= 5)
                dec++;
            if (tmp >= 100 || dec >= 100)
                result = "1.0";
            else {
                result = ".";
                if (dec < 10)
                    result = result + "0";
                result = result + dec;
            }
        }
        return result;
    }

    public double getMeasure(PRecEvaluator evaluator) {
        if (measure == 1)
            return evaluator.getPrecision();
        if (measure == 2)
            return evaluator.getRecall();
        if (measure == 3)
            return evaluator.getOverall();
        return evaluator.getFmeasure();
    }

    public String colorFormat(double f) {
        if (color == null)
            return "";
        else
            return ",fill=" + color + "!" + (int) (f * 100);
    }

    public void usage() {
        usage("java " + this.getClass().getName()
                + " [options]\nDisplays matcher results in a topological display");
    }
}