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