/*
Copyright (C) 2011 Diego Darriba, David Posada
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, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package es.uvigo.darwin.jmodeltest.observer;
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutput;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.util.Locale;
import java.util.Observable;
import java.util.Observer;
import es.uvigo.darwin.jmodeltest.ApplicationOptions;
import es.uvigo.darwin.jmodeltest.ModelTest;
import es.uvigo.darwin.jmodeltest.ModelTestConfiguration;
import es.uvigo.darwin.jmodeltest.io.TextOutputStream;
import es.uvigo.darwin.jmodeltest.model.Model;
import es.uvigo.darwin.jmodeltest.utilities.Utilities;
public class ConsoleProgressObserver implements Observer {
private TextOutputStream stream;
/** Timer for calculate the elapsed time **/
private long startTime;
private int totalModels;
private int completedModels = 0;
private boolean threadScheduling;
private ApplicationOptions options;
public ConsoleProgressObserver(ApplicationOptions options) {
this.startTime = System.currentTimeMillis();
this.stream = ModelTest.getMainConsole();
this.threadScheduling = options.threadScheduling;
this.options=options;
}
@Override
@SuppressWarnings("fallthrough")
public synchronized void update(Observable o, Object arg) {
if (arg != null) {
ProgressInfo info = (ProgressInfo) arg;
switch (info.getType()) {
case ProgressInfo.BASE_TREE_INIT:
stream.println(" ");
stream.println("Estimating a BIONJ-JC tree ... ");
break;
case ProgressInfo.BASE_TREE_COMPUTED:
stream.println("OK");
stream.println(info.getModel().getName() + " tree: "
+ info.getModel().getTreeString());
break;
case ProgressInfo.OPTIMIZATION_INIT:
this.totalModels = options.getNumModels();
stream.println(" ");stream.println(" ");
stream.println("::Progress::");
stream.println(" ");
stream.println("Model \t\t Exec. Time \t Total Time \t -lnL");
stream.println("-------------------------------------------------------------------------");
break;
case ProgressInfo.GTR_OPTIMIZATION_INIT:
stream.println("[Heuristic search] Optimizing " + info.getModel().getName() + " model");
break;
case ProgressInfo.GTR_OPTIMIZATION_COMPLETED:
stream.println("[Heuristic search] Starting model filtering");
break;
case ProgressInfo.SINGLE_OPTIMIZATION_INIT:
break;
case ProgressInfo.SINGLE_OPTIMIZATION_COMPLETED:
completedModels++;
stream.print(info.getModel().getName() + "\t");
double modelLnL;
if (info.getValue() == ProgressInfo.VALUE_REGULAR_OPTIMIZATION) {
modelLnL = info.getModel().getLnL();
} else {
modelLnL = info.getModel().getLnLIgnoringGaps();
}
if (info.getModel().getName().length()<8)
stream.print("\t");
stream.print(info.getMessage() + "\t"
+ Utilities.calculateRuntime(startTime, System.currentTimeMillis()) + "\t"
+ String.format(Locale.ENGLISH, "%13.4f", modelLnL));
if (ModelTest.MPJ_RUN && threadScheduling) {
stream.println(" ");
} else {
if (info.isHeuristicSearch() && info.getValue() == ProgressInfo.VALUE_REGULAR_OPTIMIZATION) {
stream.println("\t ["+info.getHeuristicStage()+"/6] (" + completedModels + "/" + info.getNumModelsInStage() + ")");
if (completedModels == info.getNumModelsInStage()) {
completedModels = 0;
}
} else {
stream.println("\t (" + completedModels + "/" + totalModels + ")");
}
}
if (ModelTestConfiguration.isCkpEnabled()) {
try {
OutputStream file = new FileOutputStream(
options.getCkpFile());
OutputStream buffer = new BufferedOutputStream(file);
ObjectOutput output = new ObjectOutputStream(buffer);
output.writeObject(ModelTest.getCandidateModels());
output.close();
} catch (IOException ex) {
System.err.println("Cannot perform output.");
}
}
break;
case ProgressInfo.REOPTIMIZATION_INIT:
this.totalModels = info.getValue();
this.completedModels = 0;
this.startTime = System.currentTimeMillis();
stream.println(" ");stream.println(" ");
stream.println("Some models should be reoptimized for checking lnL against the unconstrained likelihood");
stream.println(" ");
stream.println("Model \t\t Exec. Time \t Total Time\t-lnL w/o gaps");
stream.println("-------------------------------------------------------------------------");
break;
case ProgressInfo.REOPTIMIZATION_COMPLETED:
stream.println(" ");
stream.println(" Unconstrained -lnL = " + options.getUnconstrainedLnL());
stream.println(" Number of patterns found = " + options.getNumPatterns());
stream.println(" ");
break;
case ProgressInfo.INTERRUPTED:
stream.println(" ");
stream.println("Computation of likelihood scores discontinued ...");
break;
case ProgressInfo.ERROR:
stream.println(info.getMessage());
stream.println(" ");
stream.println("Computation of likelihood scores discontinued ...");
System.exit(-1);
break;
case ProgressInfo.ERROR_BINARY_NOEXISTS:
stream.println("");
stream.println("ERROR: PhyML binary does not exists: " + info.getMessage());
stream.println("");
ModelTest.finalize(ProgressInfo.ERROR_BINARY_NOEXISTS);
break;
case ProgressInfo.ERROR_BINARY_NOEXECUTE:
stream.println("");
stream.println("ERROR: PhyML binary does not have execution permission: " + info.getMessage());
stream.println("");
ModelTest.finalize(ProgressInfo.ERROR_BINARY_NOEXECUTE);
break;
case ProgressInfo.OPTIMIZATION_COMPLETED_OK:
stream.println(" ");
for (Model model : ModelTest.getCandidateModels()) {
model.print(ModelTest.getMainConsole());
ModelTest.getMainConsole().println(" ");
}
if (options.isAmbiguous()) {
stream.println(" Best-fit models should be reoptimized for comparison with unconstrained likelihood");
} else {
stream.println(" Unconstrained -lnL = " + options.getUnconstrainedLnL());
stream.println(" Number of patterns found = " + options.getNumPatterns());
}
stream.println(" ");
stream.println("Computation of likelihood scores completed. It took "
+ Utilities.calculateRuntime(startTime,
System.currentTimeMillis()) + ".");
stream.println(" ");
// continue
case ProgressInfo.OPTIMIZATION_COMPLETED_INTERRUPTED:
// dispose
break;
}
}
}
}