/*********************************************************************** This file is part of KEEL-software, the Data Mining tool for regression, classification, clustering, pattern mining and so on. Copyright (C) 2004-2010 F. Herrera (herrera@decsai.ugr.es) L. S�nchez (luciano@uniovi.es) J. Alcal�-Fdez (jalcala@decsai.ugr.es) S. Garc�a (sglopez@ujaen.es) A. Fern�ndez (alberto.fernandez@ujaen.es) J. Luengo (julianlm@decsai.ugr.es) This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 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 General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/ **********************************************************************/ package keel.RunKeelTxtDocente; /** * <p> * @author Written by Juan Carlos Fernández and Pedro Antonio Gutiérrez and(University of Córdoba) 07/07/2009 * @version 1.0 * @since JDK1.5 * </p> */ import java.io.BufferedReader; import java.io.File; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.util.ArrayList; import java.util.Calendar; import java.util.Date; import java.util.List; import java.util.StringTokenizer; import keel.GraphInterKeel.experiments.EducationalDiscretizerReport; import keel.GraphInterKeel.experiments.EducationalFSReport; import keel.GraphInterKeel.experiments.EducationalISReport; import keel.GraphInterKeel.experiments.EducationalMethodReport; import org.jdom.Document; import org.jdom.Element; import org.jdom.JDOMException; import org.jdom.input.SAXBuilder; public class EducationalRunKeelTxt { /** * <p> * This class run a iteration of a experiment when the method doIterate() * is invoqued. successive invocations finalize the experiment. * isFinished() method return true if all partitions are completed * </p> */ ////////////////////////////////////////////////////// ////////////// properties ////////////////////////////////////////////////////// private Runtime rt; private Process proc; private List<Element> sentences; private List<Element> sentencesAux; private boolean stop; private boolean interrupted; private int i; private int nJobs = 0; private int countJobs = 0; private int contPart = 0; private int contPartReal = 0; private boolean nJobFinished = false; private int NumberofJobFinished = -1; // Number of sentences for each job (job) private List<Integer> partitionList = new ArrayList<Integer>(); private long timePartition; private String command; private List line; static final int CLASSIFICATION = 0; static final int REGRESSION = 1; private int tipoExp; private int tipoPartition; private String experimentName = null; // Number of total partitions included all jobs private int partitionnumber = 0; private boolean execExternalFinished = false; private boolean runFinishedAux = false; private String problemType = ""; private String configFileString = ""; ////////////////////////////////////////////////////// ////////////// constructor ////////////////////////////////////////////////////// public EducationalRunKeelTxt(int experimentType) // CLASSIFICATION = 0, REGRESSION = 1 or UNSUPERVISED = 2 { this.tipoExp = experimentType; rt = null; proc = null; sentences = new ArrayList<Element>(); sentencesAux = new ArrayList<Element>(); stop = false; interrupted = false; i = 0; timePartition = 0; command = ""; line = null; Document doc = new Document(); //Create the file "Runkeel.xml" try { SAXBuilder builder = new SAXBuilder (); doc = builder.build(new File("./experiment/scripts/RunKeel.xml")); } catch (JDOMException e) { e.printStackTrace(); System.out.println("Error JDOM\n"); } catch (Exception e) { e.printStackTrace(); System.out.println("Execution XML file not found"); } //Number of jobs nJobs = doc.getRootElement().getChildren().size(); for (int i=0; i<nJobs; i++) { int aux = ((Element)doc.getRootElement().getChildren().get(i)).getChildren().size(); partitionList.add(aux); } for(int i=0; i<nJobs; i++) { for(int j=0; j<partitionList.get(i); j++) { sentences.add( (Element) ((Element)doc.getRootElement().getChildren(). get(i)).getChildren().get(j) ); } } partitionnumber = sentences.size(); } ////////////////////////////////////////////////////// ////////////// methods ////////////////////////////////////////////////////// /** * <p> * This method run a partition and creates the report * when all partitions of the experiment are finished * </p< */ public synchronized void doIterate() { while (interrupted == true && stop == false) { try { wait(); } catch (InterruptedException e) { } } //interrumpido = false; if(i < sentences.size() && stop == false) //else: All partitions have been finished { command = ""; line = ((Element)sentences.get(i)).getChildren(); //Caught the complet command in a String, except algorithmType and seed (line.size() -2) for (int j=0; j<line.size()-2; j++) { command += ((Element)line.get(j)).getText() + " "; } problemType = ((Element)line.get(line.size()-2)).getText(); Date now = Calendar.getInstance().getTime(); System.out.println("*** BEGIN OF EXPERIMENT " + now + "\n"); System.out.print("\nExecuting: " + command); StreamGobbler errorGobbler; StreamGobbler outputGobbler; //Initial time, in milliseconds timePartition = System.currentTimeMillis(); try { rt = Runtime.getRuntime(); proc = rt.exec(command); errorGobbler = new StreamGobbler(proc.getErrorStream(),"ERROR"); outputGobbler = new StreamGobbler(proc.getInputStream(),"OUTPUT"); errorGobbler.start(); outputGobbler.start(); //wait to finish the extern process int exitVal = proc.waitFor(); execExternalFinished = true; now = Calendar.getInstance().getTime(); //Final time, in milliseconds timePartition = System.currentTimeMillis()- timePartition; System.out.println("ExitValue: " + exitVal); if(nJobFinished==true) // Inicializacion de las sentencias del nuevo trabajo sentencesAux = new ArrayList<Element>(); if (exitVal != 0) //Error { System.out.println("\n*** ERROR - END OF EXPERIMENT!! " + now + "\n"); } else //Experiment correct.Increase i { sentencesAux.add(sentences.get(i)); System.out.println("\n*** END OF EXPERIMENT " + now + "\n"); i++; if(contPart == 0) contPartReal = 0; contPart++; contPartReal = contPart; nJobFinished = false; //Job completed if (contPart==(int)partitionList.get(countJobs))//sentencias.size()) { if (problemType.equals("Method") == true) { EducationalMethodReport inf = new EducationalMethodReport((ArrayList<Element>) sentencesAux, tipoExp); inf.running(); } else if (problemType.equals("Preprocess-D") == true) { EducationalDiscretizerReport inf = new EducationalDiscretizerReport((ArrayList<Element>) sentencesAux, tipoExp); inf.running(); } else if (problemType.equals("Preprocess-TSS") == true) { EducationalISReport inf = new EducationalISReport((ArrayList<Element>) sentencesAux, tipoExp); inf.running(); } else if (problemType.equals("Preprocess-FS") == true) { EducationalFSReport inf = new EducationalFSReport((ArrayList<Element>) sentencesAux, tipoExp); inf.running(); } nJobFinished = true; NumberofJobFinished = countJobs; //It may be put in "if". Now all are methods contPart = 0; // Se pasa el siguiente trabajo que haya en RunKeel.xml countJobs++; // Se acabaron todos los trabajos if (i==sentences.size()) { stop = true; } } } } catch (Throwable t) { t.printStackTrace(); } } else //All partitions have finished { stop = true; } execExternalFinished = false; } /** * <p> * Return the Report File Path * </p> * @return String Report File Path */ public String obtainReportFilePath() { int posCadenaScriptFile = 0; String pathString = ""; StringTokenizer st = null; String vectorCadenas[] = null; //String rutas[] = null; int counter = 0, tamanio = 0; List line; line = ((Element)sentencesAux.get(0)).getChildren(); posCadenaScriptFile = line.size() -3; pathString = ((Element)line.get(posCadenaScriptFile)).getText(); st = new StringTokenizer(pathString,"/"); tamanio = st.countTokens(); vectorCadenas = new String[tamanio]; while (st.hasMoreTokens()) { vectorCadenas[counter] = new String(st.nextToken()); counter++; } pathString = "./experiment/results/"; for (int j=3; j< (vectorCadenas.length)-1; j++) pathString = pathString + vectorCadenas[j] + "/" ; //Path file report.txt return (pathString + "report.txt"); } /** * * <p> * Return the path for PartitionDat File * Method to calculate name of partition (training or test) * The config.txt file is inspected * </p> * @param countPartitions Counter for partitions * @return String path for PartitionDat File */ public String calculatePartitionDatNameFile(int countPartitions) { FileReader fr = null; BufferedReader br = null; String partitionDatNameFile = ""; StringTokenizer st = null; configFileString = this.calculateFileConfigPath(countPartitions); //File config.txt. Read training file and test file try { fr = new FileReader(this.configFileString); br = new BufferedReader(fr); } catch (FileNotFoundException e) { e.printStackTrace(); } String cad = ""; try { cad = br.readLine(); } catch (IOException e) { e.printStackTrace(); } while (cad!=null) { if (cad.startsWith("inputData") == true) { st = new StringTokenizer(cad,"\""); st.nextToken(); String aux = st.nextToken(); st = new StringTokenizer(aux,"/"); while (st.hasMoreTokens()) partitionDatNameFile = st.nextToken(); break; } try { cad = br.readLine(); } catch (IOException e) { e.printStackTrace(); } } try { br.close(); } catch (IOException e) { e.printStackTrace(); } return partitionDatNameFile; } /** * <p> * Method to calculate config.txt path. * </p> * @param pos position for FileConfigPath * @return String with the FileConfigPath */ @SuppressWarnings("unused") private String calculateFileConfigPath(int pos) { int posCadenaScriptFile = 0; String StringPath = ""; //Configuration File "pos" configxxx.txt List linea = ((Element)sentences.get(pos)).getChildren(); //posCadenaScriptFile = linea.size() -2; posCadenaScriptFile = linea.size() -3; StringPath = ((Element)linea.get(posCadenaScriptFile)).getText(); //Path File Config.txt return StringPath; } /** * <p> * Get the experiment that is running * </p> * @return running experiment */ public String getActualNameExperiment() { int posCadenaScriptFile = 0; String stringPath = ""; StringTokenizer st = null; String vectorCadenas[] = null; //String rutas[] = null; int counter = 0, tamanio = 0; List line; line = ((Element)sentencesAux.get(0)).getChildren(); posCadenaScriptFile = line.size() -3; stringPath = ((Element)line.get(posCadenaScriptFile)).getText(); st = new StringTokenizer(stringPath,"/"); tamanio = st.countTokens(); vectorCadenas = new String[tamanio]; while (st.hasMoreTokens()) { vectorCadenas[counter] = new String(st.nextToken()); counter++; } this.experimentName = vectorCadenas[3]; return this.experimentName; } /** * <p> * Method to calculate seed for actual partition * The config.txt file is inspected * </p> */ public String calculateActualSeed() { FileReader fr = null; BufferedReader br = null; String seed = ""; StringTokenizer st = null; boolean isSeed = false; //File config.txt. Read training file and test file try { fr = new FileReader(configFileString); br = new BufferedReader(fr); } catch (FileNotFoundException e) { e.printStackTrace(); } String cad = ""; try { cad = br.readLine(); } catch (IOException e) { e.printStackTrace(); } while (cad!=null) { if (cad.startsWith("seed") == true) { st = new StringTokenizer(cad,"="); st.nextToken(); seed = st.nextToken(); isSeed = true; break; } try { cad = br.readLine(); } catch (IOException e) { e.printStackTrace(); } } try { br.close(); } catch (IOException e) { e.printStackTrace(); } if(isSeed==true) return seed; else return "none"; } /** * <p> * This method is used for stop the experiment. * Not Kill the experiment and the partitions, * "suspend" the experiment * </p> */ public void stopProcess() { interrupted = true; proc.destroy(); if (execExternalFinished == true) runFinishedAux = true; else runFinishedAux = false; } /** * <p> * This method is used for to kill the experiment. * Kill the experiment and the partitions. * </p> */ public void killProcess() { //The next time the thread don�t invoque to doIterate(), //isFinished() return true stop = true; interrupted = true; proc.destroy(); this.miNotify(); } /** * <p> * Reanude the actual thread * </p> */ private synchronized void miNotify() { notify(); } /** * <p> * To invoque previously stopProcess. Reanude the * experiment in the partition i * </p> */ public synchronized void reanudeProcess() { interrupted = false; notify(); } ////////////////////////////////////////////////////// ////////////// get methods ////////////////////////////////////////////////////// /** * <p> * This method return the state of the experiment. * True, all partitions finished * False, partitions not finished * </p> * @return boolean Has finished? */ public boolean isFinished() { return stop; } /** * <p> * This methos return if a partition is interrupted * for the extern user * True, interrupted * False, no interrupted * </p> * @return Is interrupted? */ public boolean isInterrumpted() { return interrupted; } /** * <p> * This method return a control variable used * for GUI EjecucionDocente. It controls the * conclusion of the extern process * True if method doIterate() han finished * <p> * @return boolean Has finished? */ public boolean getexecExternoFinalizado() { return runFinishedAux; } /** * <p> * This method return number of th actual partition * </p> * @return int Number of partition */ public int getNParticion() { return i; } /** * <p> * Get number partition of a experiment (not global partition) * </p> * @return number of partition in a experiement */ public int getNRealPartition() { return contPartReal; } /** * <p> * This method return the compute time for a partition * </p> * @return double Time of partition */ public double getPartitionTime() { //run time of partition, in milloseconds return (double)(timePartition/1000.0); } /** * <p> * This methos return the partition total number * </p> * @return int Total Partitions */ public int getTotalPartitions() { return partitionnumber; } /** * <p> * This methos get type problem, classification or regression * </p> * @return int Type of Experiment */ public int getExperimentType() { return tipoExp; } /** * Return type of problem * @return Type of problem */ public String getProblemType() { return this.problemType; } /** * <p> * This methos get type partitions, k-fold or 5x2 * </p> * @return int type of partition */ public int getPartitionType() { return tipoPartition; } /** * <p> * This method get number of jobs * </p> * @return int number of jobs */ public int getnJobs() { return nJobs; } /** * <p> * Get the number of Jobs that is finished actually * </p> * @return number of job finished actually */ public int getNumberofJobFinished() { return NumberofJobFinished; } /** * <p> * Return true if a job "n" has finished * </p> * @return A job "n" has finished */ public boolean nJobFinished() { return nJobFinished; } /** * <p> * Return the Actual jobs Sentences * </p> * @return List with the actual jobs Sentences */ public List<Element> getActualJobSentences() { return this.sentencesAux; } ////////////////////////////////////////////////////// ////////////// set methods ////////////////////////////////////////////////////// /** * <p> * This method set type problem, classification or regression * </p> * @param tipo Type of Experiment */ public void setExperimenttype(int tipo) { tipoExp = tipo; } /** * <p> * This methos set type partitions, k-fold or 5x2 * * PK = 0 P5X2 = 1; * </p> * @param tipo Tipe of partition */ public void setpartitionType(int tipo) { tipoPartition = tipo; //Actually the experiments has 10 partitions //2 -> training and test /* int tam = (sentencias.size())*2; rutasFicheros = new String[tam]; for (int i=0; i<tam; i++) rutasFicheros[i] = new String(); */ } /******************************************************************************** ** Internal class for output of extern process. Buffer control *********************************************************************************/ class StreamGobbler extends Thread { protected InputStream is; protected String type; public StreamGobbler(InputStream is, String type) { this.is = is; this.type = type; } public void run() { try { InputStreamReader isr = new InputStreamReader(is); BufferedReader br = new BufferedReader(isr); String line = null; while ( (line = br.readLine()) != null) { System.out.println(line); line = null; } isr.close(); br.close(); } catch (IOException ioe) { ioe.printStackTrace(); } } } }