From b0d7974c18ea8625b8b5d0599f87165a49351340 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Euzenat?= <Jerome.Euzenat@inria.fr> Date: Mon, 27 Nov 2006 23:32:07 +0000 Subject: [PATCH] - Displays diagrams of performances of algorithms depending on the problem --- .../exmo/align/util/GroupOutput.java | 363 ++++++++++++++++++ 1 file changed, 363 insertions(+) create mode 100644 src/fr/inrialpes/exmo/align/util/GroupOutput.java diff --git a/src/fr/inrialpes/exmo/align/util/GroupOutput.java b/src/fr/inrialpes/exmo/align/util/GroupOutput.java new file mode 100644 index 00000000..78cfe4ec --- /dev/null +++ b/src/fr/inrialpes/exmo/align/util/GroupOutput.java @@ -0,0 +1,363 @@ +/* + * $Id$ + * + * Copyright (C) 2003 The University of Manchester + * Copyright (C) 2003 The University of Karlsruhe + * Copyright (C) 2003-2006, INRIA Rhône-Alpes + * Copyright (C) 2004, Université de Montréal + * + * 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.util; + +import org.semanticweb.owl.model.OWLOntology; + +import org.semanticweb.owl.align.Alignment; +import org.semanticweb.owl.align.AlignmentProcess; +import org.semanticweb.owl.align.AlignmentVisitor; +import org.semanticweb.owl.align.Parameters; +import org.semanticweb.owl.align.Evaluator; + +import fr.inrialpes.exmo.align.impl.BasicAlignment; +import fr.inrialpes.exmo.align.impl.BasicParameters; +import fr.inrialpes.exmo.align.impl.eval.PRecEvaluator; + +import java.io.File; +import java.io.PrintStream; +import java.io.FileOutputStream; +import java.io.OutputStream; +import java.io.PrintWriter; +import java.io.BufferedWriter; +import java.io.OutputStreamWriter; +import java.net.URI; +import java.lang.Double; +import java.lang.Integer; +import java.util.Hashtable; +import java.util.Vector; +import java.util.Enumeration; +import java.util.StringTokenizer; + +import org.xml.sax.SAXException; + +import gnu.getopt.LongOpt; +import gnu.getopt.Getopt; + +import fr.inrialpes.exmo.align.parser.AlignmentParser; + +/** A basic class for synthesizing the alignment results of an algorithm by a + * precision recall graph. + * + * These graphs 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.GenPlot [options] + * </pre> + * + * where the options are: + * <pre> + * -o filename --output=filename + * -c --color + * -d debug --debug=level + * -l list of compared algorithms + * -t output --type=output: xml/tex/html/ascii + * </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$ + * </pre> + * + * @author Jérôme Euzenat + */ + +public class GroupOutput { + + 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 + Parameters params = null; + Vector listAlgo; + String fileNames = ""; + String outFile = null; + String type = "tex"; + String color = null; + int debug = 0; + Hashtable loaded = null; + PrintWriter output = null; + + public static void main(String[] args) { + try { new GroupOutput().run( args ); } + catch (Exception ex) { ex.printStackTrace(); }; + } + + public void run(String[] args) throws Exception { + LongOpt[] longopts = new LongOpt[8]; + loaded = new Hashtable(); + + longopts[0] = new LongOpt("help", LongOpt.NO_ARGUMENT, null, 'h'); + longopts[1] = new LongOpt("output", LongOpt.REQUIRED_ARGUMENT, null, 'o'); + longopts[2] = new LongOpt("color", LongOpt.OPTIONAL_ARGUMENT, null, 'c'); + longopts[3] = new LongOpt("type", LongOpt.REQUIRED_ARGUMENT, null, 't'); + longopts[4] = new LongOpt("debug", LongOpt.OPTIONAL_ARGUMENT, null, 'd'); + longopts[6] = new LongOpt("list", LongOpt.REQUIRED_ARGUMENT, null, 'l'); + + Getopt g = new Getopt("", args, "ho:c::d::l:t:", longopts); + int c; + String arg; + + while ((c = g.getopt()) != -1) { + switch (c) { + case 'h' : + usage(); + return; + case 'o' : + /* Write output here */ + outFile = g.getOptarg(); + break; + case 'c' : + /* Cell color */ + arg = g.getOptarg(); + if ( arg != null ) { + color = arg.trim(); + } else color = "blue"; + break; + case 't' : + /* Type of output (tex/tsv(/html/xml/ascii)) */ + type = g.getOptarg(); + break; + case 'l' : + /* List of filename */ + fileNames = g.getOptarg(); + break; + case 'd' : + /* Debug level */ + arg = g.getOptarg(); + if ( arg != null ) debug = Integer.parseInt(arg.trim()); + else debug = 4; + break; + } + } + + // JE: StringTokenizer is obsoleted in Java 1.4 in favor of split: to change + listAlgo = new Vector(); + StringTokenizer st = new StringTokenizer(fileNames,","); + while (st.hasMoreTokens()) { + listAlgo.add(st.nextToken()); + } + + params = new BasicParameters(); + if (debug > 0) params.setParameter("debug", new Integer(debug-1)); + + params.setParameter("step", new Integer(SIZE)); + + // Set output file + OutputStream stream; + if (outFile == null) { + stream = System.out; + } else { + stream = new FileOutputStream(outFile); + } + 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 ( Enumeration e = listAlgo.elements() ; e.hasMoreElements() ; ) { + String algo = (String)e.nextElement(); + if ( debug > 0 ) System.err.println("Algorithm: "+algo); + // type + if ( type.equals("tex") ) { + printPGFTeX( algo, iterateCells( algo ) ); + } else System.err.println("Flag -t "+type+" : not implemented yet"); + } + } + + 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 ){ + File dir = (new File(System.getProperty("user.dir"))); + double result = 0.0; + for ( int i=0; i<tests.length; i++ ){//size() or length + if ( debug > 1 ) System.err.println(" tests: "+tests[i]); + String prefix = dir.toURI().toString()+"/"+tests[i]+"/"; + PRecEvaluator evaluator = (PRecEvaluator)eval( prefix+"refalign.rdf", prefix+algo+".rdf"); + result = result + evaluator.getFmeasure(); + } + // Unload the ontologies. + try { + for ( Enumeration e = loaded.elements() ; e.hasMoreElements(); ){ + OWLOntology o = (OWLOntology)e.nextElement(); + o.getOWLConnection().notifyOntologyDeleted( o ); + } + } catch (Exception ex) { System.err.println(ex); }; + return (double)result/(double)tests.length; + } + + public Evaluator eval( String alignName1, String alignName2 ) { + Evaluator eval = null; + try { + int nextdebug; + if ( debug < 3 ) nextdebug = 0; + else nextdebug = debug - 3; + // Load alignments + AlignmentParser aparser1 = new AlignmentParser( nextdebug ); + Alignment align1 = aparser1.parse( alignName1, loaded ); + if ( debug > 2 ) System.err.println(" Alignment structure1 parsed"); + AlignmentParser aparser2 = new AlignmentParser( nextdebug ); + Alignment align2 = aparser2.parse( alignName2, loaded ); + if ( debug > 2 ) System.err.println(" Alignment structure2 parsed"); + // Create evaluator object + eval = new PRecEvaluator( align1, align2 ); + // Compare + params.setParameter( "debug", new Integer( nextdebug ) ); + eval.eval( params ) ; + } catch (Exception ex) { + // The returned value must be 0 + eval = new PRecEvaluator( (Alignment)null, (Alignment)null ); + ((PRecEvaluator)eval).init(); + System.err.println(ex); + } + 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("\\draw (-.5,2.) node[anchor=east] {labels};"); + output.println("\\draw (0,2.) node[diamond,minimum size=.5cm"+colorFormat(cells[11])+"] {"+stringFormat(cells[11])+"}; % l"); + output.println("\\draw (0,1.) node[diamond,minimum size=.5cm"+colorFormat(cells[5])+"] {"+stringFormat(cells[5])+"}; % lp"); + output.println("\\draw (0.5,1.5) node[diamond,minimum size=.5cm"+colorFormat(cells[2])+"] {"+stringFormat(cells[2])+"}; % lip"); + output.println("\\draw (1.,2.) node[diamond,minimum size=.5cm"+colorFormat(cells[6])+"] {"+stringFormat(cells[6])+"}; %li"); + output.println(""); + output.println("\\draw (-.5,0.) node[anchor=east] {properties};"); + output.println("\\draw (-0.5,-0.5) node[diamond,minimum size=.5cm"+colorFormat(cells[9])+"] {"+stringFormat(cells[9])+"}; % ip"); + output.println("\\draw (0,0) node[diamond,minimum size=.5cm"+colorFormat(cells[12])+"] {"+stringFormat(cells[12])+"}; %p"); + output.println("\\draw (.5,.5) node[diamond,minimum size=.5cm"+colorFormat(cells[3])+"] {"+stringFormat(cells[3])+"}; % lph"); + output.println("\\draw (1.,1.) node[diamond,minimum size=.5cm"+colorFormat(cells[0])+"] {"+stringFormat(cells[0])+"}; % liph"); + output.println("\\draw (1.5,1.5) node[diamond,minimum size=.5cm"+colorFormat(cells[4])+"] {"+stringFormat(cells[4])+"}; %hil"); + output.println("\\draw (2.,2.) node[diamond,minimum size=.5cm"+colorFormat(cells[14])+"] {"+stringFormat(cells[14])+"}; %i"); + output.println("\\draw (2.5,2.0) node[anchor=west] {instances};"); + output.println(""); + output.println("\\draw (2.,1.) node[diamond,minimum size=.5cm"+colorFormat(cells[10])+"] {"+stringFormat(cells[10])+"}; % hi"); + output.println("\\draw (1.5,0.5) node[diamond,minimum size=.5cm"+colorFormat(cells[1])+"] {"+stringFormat(cells[1])+"}; % phi"); + output.println("\\draw (1.,0) node[diamond,minimum size=.5cm"+colorFormat(cells[8])+"] {"+stringFormat(cells[8])+"}; % ph"); + output.println("\\draw (2.,0) node[diamond,minimum size=.5cm"+colorFormat(cells[13])+"] {"+stringFormat(cells[13])+"}; % h"); + output.println("\\draw (2.5,0.) node[anchor=west] {hierarchy};"); + output.println("\\draw (2.5,-0.5) node[diamond,minimum size=.5cm"+colorFormat(cells[7])+"] {"+stringFormat(cells[7])+"}; % hl"); + + + 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 String colorFormat(double f){ + if ( color == null ) return ""; + else return ",fill="+color+"!"+(int)(f*100); + } + + public void usage() { + System.out.println("usage: GenPlot [options]"); + System.out.println("options are:"); + System.out.println("\t--type=tsv|tex|(html|xml) -t tsv|tex|(html|xml)\tSpecifies the output format"); + System.out.println("\t--list=algo1,...,algon -l algo1,...,algon\tSequence of the filenames to consider"); + System.out.println("\t--color=color -c color\tSpecifies if the output must color even lines of the output"); + System.out.println("\t--debug[=n] -d [n]\t\tReport debug info at level n"); + System.out.println("\t--help -h\t\t\tPrint this message"); + } +} -- GitLab