diff --git a/moa/src/main/java/moa/classifiers/drift/AdaptiveClassifier.java b/moa/src/main/java/moa/classifiers/drift/AdaptiveClassifier.java new file mode 100644 index 000000000..4045bb91a --- /dev/null +++ b/moa/src/main/java/moa/classifiers/drift/AdaptiveClassifier.java @@ -0,0 +1,179 @@ +/* + * AdaptiveClassifier.java + * + * @author Isvani Frías-Blanco + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package moa.classifiers.drift; + +import com.yahoo.labs.samoa.instances.Instance; +import moa.classifiers.AbstractClassifier; +import moa.classifiers.Classifier; +import moa.classifiers.MultiClassClassifier; +import moa.core.Measurement; +import moa.options.ClassOption; + +/** + * + * @author Isvani Frías Blanco (ifriasb at hotmail dot com) + *

See details in:
Frías-Blanco, I., Verdecia-Cabrera, A., Ortiz-Díaz, A., & Carvalho, A. (2016, April). + * Fast adaptive stacking of ensembles. * In Proceedings of the 31st Annual ACM Symposium on Applied Computing + * (pp. 929-934). ACM.

+ */ + +public class AdaptiveClassifier extends AbstractClassifier implements MultiClassClassifier{ + + private static final long serialVersionUID = 1L; + + public ClassOption baseLearnerOption = new ClassOption("baseLearner", 'l', + "Classifier to train.", ClassifierWithChangeDetector.class, "ClassifierWithChangeDetector"); + + public Classifier mainClassifier, + alternativeClassifier; + + protected int driftStatus; + + protected int changeDetected = 0; + + protected int warningDetected = 0; + + public static final int DDM_INCONTROL_LEVEL = 0; + + public static final int DDM_WARNING_LEVEL = 1; + + public static final int DDM_OUTCONTROL_LEVEL = 2; + + @Override + public void resetLearningImpl() { + this.mainClassifier = ((Classifier) getPreparedClassOption(this.baseLearnerOption)).copy(); + this.alternativeClassifier = null; + this.trainingWeightSeenByModel = 0.0; + } + + public boolean isMoreAccurate(Classifier alt, Classifier main) { + if (alt == null) { + return false; + } + if (!(alt instanceof ClassifierWithChangeDetector && main instanceof ClassifierWithChangeDetector)) { + return false; + } + ClassifierWithChangeDetector aClassifier = (ClassifierWithChangeDetector) alt, + mClassifier = (ClassifierWithChangeDetector) main; + boolean flag = false; + double errorAlt = aClassifier.getEstimation(), + errorMain = mClassifier.getEstimation(); + double nAlt = aClassifier.getDelay(), + nMain = mClassifier.getDelay(); + double m = 1.0 / nAlt + 1.0 / nMain, + delta = 0.01, + bound = Math.sqrt(m * Math.log(2.0 / delta) / 2.0); + + if (errorMain > errorAlt + bound) { + flag = true; + } + + return flag; + } + + @Override + public void trainOnInstanceImpl(Instance inst) { + this.mainClassifier.trainOnInstance(inst); + if (this.alternativeClassifier != null) { + this.alternativeClassifier.trainOnInstance(inst); + } + // estimating the drift level + if (((ClassifierWithChangeDetector) this.mainClassifier).getChange()) { + this.driftStatus = DDM_OUTCONTROL_LEVEL; + } else if (((ClassifierWithChangeDetector) this.mainClassifier).getWarningZone()) { + this.driftStatus = DDM_WARNING_LEVEL; + } else { + this.driftStatus = DDM_INCONTROL_LEVEL; + } + /* new + if (((ClassifierWithChangeDetector) this.alternativeClassifier).getChange()) { + this.driftStatus = DDM_OUTCONTROL_LEVEL; + } + + if (isMoreAccurate(this.alternativeClassifier, this.mainClassifier)) { + this.mainClassifier = this.alternativeClassifier; + this.alternativeClassifier = null; + } + /* end new */ + switch (driftStatus) { + case DDM_WARNING_LEVEL: + if (this.alternativeClassifier == null) { + this.alternativeClassifier = ((Classifier) getPreparedClassOption(this.baseLearnerOption)).copy(); + this.alternativeClassifier.resetLearning(); + this.alternativeClassifier.trainOnInstance(inst); + } + break; + + case DDM_OUTCONTROL_LEVEL: + if (this.alternativeClassifier == null) { + this.alternativeClassifier = ((Classifier) getPreparedClassOption(this.baseLearnerOption)).copy(); + this.alternativeClassifier.resetLearning(); + this.alternativeClassifier.trainOnInstance(inst); + } + this.mainClassifier = this.alternativeClassifier; + this.alternativeClassifier = null; + break; + case DDM_INCONTROL_LEVEL: + this.alternativeClassifier = null; + break; + default: + } + } + + protected boolean isSignificantlyGreaterThan(double error1, int n1, double error2, int n2) { + if (n1 == 0 || n2 == 0) { + return false; + } + double m = 1.0 / n1 + 1.0 / n2, + size = 0.05; + return error1 - error2 > Math.sqrt(m / 2 * Math.log(1.0 / size)); + } + + @Override + protected Measurement[] getModelMeasurementsImpl() { + return this.mainClassifier.getModelMeasurements(); + } + + @Override + public void getModelDescription(StringBuilder out, int indent) { + ((AbstractClassifier) this.mainClassifier).getModelDescription(out, indent); + } + + @Override + public boolean isRandomizable() { + return true; + } + + @Override + public double[] getVotesForInstance(Instance inst) { + if (this.alternativeClassifier == null) { + return this.mainClassifier.getVotesForInstance(inst); + } else { + double combinedVote[] = new double[inst.numClasses()]; + double mainVotes[] = this.mainClassifier.getVotesForInstance(inst); + double alternativeVotes[] = this.alternativeClassifier.getVotesForInstance(inst); + for (int i = 0; i < combinedVote.length; i++) { + combinedVote[i] = (i < mainVotes.length ? mainVotes[i] : 0) + (i < alternativeVotes.length ? alternativeVotes[i] : 0); + } + return combinedVote; + } + } + public double getEstimation() { + return ((ClassifierWithChangeDetector)this.mainClassifier).driftDetectionMethod.getEstimation(); + } +} diff --git a/moa/src/main/java/moa/classifiers/drift/ClassifierWithChangeDetector.java b/moa/src/main/java/moa/classifiers/drift/ClassifierWithChangeDetector.java new file mode 100644 index 000000000..4d499f835 --- /dev/null +++ b/moa/src/main/java/moa/classifiers/drift/ClassifierWithChangeDetector.java @@ -0,0 +1,122 @@ +/* + * ClassifierWithChangeDetector.java + * + * @author Isvani Frías-Blanco + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package moa.classifiers.drift; + +import com.yahoo.labs.samoa.instances.Instance; +import java.util.Arrays; +import java.util.LinkedList; +import java.util.List; +import moa.classifiers.AbstractClassifier; +import moa.classifiers.Classifier; +import moa.classifiers.MultiClassClassifier; +import moa.classifiers.core.driftdetection.ChangeDetector; +import moa.core.Measurement; +import moa.options.ClassOption; +import weka.core.Utils; +/** + * + * @author Isvani Frías Blanco (ifriasb at hotmail dot com) + */ +public class ClassifierWithChangeDetector extends AbstractClassifier implements MultiClassClassifier{ + + private static final long serialVersionUID = 1L; + + public ClassOption baseLearnerOption = new ClassOption("baseLearner", 'l', + "Classifier to train.", Classifier.class, "bayes.NaiveBayes"); + + public ClassOption driftDetectionMethodOption = new ClassOption("driftDetectionMethod", 'd', + "Drift detection method to use.", ChangeDetector.class, "HDDM_A_Test"); + + public Classifier classifier; + + public ChangeDetector driftDetectionMethod; + + public ChangeDetector getDriftDetectionMethod() { + return driftDetectionMethod; + } + + @Override + public void resetLearningImpl() { + this.classifier = ((Classifier) getPreparedClassOption(this.baseLearnerOption)).copy(); + this.classifier.resetLearning(); + this.driftDetectionMethod = ((ChangeDetector) getPreparedClassOption(this.driftDetectionMethodOption)).copy(); + } + + @Override + public void trainOnInstanceImpl(Instance inst) { + boolean correctlyClassifies = this.classifier.correctlyClassifies(inst); + this.driftDetectionMethod.input(correctlyClassifies ? 0 : 1); + this.classifier.trainOnInstance(inst); + } + + @Override + protected Measurement[] getModelMeasurementsImpl() { + List measurementList = new LinkedList(); + measurementList.add(new Measurement("Error estimates", this.driftDetectionMethod.getEstimation())); + Measurement[] modelMeasurements = ((AbstractClassifier) this.classifier).getModelMeasurements(); + if (modelMeasurements != null) { + measurementList.addAll(Arrays.asList(modelMeasurements)); + } + return measurementList.toArray(new Measurement[measurementList.size()]); + } + + @Override + public void getModelDescription(StringBuilder out, int indent) { + ((AbstractClassifier) this.classifier).getModelDescription(out, indent); + } + + @Override + public boolean isRandomizable() { + return true; + } + + @Override + public double[] getVotesForInstance(Instance inst) { + double[] votes = this.classifier.getVotesForInstance(inst); + double distSum = Utils.sum(votes); + if (distSum * this.driftDetectionMethod.getEstimation() > 0.0) { + Utils.normalize(votes, distSum * this.driftDetectionMethod.getEstimation()); //Adding weight + } + return votes; + } + + public boolean getChange() { + return this.driftDetectionMethod.getChange(); + } + + public boolean getWarningZone() { + return this.driftDetectionMethod.getWarningZone(); + } + + public double getEstimation() { + return this.driftDetectionMethod.getEstimation(); + } + + public double getDelay() { + return this.driftDetectionMethod.getDelay(); + } + + public double[] getOutput() { + return this.driftDetectionMethod.getOutput(); + } + + public ChangeDetector changeDetectorCopy() { + return this.driftDetectionMethod.copy(); + } + +} diff --git a/moa/src/main/java/moa/classifiers/meta/OACEBag.java b/moa/src/main/java/moa/classifiers/meta/OACEBag.java new file mode 100644 index 000000000..b8a24f391 --- /dev/null +++ b/moa/src/main/java/moa/classifiers/meta/OACEBag.java @@ -0,0 +1,168 @@ +/* + * OACEBag.java + * + * @author Alberto Verdecia-Cabrera + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * + */ +package moa.classifiers.meta; + +import com.github.javacliparser.FlagOption; +import com.github.javacliparser.IntOption; +import com.yahoo.labs.samoa.instances.Instance; +import moa.classifiers.AbstractClassifier; +import moa.classifiers.Classifier; +import moa.classifiers.MultiClassClassifier; +import moa.classifiers.core.driftdetection.ChangeDetector; +import moa.core.DoubleVector; +import moa.core.Measurement; +import moa.core.MiscUtils; +import moa.options.ClassOption; + +/** + * + * @author Alberto Verdecia Cabrera (averdeciac at gmail dot com) + *

See details in:
Verdecia-Cabrera, Alberto, Isvani Frias Blanco, and André CPLF Carvalho. + * "An online adaptive classifier ensemble for mining non-stationary data streams." + * Intelligent Data Analysis 22.4 (2018): 787-806.

+ */ +public class OACEBag extends AbstractClassifier implements MultiClassClassifier{ + + private static final long serialVersionUID = 1L; + + public ClassOption baseLearnerOption = new ClassOption("baseLearner", 'b', + "Classifier to train.", Classifier.class, "drift.AdaptiveClassifier -l (ClassifierWithChangeDetector -d DDM)"); + + public IntOption ensembleSizeOption = new IntOption("ensembleSize", 's', + "The number of models in the bag.", 10, 1, Integer.MAX_VALUE); + public ClassOption driftDetectionMethodOption = new ClassOption("driftDetectionMethod", 'd', + "Drift detection method to use.", ChangeDetector.class, "DDM"); + public FlagOption deleteOption = new FlagOption("deleWorstCalssifier", 'i', + "Delete the worst classifier."); + + protected Classifier[] ensemble; + + protected ChangeDetector[] estimator; + + protected Classifier[] alternativeClassifier; + + protected ChangeDetector[] alternativeDetector; + + @Override + public void resetLearningImpl() { + this.ensemble = new Classifier[this.ensembleSizeOption.getValue()]; + this.alternativeClassifier = new Classifier[this.ensembleSizeOption.getValue()]; + this.alternativeDetector = new ChangeDetector[this.ensembleSizeOption.getValue()]; + this.estimator = new ChangeDetector[this.ensemble.length]; + + Classifier baseLearner = (Classifier) getPreparedClassOption(this.baseLearnerOption); + baseLearner.resetLearning(); + for (int i = 0; i < this.ensemble.length; i++) { + this.ensemble[i] = baseLearner.copy(); + this.alternativeClassifier[i] = null; + this.estimator[i] = ((ChangeDetector) getPreparedClassOption(this.driftDetectionMethodOption)).copy(); + this.alternativeDetector[i] = ((ChangeDetector) getPreparedClassOption(this.driftDetectionMethodOption)).copy(); + } + + } + + @Override + public void trainOnInstanceImpl(Instance inst) { + + boolean change = false; + for (int i = 0; i < this.ensemble.length; i++) { + int k = MiscUtils.poisson(1.0, this.classifierRandom); + if (k > 0) { + Instance weightedInst = (Instance) inst.copy(); + weightedInst.setWeight(inst.weight() * k); + this.ensemble[i].trainOnInstance(weightedInst); + } + boolean correctlyClassifies = this.ensemble[i].correctlyClassifies(inst); + + this.estimator[i].input(correctlyClassifies ? 0 : 1); + if (this.deleteOption.isSet()) { + if (this.estimator[i].getChange() == true) { + change = true; + } + } else if (this.estimator[i].getWarningZone() == true) { + if (this.alternativeClassifier[i] == null) { + this.alternativeClassifier[i] = ((Classifier) getPreparedClassOption(this.baseLearnerOption)).copy(); + this.alternativeClassifier[i].trainOnInstance(inst); + boolean correctlyClassifies1 = this.alternativeClassifier[i].correctlyClassifies(inst); + this.alternativeDetector[i].input(correctlyClassifies1 ? 0 : 1); + } + + } else if (this.estimator[i].getChange() == true) { + if (this.alternativeClassifier[i] != null) { + this.ensemble[i] = this.alternativeClassifier[i].copy(); + this.estimator[i] = (ChangeDetector) this.alternativeDetector[i].copy(); + this.alternativeClassifier[i] = null; + } else { + this.ensemble[i].resetLearning(); + + } + + } else { + this.alternativeClassifier[i] = null; + } + + } + if (change) { + double max = 0.0; + int imax = -1; + for (int i = 0; i < this.ensemble.length; i++) { + if (max < this.estimator[i].getEstimation()) { + max = this.estimator[i].getEstimation(); + imax = i; + } + } + if (imax != -1) { + this.ensemble[imax].resetLearning(); + this.estimator[imax] = ((ChangeDetector) getPreparedClassOption(this.driftDetectionMethodOption)).copy(); + } + } + + } + + @Override + protected Measurement[] getModelMeasurementsImpl() { + return new Measurement[]{new Measurement("ensemble size", + this.ensemble != null ? this.ensemble.length : 0)}; + } + + @Override + public void getModelDescription(StringBuilder out, int indent) { + // TODO Auto-generated method stub + } + + @Override + public double[] getVotesForInstance(Instance inst) { + DoubleVector combinedVote = new DoubleVector(); + for (int i = 0; i < this.ensemble.length; i++) { + DoubleVector vote = new DoubleVector(this.ensemble[i].getVotesForInstance(inst)); + if (vote.sumOfValues() > 0.0) { + vote.normalize(); + combinedVote.addValues(vote); + } + } + return combinedVote.getArrayRef(); + } + + @Override + public boolean isRandomizable() { + return true; + } + +} diff --git a/moa/src/main/java/moa/classifiers/meta/OACEBoost.java b/moa/src/main/java/moa/classifiers/meta/OACEBoost.java new file mode 100644 index 000000000..a63e27402 --- /dev/null +++ b/moa/src/main/java/moa/classifiers/meta/OACEBoost.java @@ -0,0 +1,198 @@ +/* + * OACEBoost.java + * + * @author Alberto Verdecia-Cabrera + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * + */ +package moa.classifiers.meta; + +import com.github.javacliparser.FlagOption; +import com.github.javacliparser.IntOption; +import com.yahoo.labs.samoa.instances.Instance; +import moa.classifiers.AbstractClassifier; +import moa.classifiers.Classifier; +import moa.classifiers.MultiClassClassifier; +import moa.classifiers.core.driftdetection.ChangeDetector; +import moa.core.DoubleVector; +import moa.core.Measurement; +import moa.core.MiscUtils; +import moa.options.ClassOption; + + +/** + * + * @author Alberto Verdecia Cabrera (averdeciac at gmail dot com) + *

See details in:
Verdecia-Cabrera, Alberto, Isvani Frias Blanco, and André CPLF Carvalho. + * "An online adaptive classifier ensemble for mining non-stationary data streams." + * Intelligent Data Analysis 22.4 (2018): 787-806.

+ */ +public class OACEBoost extends AbstractClassifier implements MultiClassClassifier{ + + public ClassOption baseLearnerOption = new ClassOption("baseLearner", 'b', + "Classifier to train.", Classifier.class, "drift.AdaptiveClassifier"); + + public IntOption ensembleSizeOption = new IntOption("ensembleSize", 's', + "The number of models in the bag.", 10, 1, Integer.MAX_VALUE); + public ClassOption driftDetectionMethodOption = new ClassOption("driftDetectionMethod", 'd', + "Drift detection method to use.", ChangeDetector.class, "HDDM_A_Test"); + public FlagOption deleteOption = new FlagOption("deleWorstCalssifier", 'i', + "Delete the worst classifier."); + + protected Classifier[] ensemble; + + protected ChangeDetector[] estimator; + + protected Classifier[] alternativeClassifier; + + protected ChangeDetector[] alternativeDetector; + protected double[] scms; + + protected double[] swms; + + @Override + public void resetLearningImpl() { + + this.ensemble = new Classifier[this.ensembleSizeOption.getValue()]; + this.alternativeClassifier = new Classifier[this.ensembleSizeOption.getValue()]; + this.alternativeDetector = new ChangeDetector[this.ensembleSizeOption.getValue()]; + this.estimator = new ChangeDetector[this.ensemble.length]; + + Classifier baseLearner = (Classifier) getPreparedClassOption(this.baseLearnerOption); + baseLearner.resetLearning(); + for (int i = 0; i < this.ensemble.length; i++) { + this.ensemble[i] = baseLearner.copy(); + this.alternativeClassifier[i] = null; + this.estimator[i] = ((ChangeDetector) getPreparedClassOption(this.driftDetectionMethodOption)).copy();; + this.alternativeDetector[i] = ((ChangeDetector) getPreparedClassOption(this.driftDetectionMethodOption)).copy(); + } + this.scms = new double[this.ensemble.length]; + this.swms = new double[this.ensemble.length]; + + } + @Override + public void trainOnInstanceImpl(Instance inst) { + + double lambda_d = 1.0; + boolean change = false; + for (int i = 0; i < this.ensemble.length; i++) { + int k = MiscUtils.poisson(lambda_d, this.classifierRandom); + if (k > 0) { + Instance weightedInst = (Instance) inst.copy(); + weightedInst.setWeight(inst.weight() * k); + this.ensemble[i].trainOnInstance(weightedInst); + } + boolean correctlyClassifies = this.ensemble[i].correctlyClassifies(inst); + if (correctlyClassifies) { + this.scms[i] += lambda_d; + lambda_d *= this.trainingWeightSeenByModel / (2 * this.scms[i]); + } else { + this.swms[i] += lambda_d; + lambda_d *= this.trainingWeightSeenByModel / (2 * this.swms[i]); + } + this.estimator[i].input(correctlyClassifies ? 0 : 1); + if (this.deleteOption.isSet()) { + if (this.estimator[i].getChange() == true) { + change = true; + } + } else{ + if (this.estimator[i].getWarningZone() == true) { + if (this.alternativeClassifier[i] == null) { + this.alternativeClassifier[i] = ((Classifier) getPreparedClassOption(this.baseLearnerOption)).copy(); + this.alternativeClassifier[i].trainOnInstance(inst); + boolean correctlyClassifies1 = this.alternativeClassifier[i].correctlyClassifies(inst); + this.alternativeDetector[i].input(correctlyClassifies1 ? 0 : 1); + } + + } else if (this.estimator[i].getChange() == true) { + if (this.alternativeClassifier[i] != null) { + if (this.estimator[i].getEstimation() < this.alternativeDetector[i].getEstimation()) { + this.ensemble[i] = this.alternativeClassifier[i].copy(); + this.estimator[i] = (ChangeDetector) this.alternativeDetector[i].copy(); + } + this.alternativeClassifier[i] = null; + } else { + this.ensemble[i].resetLearning(); /*= ((Classifier) getPreparedClassOption(this.baseLearnerOption)).copy();*/ + + this.estimator[i] = (ChangeDetector) this.alternativeDetector[i].copy(); + } + + } else { + this.alternativeClassifier[i] = null; + } + } + } + if (change) { + double max = 0.0; + int imax = -1; + for (int i = 0; i < this.ensemble.length; i++) { + if (max < this.estimator[i].getEstimation()) { + max = this.estimator[i].getEstimation(); + imax = i; + } + } + if (imax != -1) { + this.ensemble[imax].resetLearning(); + this.estimator[imax] = ((ChangeDetector) getPreparedClassOption(this.driftDetectionMethodOption)).copy(); + } + + } + + } + @Override + protected Measurement[] getModelMeasurementsImpl() { + return new Measurement[]{new Measurement("ensemble size", + this.ensemble != null ? this.ensemble.length : 0)}; + } + + @Override + public void getModelDescription(StringBuilder out, int indent) { + // TODO Auto-generated method stub + } + + protected double getEnsembleMemberWeight(int i) { + double em = this.swms[i] / (this.scms[i] + this.swms[i]); + if ((em == 0.0) || (em > 0.5)) { + return 0.0; + } + double Bm = em / (1.0 - em); + return Math.log(1.0 / Bm); + + } + + @Override + public double[] getVotesForInstance(Instance inst) { + DoubleVector combinedVote = new DoubleVector(); + for (int i = 0; i < this.ensemble.length; i++) { + double memberWeight = getEnsembleMemberWeight(i); + if (memberWeight > 0.0) { + DoubleVector vote = new DoubleVector(this.ensemble[i].getVotesForInstance(inst)); + if (vote.sumOfValues() > 0.0) { + vote.normalize(); + vote.scaleValues(memberWeight); + combinedVote.addValues(vote); + } + } else { + break; + } + } + return combinedVote.getArrayRef(); + } + + @Override + public boolean isRandomizable() { + return true; + } +} diff --git a/moa/src/main/java/moa/gui/GUIDefaults.java b/moa/src/main/java/moa/gui/GUIDefaults.java index 5ff90ed57..ee4088542 100644 --- a/moa/src/main/java/moa/gui/GUIDefaults.java +++ b/moa/src/main/java/moa/gui/GUIDefaults.java @@ -136,7 +136,7 @@ public static String[] getTabs() { String tabs; // read and split on comma - tabs = get("Tabs", "moa.gui.ClassificationTabPanel,moa.gui.RegressionTabPanel,moa.gui.MultiTargetTabPanel,moa.gui.clustertab.ClusteringTabPanel,moa.gui.outliertab.OutlierTabPanel,moa.gui.ConceptDriftTabPanel"); + tabs = get("Tabs", "moa.gui.ClassificationTabPanel,moa.gui.RegressionTabPanel,moa.gui.MultiLabelTabPanel,moa.gui.MultiTargetTabPanel,moa.gui.clustertab.ClusteringTabPanel,moa.gui.outliertab.OutlierTabPanel,moa.gui.ConceptDriftTabPanel,moa.gui.ALTabPanel,moa.gui.AuxiliarTabPanel,moa.gui.experimentertab.ExperimenterTabPanel"); result = tabs.split(","); return result; diff --git a/moa/src/main/java/moa/gui/experimentertab/Algorithm.java b/moa/src/main/java/moa/gui/experimentertab/Algorithm.java new file mode 100644 index 000000000..b15dbbfe6 --- /dev/null +++ b/moa/src/main/java/moa/gui/experimentertab/Algorithm.java @@ -0,0 +1,177 @@ +/* + * Algorithm.java + * Copyright (C) 2007 University of Waikato, Hamilton, New Zealand + * @author Alberto Verdecia Cabrera (averdeciac@gmail.com) + * + * 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 . + * + */ +package moa.gui.experimentertab; + +import java.io.BufferedReader; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.logging.Level; +import java.util.logging.Logger; +import moa.core.DoubleVector; + +/** + * This class calculates the different measures for each algorithm + * + * @author Alberto Verdecia Cabrera (averdeciac@gmail.com) + */ +public class Algorithm { + + /** + * The name of the algorithms + */ + public String name; + + public String path; + /** + * The list of measures per algorithm + */ + public List measures = new ArrayList<>(); + + /** + * The results file for the algorithm + */ + public BufferedReader buffer; + + /** + * The same size that the measure list + */ + public int measureStdSize = 0; + + /** + * Algorithm constructor + * + * @param name + * @param measures + * @param buffer + * @param path + */ + public Algorithm(String name, List measures, BufferedReader buffer,String path) { + + this.name = name; + this.path = path; + this.measureStdSize = measures.size(); + measures.stream().map((measure) -> { + int index = ReadFile.getMeasureIndex(path,measure.getFileName()); + this.measures.add(new Measure(measure.getName(),measure.getFileName(), measure.isType(), index)); + return measure; + }).filter((measure) -> (measure.isType())).forEach((_item) -> { + this.measureStdSize++; + }); + + this.buffer = buffer; + try { + calculateMeasures(); + } catch (IOException ex) { + Logger.getLogger(Algorithm.class.getName()).log(Level.SEVERE, null, ex); + } + + } + + /** + * calculates the different measures for each algorithm. + * + */ + private void calculateMeasures() throws IOException { + int cont = 0; + DoubleVector values[] = new DoubleVector[this.measures.size()]; + for (int i = 0; i < this.measures.size(); i++) { + values[i] = new DoubleVector(); + } + String lines; + lines = this.buffer.readLine(); + while ((lines = this.buffer.readLine()) != null) { + + String line[] = lines.split(","); + for (int i = 0; i < this.measures.size(); i++) { + if (this.measures.get(i).isType()) { + + try{ + values[i].setValue(cont, Double.parseDouble(line[this.measures.get(i).getIndex()])); + }catch(NumberFormatException exp){ + values[i].setValue(cont,0); + } + + } else { + try{ + this.measures.get(i).setValue(Double.parseDouble(line[this.measures.get(i).getIndex()])); + }catch(NumberFormatException exp){ + this.measures.get(i).setValue(0.0); + } + } + } + cont++; + } + //compute values + for (int i = 0; i < this.measures.size(); i++) { + this.measures.get(i).computeValue(values[i]); + } + + } + + /** + * Returns a list of measures per dataset. + * + * @param stream + * @return a list of measures per dataset + */ + public List[] getMeasuresPerData(List stream) { + List measures[] = new ArrayList[stream.size()]; + for (int i = 0; i < stream.size(); i++) { + measures[i] = new ArrayList<>(); + for (int j = 0; j < stream.get(i).algorithm.size(); j++) { + if (stream.get(i).algorithm.get(j).name.equals(name)) { + measures[i] = stream.get(i).algorithm.get(j).measures; + } + } + } + return measures; + } + + /** + * Rounds to two decimal places and returns the rounded value as a string. + * + * @return a formated value. + */ + static String format(double value) { + return String.format("%.2f", value); + } + + /** + * Returns the closest long to the argument, with ties rounding to positive + * infinity. + * + * @return the value of the argument rounded to the nearest long value. + */ + static String format1(double x) { + String s = "" + Math.round(x); + return s; + } + + /** + * Rounds to two decimal places and returns the rounded value as a double. + * + * @return a formated value. + */ + static double Round(double x) { + return (Math.floor((x + 0.005) * 100)) / 100; + } + +} diff --git a/moa/src/main/java/moa/gui/experimentertab/AnalyzeTab.form b/moa/src/main/java/moa/gui/experimentertab/AnalyzeTab.form new file mode 100644 index 000000000..cdf3ec87c --- /dev/null +++ b/moa/src/main/java/moa/gui/experimentertab/AnalyzeTab.form @@ -0,0 +1,405 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
diff --git a/moa/src/main/java/moa/gui/experimentertab/AnalyzeTab.java b/moa/src/main/java/moa/gui/experimentertab/AnalyzeTab.java new file mode 100644 index 000000000..700f6d855 --- /dev/null +++ b/moa/src/main/java/moa/gui/experimentertab/AnalyzeTab.java @@ -0,0 +1,669 @@ +/* + * AnalyzeTab.java + * Copyright (C) 2007 University of Waikato, Hamilton, New Zealand + * @author Alberto Verdecia Cabrera (averdeciac@gmail.com) + * + * 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 . + * + */ +package moa.gui.experimentertab; + +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.io.File; +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; +import javax.swing.JFileChooser; +import javax.swing.JFrame; +import javax.swing.JMenuItem; +import javax.swing.JOptionPane; +import javax.swing.JPanel; +import javax.swing.JPopupMenu; +import javax.swing.UIManager; +import javax.swing.table.DefaultTableModel; +import moa.gui.experimentertab.statisticaltests.PValuePerTwoAlgorithm; +import moa.gui.experimentertab.statisticaltests.RankPerAlgorithm; +import moa.gui.experimentertab.statisticaltests.StatisticalTest; +import nz.ac.waikato.cms.gui.core.BaseDirectoryChooser; +import org.apache.commons.io.FilenameUtils; + +/** + * In this class are compared online learning algorithms on multiple datasets by + * performing appropriate statistical tests. + * + * @author Alberto Verdecia Cabrera (averdeciac@gmail.com) + */ +public class AnalyzeTab extends javax.swing.JPanel { + + private String algorithms[]; + ArrayList rank = null; + ArrayList pvalues = null; + private DefaultTableModel algoritmModel; + private DefaultTableModel streamModel; + private String path = ""; + private LinkedList measures = new LinkedList(); + ReadFile rf; + /** + * Creates new form Analize + */ + public AnalyzeTab() { + initComponents(); + this.algoritmModel = (DefaultTableModel) jTableAlgoritms.getModel(); + this.streamModel = (DefaultTableModel) jTableStreams.getModel(); + jTextAreaOut.addMouseListener(new PopClickListener()); + } + + private static void createAndShowGUI() { + + // Create and set up the window. + JFrame frame = new JFrame("Test"); + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + + // Create and set up the content pane. + JPanel panel = new AnalyzeTab(); + panel.setOpaque(true); // content panes must be opaque + frame.setContentPane(panel); + + // Display the window. + frame.pack(); + frame.setVisible(true); + } + + @SuppressWarnings("unchecked") + // //GEN-BEGIN:initComponents + private void initComponents() { + + jPanel1 = new javax.swing.JPanel(); + jScrollPaneAlgorithms = new javax.swing.JScrollPane(); + jTableAlgoritms = new javax.swing.JTable(); + jScrollPaneStreams = new javax.swing.JScrollPane(); + jTableStreams = new javax.swing.JTable(); + jTextFieldResultsPath = new javax.swing.JTextField(); + jButtonResults = new javax.swing.JButton(); + jLabelDirectory = new javax.swing.JLabel(); + jButtonDelAlgoritm = new javax.swing.JButton(); + jButtonDelStream = new javax.swing.JButton(); + jPanel2 = new javax.swing.JPanel(); + jLabel2 = new javax.swing.JLabel(); + jComboBoxTest = new javax.swing.JComboBox(); + jButtonTest = new javax.swing.JButton(); + jButtonImage = new javax.swing.JButton(); + jLabel3 = new javax.swing.JLabel(); + jSpinnerPvalue = new javax.swing.JSpinner(); + jButtonReset = new javax.swing.JButton(); + jComboBoxMeasure = new javax.swing.JComboBox(); + jLabel4 = new javax.swing.JLabel(); + jComboBoxType = new javax.swing.JComboBox(); + jLabel1 = new javax.swing.JLabel(); + jScrollPane1 = new javax.swing.JScrollPane(); + jTextAreaOut = new javax.swing.JTextArea(); + + jPanel1.setBorder(javax.swing.BorderFactory.createTitledBorder("Configuration")); + + jScrollPaneAlgorithms.setBorder(javax.swing.BorderFactory.createTitledBorder("Algorithm")); + + jTableAlgoritms.setBorder(javax.swing.BorderFactory.createTitledBorder("")); + jTableAlgoritms.setModel(new javax.swing.table.DefaultTableModel( + new Object [][] { + + }, + new String [] { + "Algorithm", "Algorithm ID" + } + )); + jScrollPaneAlgorithms.setViewportView(jTableAlgoritms); + + jScrollPaneStreams.setBorder(javax.swing.BorderFactory.createTitledBorder("Stram")); + + jTableStreams.setBorder(javax.swing.BorderFactory.createTitledBorder("")); + jTableStreams.setModel(new javax.swing.table.DefaultTableModel( + new Object [][] { + + }, + new String [] { + "Stream", "Stream ID" + } + )); + jScrollPaneStreams.setViewportView(jTableStreams); + + jButtonResults.setText("Browse"); + jButtonResults.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jButtonResultsActionPerformed(evt); + } + }); + + jLabelDirectory.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT); + jLabelDirectory.setText("Result folder"); + + jButtonDelAlgoritm.setText("Delete Algorithm"); + jButtonDelAlgoritm.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jButtonDelAlgoritmActionPerformed(evt); + } + }); + + jButtonDelStream.setText("Delete Stream"); + jButtonDelStream.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jButtonDelStreamActionPerformed(evt); + } + }); + + javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1); + jPanel1.setLayout(jPanel1Layout); + jPanel1Layout.setHorizontalGroup( + jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel1Layout.createSequentialGroup() + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup() + .addGap(14, 14, 14) + .addComponent(jLabelDirectory) + .addGap(18, 18, 18) + .addComponent(jTextFieldResultsPath) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(jButtonResults)) + .addGroup(jPanel1Layout.createSequentialGroup() + .addContainerGap() + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jButtonDelAlgoritm) + .addComponent(jScrollPaneAlgorithms, javax.swing.GroupLayout.DEFAULT_SIZE, 327, Short.MAX_VALUE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jScrollPaneStreams, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE) + .addGroup(jPanel1Layout.createSequentialGroup() + .addComponent(jButtonDelStream) + .addGap(0, 216, Short.MAX_VALUE))))) + .addGap(16, 16, 16)) + ); + jPanel1Layout.setVerticalGroup( + jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup() + .addGap(23, 23, 23) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jTextFieldResultsPath, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jButtonResults) + .addComponent(jLabelDirectory)) + .addGap(18, 18, 18) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jScrollPaneAlgorithms, javax.swing.GroupLayout.DEFAULT_SIZE, 164, Short.MAX_VALUE) + .addComponent(jScrollPaneStreams, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jButtonDelStream) + .addComponent(jButtonDelAlgoritm))) + ); + + jPanel2.setBorder(javax.swing.BorderFactory.createTitledBorder("Statistical Test")); + + jLabel2.setText("Test"); + + jComboBoxTest.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Holm", "Shaffer", "Nemenyi" })); + + jButtonTest.setText("Run Test"); + jButtonTest.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jButtonTestActionPerformed(evt); + } + }); + + jButtonImage.setText("Image"); + jButtonImage.setEnabled(false); + jButtonImage.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jButtonImageActionPerformed(evt); + } + }); + + jLabel3.setText("pValue"); + + jSpinnerPvalue.setModel(new javax.swing.SpinnerNumberModel(Double.valueOf(0.05d), null, null, Double.valueOf(0.001d))); + + jButtonReset.setText("Reset to Default"); + jButtonReset.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jButtonResetActionPerformed(evt); + } + }); + + jLabel4.setText("measure"); + + jComboBoxType.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Mean", "Last" })); + + jLabel1.setText("type"); + + javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2); + jPanel2.setLayout(jPanel2Layout); + jPanel2Layout.setHorizontalGroup( + jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel2Layout.createSequentialGroup() + .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel2Layout.createSequentialGroup() + .addContainerGap() + .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) + .addComponent(jLabel2) + .addComponent(jLabel3) + .addComponent(jLabel4)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jComboBoxTest, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(jSpinnerPvalue) + .addComponent(jComboBoxMeasure, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))) + .addGroup(jPanel2Layout.createSequentialGroup() + .addGap(49, 49, 49) + .addComponent(jButtonTest) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jButtonImage) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jButtonReset) + .addGap(0, 0, Short.MAX_VALUE)) + .addGroup(jPanel2Layout.createSequentialGroup() + .addGap(29, 29, 29) + .addComponent(jLabel1) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(jComboBoxType, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))) + .addContainerGap()) + ); + jPanel2Layout.setVerticalGroup( + jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel2Layout.createSequentialGroup() + .addContainerGap() + .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jComboBoxTest, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel2)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jSpinnerPvalue, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel3)) + .addGap(6, 6, 6) + .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jComboBoxMeasure, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel4)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jComboBoxType, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel1)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jButtonTest) + .addComponent(jButtonImage) + .addComponent(jButtonReset))) + ); + + jScrollPane1.setBorder(javax.swing.BorderFactory.createTitledBorder("Output")); + + jTextAreaOut.setColumns(20); + jTextAreaOut.setRows(5); + jScrollPane1.setViewportView(jTextAreaOut); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); + this.setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 682, Short.MAX_VALUE) + .addComponent(jPanel2, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jPanel1, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() + .addGap(289, 289, 289) + .addComponent(jPanel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 113, Short.MAX_VALUE) + .addContainerGap()) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap(300, Short.MAX_VALUE))) + ); + }// //GEN-END:initComponents + + private void jButtonResultsActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonResultsActionPerformed + BaseDirectoryChooser resultsFile = new BaseDirectoryChooser(); + //resultsFile.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); + int selection = resultsFile.showOpenDialog(this); + if (selection == JFileChooser.APPROVE_OPTION) { + path = resultsFile.getSelectedFile().getAbsolutePath(); + } + + if (!path.equals("")) { + reset(); + this.jTextFieldResultsPath.setText(path); + rf = new ReadFile(path); + String str = rf.processFiles(); + if (str.equals("")) { + + int algSize = rf.getAlgShortNames().size(); + int streamSize = rf.getStream().size(); + this.measures = rf.getMeasures(); + for (int i = 0; i < algSize; i++) { + this.algoritmModel.addRow(new Object[]{rf.getAlgNames().get(i), rf.getAlgShortNames().get(i)}); + } + for (int i = 0; i < streamSize; i++) { + this.streamModel.addRow(new Object[]{rf.getStream().get(i), rf.getStream().get(i)}); + } + + String measuresNames[] = measures.getFirst().split(","); + for (String measuresName : measuresNames) { + jComboBoxMeasure.addItem(measuresName); + if (measuresName.equals("classifications correct (percent)") == true + || measuresName.equals("[avg] classifications correct (percent)") == true) { + jComboBoxMeasure.setSelectedItem(measuresName); + } + + } + } else { + + JOptionPane.showMessageDialog(this, str, + "Error", JOptionPane.ERROR_MESSAGE); + } + } + }//GEN-LAST:event_jButtonResultsActionPerformed + + private void jButtonDelAlgoritmActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonDelAlgoritmActionPerformed + if (this.jTableAlgoritms.getSelectedRow() != -1) { + + this.algoritmModel.removeRow(this.jTableAlgoritms.getSelectedRow()); + String algorithms[] = new String[algoritmModel.getRowCount()]; + for (int i = 0; i < algoritmModel.getRowCount(); i++) { + algorithms[i] = algoritmModel.getValueAt(i, 0).toString(); + } + + if (streamModel.getValueAt(0, 0).toString() != null) { + rf.updateMeasures(algorithms, streamModel.getValueAt(0, 0).toString()); + this.measures = rf.getMeasures(); + String measuresNames[] = measures.getFirst().split(","); + jComboBoxMeasure.removeAllItems(); + for (String measuresName : measuresNames) { + jComboBoxMeasure.addItem(measuresName); + if (measuresName.equals("classifications correct (percent)") == true + || measuresName.equals("[avg] classifications correct (percent)") == true) { + jComboBoxMeasure.setSelectedItem(measuresName); + } + + } + } + } + }//GEN-LAST:event_jButtonDelAlgoritmActionPerformed + + private void jButtonDelStreamActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonDelStreamActionPerformed + this.streamModel.removeRow(this.jTableStreams.getSelectedRow()); + }//GEN-LAST:event_jButtonDelStreamActionPerformed + + private void jButtonTestActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonTestActionPerformed + if (this.jTextFieldResultsPath.getText().equals("")) { + JOptionPane.showMessageDialog(this, "Directory not found", + "Error", JOptionPane.ERROR_MESSAGE); + return; + } + List algmeasures = new ArrayList<>(); + List streams = new ArrayList<>(); + List algPath = new ArrayList<>(); + List algShortNames = new ArrayList<>(); + int count = 0; + boolean type = true; + type = this.jComboBoxType.getSelectedItem().toString().equals("Mean"); + Measure m = new Measure(this.jComboBoxMeasure.getSelectedItem().toString(), + this.jComboBoxMeasure.getSelectedItem().toString(),type, 0); + algmeasures.add(m); + String path = this.jTextFieldResultsPath.getText(); + for (int i = 0; i < streamModel.getRowCount(); i++) { + + algPath.clear(); + for (int j = 0; j < algoritmModel.getRowCount(); j++) { + File inputFile = new File(FilenameUtils.separatorsToSystem( + path + "\\" + streamModel.getValueAt(i, 0) + "\\" + algoritmModel.getValueAt(j, 0))); + File streamFile = new File(FilenameUtils.separatorsToSystem( + path + "\\" + streamModel.getValueAt(i, 0))); + if (!inputFile.exists()) { + JOptionPane.showMessageDialog(this, "File not found: " + + inputFile.getAbsolutePath(), + "Error", JOptionPane.ERROR_MESSAGE); + return; + } else { + String algorithmPath = FilenameUtils.separatorsToSystem( + path + "\\" + streamModel.getValueAt(i, 0).toString() + "\\" + + algoritmModel.getValueAt(j, 0).toString()); + algPath.add(algorithmPath); + if (i == 0) { + algShortNames.add(algoritmModel.getValueAt(j, 1).toString()); + } + + } + } + Stream s = new Stream(streamModel.getValueAt(i, 1).toString(), algPath, algShortNames, algmeasures); + streams.add(s); + } + + //Statistical Test + StatisticalTest test = new StatisticalTest(streams); + try { + // test.readCSV(this.jTextFieldCSV.getText()); + test.readData(); + } catch (Exception exp) { + JOptionPane.showMessageDialog(this, "Problem with csv file", + "Error", JOptionPane.ERROR_MESSAGE); + return; + } + + test.avgPerformance(); + this.jTextAreaOut.append("P-values involving all algorithms\n"); + this.jTextAreaOut.append(System.getProperty("line.separator")); + this.jTextAreaOut.append("P-value computed by Friedman Test: " + test.getFriedmanPValue() + "\n"); + this.jTextAreaOut.append("P-value computed by Iman and Daveport Test: " + test.getImanPValue() + "\n"); + + rank = test.getRankAlg(); + this.jTextAreaOut.append(System.getProperty("line.separator")); + this.jTextAreaOut.append("Ranking of the algorithms\n"); + this.jTextAreaOut.append(System.getProperty("line.separator")); + rank.stream().forEach((RankPerAlgorithm rank1) -> { + this.jTextAreaOut.append(rank1.algName + ": " + rank1.rank + "\n"); + }); + + switch (jComboBoxTest.getSelectedItem().toString()) { + case "Holm": + pvalues = test.holmTest(); + break; + case "Shaffer": + pvalues = test.shafferTest(); + break; + case "Nemenyi": + pvalues = test.nemenyiTest(); + } + this.jTextAreaOut.append(System.getProperty("line.separator")); + this.jTextAreaOut.append("P-values of classifiers against each other\n"); + this.jTextAreaOut.append(System.getProperty("line.separator")); + pvalues.stream().forEach((pvalue) -> { + this.jTextAreaOut.append(pvalue.algName1 + " vs " + pvalue.algName2 + ": " + pvalue.PValue + "\n"); + }); + jButtonImage.setEnabled(true); + // + }//GEN-LAST:event_jButtonTestActionPerformed + + private void jButtonImageActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonImageActionPerformed + RankingGraph graf = new RankingGraph(rank, pvalues, jTextFieldResultsPath.getText(), Double.parseDouble(this.jSpinnerPvalue.getValue().toString())); + }//GEN-LAST:event_jButtonImageActionPerformed + + private void jButtonResetActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonResetActionPerformed + reset(); + }//GEN-LAST:event_jButtonResetActionPerformed + + /** + * Tables of algorithms and datasets are cleaned. + */ + public void cleanTables() { + try { + DefaultTableModel algModel = (DefaultTableModel) jTableAlgoritms.getModel(); + DefaultTableModel strModel = (DefaultTableModel) jTableStreams.getModel(); + int rows = jTableAlgoritms.getRowCount(); + int srow = jTableStreams.getRowCount(); + for (int i = 0; i < rows; i++) { + algModel.removeRow(0); + } + for (int i = 0; i < srow; i++) { + strModel.removeRow(0); + } + + } catch (Exception e) { + JOptionPane.showMessageDialog(null, "Error cleaning the table."); + } + } + + private void reset() { + cleanTables(); + this.jTextFieldResultsPath.setText(""); + + //Combobox + this.jComboBoxMeasure.removeAllItems(); + this.jComboBoxTest.setSelectedItem("Holm"); + //spinner + this.jSpinnerPvalue.setValue(0.05); + + this.jButtonTest.setSelected(false); + this.jButtonImage.setSelected(false); + + } + + /** + * Allows you to read the results file and update the corresponding fields. + * + * @param path + */ + public void readData(String path) { + reset(); + this.jTextFieldResultsPath.setText(path); + this.path = path; + rf = new ReadFile(path); + String str = rf.processFiles(); + if (str.equals("")) { + + int algSize = rf.getAlgShortNames().size(); + int streamSize = rf.getStream().size(); + this.measures = rf.getMeasures(); + for (int i = 0; i < algSize; i++) { + this.algoritmModel.addRow(new Object[]{rf.getAlgNames().get(i), rf.getAlgShortNames().get(i)}); + } + for (int i = 0; i < streamSize; i++) { + this.streamModel.addRow(new Object[]{rf.getStream().get(i), rf.getStream().get(i)}); + } + String measuresNames[] = measures.getFirst().split(","); + for (String measuresName : measuresNames) { + jComboBoxMeasure.addItem(measuresName); + if (measuresName.equals("classifications correct (percent)") == true + || measuresName.equals("[avg] classifications correct (percent)") == true) { + jComboBoxMeasure.setSelectedItem(measuresName); + } + + } + } else { + + JOptionPane.showMessageDialog(this, str, + "Error", JOptionPane.ERROR_MESSAGE); + } + + } + + /** + * Main class method. + * + * @param args + */ + public static void main(String[] args) { + try { + UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); + javax.swing.SwingUtilities.invokeLater(new Runnable() { + + @Override + public void run() { + createAndShowGUI(); + } + }); + } catch (Exception e) { + e.printStackTrace(); + } + + } + + class PopupMenu extends JPopupMenu { + + JMenuItem anItem; + + public PopupMenu() { + anItem = new JMenuItem("Clear"); + add(anItem); + ActionListener listener = (ActionEvent event) -> { + jTextAreaOut.setText(""); + }; + anItem.addActionListener(listener); + } + + } + + class PopClickListener extends MouseAdapter { + + @Override + public void mousePressed(MouseEvent e) { + if (e.isPopupTrigger()) { + doPop(e); + } + } + + @Override + public void mouseReleased(MouseEvent e) { + if (e.isPopupTrigger()) { + doPop(e); + } + } + + private void doPop(MouseEvent e) { + PopupMenu menu = new PopupMenu(); + menu.show(e.getComponent(), e.getX(), e.getY()); + + } + } + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JButton jButtonDelAlgoritm; + private javax.swing.JButton jButtonDelStream; + private javax.swing.JButton jButtonImage; + private javax.swing.JButton jButtonReset; + private javax.swing.JButton jButtonResults; + private javax.swing.JButton jButtonTest; + private javax.swing.JComboBox jComboBoxMeasure; + private javax.swing.JComboBox jComboBoxTest; + private javax.swing.JComboBox jComboBoxType; + private javax.swing.JLabel jLabel1; + private javax.swing.JLabel jLabel2; + private javax.swing.JLabel jLabel3; + private javax.swing.JLabel jLabel4; + private javax.swing.JLabel jLabelDirectory; + private javax.swing.JPanel jPanel1; + private javax.swing.JPanel jPanel2; + private javax.swing.JScrollPane jScrollPane1; + private javax.swing.JScrollPane jScrollPaneAlgorithms; + private javax.swing.JScrollPane jScrollPaneStreams; + private javax.swing.JSpinner jSpinnerPvalue; + private javax.swing.JTable jTableAlgoritms; + private javax.swing.JTable jTableStreams; + private javax.swing.JTextArea jTextAreaOut; + private javax.swing.JTextField jTextFieldResultsPath; + // End of variables declaration//GEN-END:variables +} diff --git a/moa/src/main/java/moa/gui/experimentertab/Buffer.java b/moa/src/main/java/moa/gui/experimentertab/Buffer.java new file mode 100644 index 000000000..d3c369834 --- /dev/null +++ b/moa/src/main/java/moa/gui/experimentertab/Buffer.java @@ -0,0 +1,72 @@ +/* + * Buffer.java + * Copyright (C) 2007 University of Waikato, Hamilton, New Zealand + * @author Alberto Verdecia Cabrera (averdeciac@gmail.com) + * + * 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 . + * + */ +package moa.gui.experimentertab; + +import moa.tasks.MainTask; + +/** + * This class is the buffer where the threads get each task to execute + * + * @author Alberto Verdecia Cabrera (averdeciac@gmail.com) + */ +public class Buffer { + + MainTask tasks[]; + int cantTask = 0; + + /** + * Buffer Constructor + * @param tasks + */ + public Buffer(MainTask tasks[]) { + this.tasks = tasks; + } + + /** + * Returns the next task to be executed. + * + * @return the next task to be executed. + */ + synchronized MainTask getTask() { + if (this.tasks.length != this.cantTask) { + return this.tasks[this.cantTask++]; + } + return null; + } + + /** + * Returns the number of executed tasks. + * + * @return the number of executed tasks. + */ + synchronized int getCantTask() { + return this.cantTask; + } + + /** + * Returns the number of tasks. + * + * @return the number of tasks. + */ + synchronized int getSize() { + return this.tasks.length; + } + +} diff --git a/moa/src/main/java/moa/gui/experimentertab/ExpPreviewPanel.java b/moa/src/main/java/moa/gui/experimentertab/ExpPreviewPanel.java new file mode 100644 index 000000000..7786e0553 --- /dev/null +++ b/moa/src/main/java/moa/gui/experimentertab/ExpPreviewPanel.java @@ -0,0 +1,202 @@ +/* + * ExpPreviewPanel.java + * Copyright (C) 2007 University of Waikato, Hamilton, New Zealand + * @author Richard Kirkby (rkirkby@cs.waikato.ac.nz) + * + * 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 . + * + */ +package moa.gui.experimentertab; + +import java.awt.BorderLayout; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +import javax.swing.JButton; +import javax.swing.JComboBox; +import javax.swing.JLabel; +import javax.swing.JPanel; + +import moa.core.StringUtils; +import moa.evaluation.Accuracy; +import moa.evaluation.ChangeDetectionMeasures; +import moa.evaluation.MeasureCollection; +import moa.evaluation.RegressionAccuracy; +import moa.gui.conceptdrift.CDTaskManagerPanel; +import moa.tasks.ResultPreviewListener; + +/** + * This panel displays the running task preview text and buttons. + * + * @author Richard Kirkby (rkirkby@cs.waikato.ac.nz) + * @version $Revision: 7 $ + */ +public class ExpPreviewPanel extends JPanel implements ResultPreviewListener { + + private static final long serialVersionUID = 1L; + + public static final String[] autoFreqStrings = {"never", "every second", + "every 5 seconds", "every 10 seconds", "every 30 seconds", + "every minute"}; + + public static final int[] autoFreqTimeSecs = {0, 1, 5, 10, 30, 60}; + + protected ExpTaskThread previewedThread; + + protected JLabel previewLabel = new JLabel("No preview available"); + + protected JButton refreshButton = new JButton("Refresh"); + + protected JLabel autoRefreshLabel = new JLabel("Auto refresh: "); + + protected JComboBox autoRefreshComboBox = new JComboBox(autoFreqStrings); + + protected TaskTextViewerPanel textViewerPanel; // = new TaskTextViewerPanel(); + + protected javax.swing.Timer autoRefreshTimer; + + public enum TypePanel { + CLASSIFICATION(new Accuracy()), + REGRESSION(new RegressionAccuracy()), + CONCEPT_DRIFT(new ChangeDetectionMeasures()); + private final MeasureCollection measureCollection; + //Constructor + TypePanel(MeasureCollection measureCollection){ + this.measureCollection = measureCollection; + } + + public MeasureCollection getMeasureCollection(){ + return (MeasureCollection) this.measureCollection.copy(); + } + } + + public ExpPreviewPanel() { + this(TypePanel.CLASSIFICATION, null); + } + + public ExpPreviewPanel(TypePanel typePanel) { + this(typePanel, null); + } + + public ExpPreviewPanel(TypePanel typePanel, CDTaskManagerPanel taskManagerPanel) { + this.textViewerPanel = new TaskTextViewerPanel(typePanel,taskManagerPanel); + this.autoRefreshComboBox.setSelectedIndex(1); // default to 1 sec + JPanel controlPanel = new JPanel(); + controlPanel.add(this.previewLabel); + controlPanel.add(this.refreshButton); + controlPanel.add(this.autoRefreshLabel); + controlPanel.add(this.autoRefreshComboBox); + setLayout(new BorderLayout()); + add(controlPanel, BorderLayout.NORTH); + add(this.textViewerPanel, BorderLayout.CENTER); + this.refreshButton.addActionListener(new ActionListener() { + + @Override + public void actionPerformed(ActionEvent arg0) { + refresh(); + } + }); + this.autoRefreshTimer = new javax.swing.Timer(1000, + new ActionListener() { + + @Override + public void actionPerformed(ActionEvent e) { + refresh(); + } + }); + this.autoRefreshComboBox.addActionListener(new ActionListener() { + + @Override + public void actionPerformed(ActionEvent arg0) { + updateAutoRefreshTimer(); + } + }); + setTaskThreadToPreview(null); + } + + public void refresh() { + if (this.previewedThread != null) { + if (this.previewedThread.isComplete()) { + setLatestPreview(null); + disableRefresh(); + } else { + this.previewedThread.getPreview(ExpPreviewPanel.this); + } + } + } + + public void setTaskThreadToPreview(ExpTaskThread thread) { + this.previewedThread = thread; + setLatestPreview(thread != null ? thread.getLatestResultPreview() + : null); + if (thread == null) { + disableRefresh(); + } else if (!thread.isComplete()) { + enableRefresh(); + } + } + + public void setLatestPreview(Object preview) { + if ((this.previewedThread != null) && this.previewedThread.isComplete()) { + this.previewLabel.setText("Final result"); + Object finalResult = this.previewedThread.getFinalResult(); + this.textViewerPanel.setText(finalResult != null ? finalResult.toString() : null); + disableRefresh(); + } else { + double grabTime = this.previewedThread != null ? this.previewedThread.getLatestPreviewGrabTimeSeconds() + : 0.0; + String grabString = grabTime > 0.0 ? (" (" + + StringUtils.secondsToDHMSString(grabTime) + ")") : ""; + this.textViewerPanel.setText(preview != null ? preview.toString() + : null); + if (preview == null) { + this.previewLabel.setText("No preview available" + grabString); + } else { + this.previewLabel.setText("Preview" + grabString); + } + } + } + + public void updateAutoRefreshTimer() { + int autoDelay = autoFreqTimeSecs[this.autoRefreshComboBox.getSelectedIndex()]; + if (autoDelay > 0) { + if (this.autoRefreshTimer.isRunning()) { + this.autoRefreshTimer.stop(); + } + this.autoRefreshTimer.setDelay(autoDelay * 1000); + this.autoRefreshTimer.start(); + } else { + this.autoRefreshTimer.stop(); + } + } + + public void disableRefresh() { + this.refreshButton.setEnabled(false); + this.autoRefreshLabel.setEnabled(false); + this.autoRefreshComboBox.setEnabled(false); + this.autoRefreshTimer.stop(); + } + + public void enableRefresh() { + this.refreshButton.setEnabled(true); + this.autoRefreshLabel.setEnabled(true); + this.autoRefreshComboBox.setEnabled(true); + updateAutoRefreshTimer(); + } + + @Override + public void latestPreviewChanged() { + setTaskThreadToPreview(this.previewedThread); + } +} diff --git a/moa/src/main/java/moa/gui/experimentertab/ExpTaskThread.java b/moa/src/main/java/moa/gui/experimentertab/ExpTaskThread.java new file mode 100644 index 000000000..456f9e76f --- /dev/null +++ b/moa/src/main/java/moa/gui/experimentertab/ExpTaskThread.java @@ -0,0 +1,196 @@ +/* + * ExpTaskThread.java + * Copyright (C) 2007 University of Waikato, Hamilton, New Zealand + * @author Richard Kirkby (rkirkby@cs.waikato.ac.nz) + * @modified Alberto Verdecia (averdeciac@gmail.com) + * 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 . + * + */ +package moa.gui.experimentertab; + +import java.util.concurrent.CopyOnWriteArraySet; +import moa.core.ObjectRepository; +import moa.core.TimingUtils; +import moa.tasks.MainTask; +import moa.tasks.ResultPreviewListener; +import moa.tasks.StandardTaskMonitor; +import moa.tasks.Task; +import moa.tasks.TaskCompletionListener; +import moa.tasks.TaskMonitor; +import moa.tasks.TaskThread; + +/** + * Task Thread. + * + * @author Richard Kirkby (rkirkby@cs.waikato.ac.nz) + * @modified Alberto Verdecia (averdeciac@gmail.com) + */ +public class ExpTaskThread extends Thread { + + Buffer tasks; + + public static enum Status { + + NOT_STARTED, RUNNING, PAUSED, CANCELLING, CANCELLED, COMPLETED, FAILED + } + + protected MainTask runningTask; + + protected volatile Status currentStatus; + + protected TaskMonitor taskMonitor; + + protected ObjectRepository repository; + + protected Object finalResult; + + protected long taskStartTime; + + protected long taskEndTime; + + protected double latestPreviewGrabTime = 0.0; + + public boolean isCompleted = false; + + CopyOnWriteArraySet completionListeners = new CopyOnWriteArraySet(); + + public ExpTaskThread(Buffer buf) { + this.tasks = buf; + this.currentStatus = ExpTaskThread.Status.NOT_STARTED; + this.taskMonitor = new StandardTaskMonitor(); + this.repository =null; + + } + + @Override + public void run() { + TimingUtils.enablePreciseTiming(); + this.taskStartTime = TimingUtils.getNanoCPUTimeOfThread(getId()); + while (this.tasks.getCantTask() != this.tasks.getSize()) { + this.runningTask = this.tasks.getTask(); + this.currentStatus = ExpTaskThread.Status.RUNNING; + this.taskMonitor.setCurrentActivityDescription("Running task " + this.runningTask); + this.finalResult = this.runningTask.doTask(this.taskMonitor, this.repository); + this.currentStatus = this.taskMonitor.isCancelled() ? ExpTaskThread.Status.CANCELLED + : ExpTaskThread.Status.COMPLETED; + //System.out.println(this.taskMonitor.getCurrentActivityFractionComplete()*100); + } + this.isCompleted = true; + } + public String getCurrentActivityString() { + return (isComplete() || (this.currentStatus == ExpTaskThread.Status.NOT_STARTED)) ? "" + : this.taskMonitor.getCurrentActivityDescription(); + } + + public boolean isComplete() { + return ((this.currentStatus == ExpTaskThread.Status.CANCELLED) + || (this.currentStatus == ExpTaskThread.Status.COMPLETED) || (this.currentStatus == ExpTaskThread.Status.FAILED)); + } + public double getCPUSecondsElapsed() { + double secondsElapsed = 0.0; + if (this.currentStatus == ExpTaskThread.Status.NOT_STARTED) { + secondsElapsed = 0.0; + } else if (isComplete()) { + secondsElapsed = TimingUtils.nanoTimeToSeconds(this.taskEndTime + - this.taskStartTime); + } else { + secondsElapsed = TimingUtils.nanoTimeToSeconds(TimingUtils.getNanoCPUTimeOfThread(getId()) + - this.taskStartTime); + } + return secondsElapsed > 0.0 ? secondsElapsed : 0.0; + } + public Task getTask() { + return this.runningTask; + } + public String getCurrentStatusString() { + switch (this.currentStatus) { + case NOT_STARTED: + return "not started"; + case RUNNING: + return "running"; + case PAUSED: + return "paused"; + case CANCELLING: + return "cancelling"; + case CANCELLED: + return "cancelled"; + case COMPLETED: + return "completed"; + case FAILED: + return "failed"; + } + return "unknown"; + } + public double getCurrentActivityFracComplete() { + switch (this.currentStatus) { + case NOT_STARTED: + return 0.0; + case RUNNING: + case PAUSED: + case CANCELLING: + return this.taskMonitor.getCurrentActivityFractionComplete(); + case CANCELLED: + case COMPLETED: + case FAILED: + return 1.0; + } + return 0.0; + } + public Object getFinalResult() { + return this.finalResult; + } + + public void addTaskCompletionListener(TaskCompletionListener tcl) { + this.completionListeners.add(tcl); + } + + public void removeTaskCompletionListener(TaskCompletionListener tcl) { + this.completionListeners.remove(tcl); + } + + public void getPreview(ResultPreviewListener previewer) { + this.taskMonitor.requestResultPreview(previewer); + this.latestPreviewGrabTime = getCPUSecondsElapsed(); + } + + public Object getLatestResultPreview() { + return this.taskMonitor.getLatestResultPreview(); + } + + public double getLatestPreviewGrabTimeSeconds() { + return this.latestPreviewGrabTime; + } + public synchronized void pauseTask() { + if (this.currentStatus == Status.RUNNING) { + this.taskMonitor.requestPause(); + this.currentStatus = Status.PAUSED; + } + } + + public synchronized void resumeTask() { + if (this.currentStatus == Status.PAUSED) { + this.taskMonitor.requestResume(); + this.currentStatus = Status.RUNNING; + } + } + + public synchronized void cancelTask() { + if ((this.currentStatus == Status.RUNNING) + || (this.currentStatus == Status.PAUSED)) { + this.taskMonitor.requestCancel(); + this.currentStatus = Status.CANCELLING; + } + } + +} diff --git a/moa/src/main/java/moa/gui/experimentertab/ExperimenterTabPanel.java b/moa/src/main/java/moa/gui/experimentertab/ExperimenterTabPanel.java new file mode 100644 index 000000000..bc1dd613d --- /dev/null +++ b/moa/src/main/java/moa/gui/experimentertab/ExperimenterTabPanel.java @@ -0,0 +1,57 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package moa.gui.experimentertab; + +import java.awt.BorderLayout; +import javax.swing.JTabbedPane; +import moa.gui.AbstractTabPanel; +import moa.gui.TaskManagerPanel; + +/** + * + * @author Alberto + */ +public class ExperimenterTabPanel extends AbstractTabPanel { + + private static final long serialVersionUID = 1L; + + protected TaskManagerTabPanel taskTabManagerPanel; + + protected ExpPreviewPanel previewPanel; + + protected JTabbedPane tabs = new JTabbedPane(); + + /** + *Initializes the different tabs of the application + */ + public ExperimenterTabPanel() { + //this.taskManagerPanel = new TaskManagerPanel(); + this.taskTabManagerPanel = new TaskManagerTabPanel(); + tabs.addTab("Experiments", this.taskTabManagerPanel); + tabs.addTab("Summary", this.taskTabManagerPanel.summary); + tabs.addTab("Plot", this.taskTabManagerPanel.plot); + tabs.addTab("Analyze", this.taskTabManagerPanel.analizeTab); + this.previewPanel = new ExpPreviewPanel(); + //this.taskTabManagerPanel.setPreviewPanel(this.previewPanel); + //this.taskManagerPanel.setPreviewPanel(this.previewPanel); + // tabs.addTab("Analyze", this.previewPanel); + setLayout(new BorderLayout()); + add(this.tabs); + //add(this.previewPanel, BorderLayout.CENTER); + } + + //returns the string to display as title of the tab + @Override + public String getTabTitle() { + return "Experimenter"; + } + + //a short description (can be used as tool tip) of the tab, or contributor, etc. + @Override + public String getDescription() { + return "MOA Classification"; + } +} diff --git a/moa/src/main/java/moa/gui/experimentertab/ExperimeterCLI.java b/moa/src/main/java/moa/gui/experimentertab/ExperimeterCLI.java new file mode 100644 index 000000000..6a021f1b8 --- /dev/null +++ b/moa/src/main/java/moa/gui/experimentertab/ExperimeterCLI.java @@ -0,0 +1,332 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package moa.gui.experimentertab; + +import java.io.File; +import java.io.IOException; +import java.util.logging.Level; +import java.util.logging.Logger; +import org.apache.commons.cli.BasicParser; +import org.apache.commons.cli.CommandLine; +import org.apache.commons.cli.CommandLineParser; +import org.apache.commons.cli.HelpFormatter; +import org.apache.commons.cli.Options; +import org.apache.commons.io.FilenameUtils; + +/** + * + * @author Alberto + */ +public class ExperimeterCLI { + + private String algorithms[]; + private String algorithmsID[]; + private String streams[]; + private String streamsID[]; + private String task; + private String resultsFolder; + private String saveExperimentsPath; + private String args[]; + private int threads = 1; + + public int[] measures = null; + public String[] types = null; + Options options = new Options(); + Options optionsm = new Options(); + + public ExperimeterCLI(String[] args) { + this.args = args; + //Config the options + + options.addOption("ls", true, "The names of the algorithms separated by commas"); + options.addOption("lss", true, "ID of the algorithms separated by commas"); + options.addOption("ds", true, "The names of the streams separated by commas"); + options.addOption("dss", true, "ID of the streams separated by commas"); + options.addOption("rf", true, "Results folder"); + options.addOption("th", true, "Number of threads"); + options.addOption("ts", true, "Task"); + options.addOption("h", "help", false, "Prints the help message"); + + optionsm.addOption("h", "help", false, "Prints the help message"); + optionsm.addOption("m", true, "The number of measures separated by commas"); + optionsm.addOption("tm", true, "The types of measures separated by commas, the types are Mean and Last"); + } + + public boolean summary1CMD(String[] args) { + + CommandLineParser parser = null; + CommandLine cmdLine = null; + + try { + parser = new BasicParser(); + cmdLine = parser.parse(optionsm, args); + if (cmdLine.hasOption("h")) { + new HelpFormatter().printHelp(ExperimeterCLI.class.getCanonicalName(), optionsm); + return false; + } + String measure = cmdLine.getOptionValue("m"); + if (measure == null) { + System.out.println("The measures are required"); + return false; + } + if (measure.contains(",")) { + String[] m = measure.split(","); + measures = new int[m.length]; + for (int i = 0; i < m.length; i++) { + measures[i] = Integer.parseInt(m[i]); + } + } else { + measures = new int[1]; + measures[0] = Integer.parseInt(measure); + } + + if (cmdLine.hasOption("tm")) { + String type = cmdLine.getOptionValue("tm"); + if (type.contains(",")) { + types = type.split(","); + } else { + types = new String[1]; + types[0] = type; + } + } else { + types = new String[measures.length]; + for (int i = 0; i < types.length; i++) { + types[i] = "Mean"; + } + } + } catch (org.apache.commons.cli.ParseException ex) { + System.out.println(ex.getMessage()); + + new HelpFormatter().printHelp(ExperimeterCLI.class.getCanonicalName(), optionsm); // Error, imprimimos la ayuda + } catch (java.lang.NumberFormatException ex) { + new HelpFormatter().printHelp(ExperimeterCLI.class.getCanonicalName(), optionsm); // Error, imprimimos la ayuda + } + return true; + } + + public boolean proccesCMD(){ + int threads = 1; + String algNames = null; + String algShortNames = null; + String streamNames = null; + String streamShortNames = null; + String task = null; + String resultsFolder = null; + + CommandLineParser parser = null; + CommandLine cmdLine = null; + + try { + //Parse the input with the set configuration + parser = new BasicParser(); + cmdLine = parser.parse(options, args); + if (cmdLine.hasOption("h")) { + new HelpFormatter().printHelp(ExperimeterCLI.class.getCanonicalName(), options); + return false; + } + + if (cmdLine.hasOption("th")) { + threads = Integer.parseInt(cmdLine.getOptionValue("th")); + this.setThreads(threads); + } + + task = cmdLine.getOptionValue("ts"); + if (task == null) { + throw new org.apache.commons.cli.ParseException("The task is required"); + } + this.setTask(task); + //Algorithms names + algNames = cmdLine.getOptionValue("ls"); + + if (algNames == null) { + throw new org.apache.commons.cli.ParseException("The name of the algorithms are required"); + } + + try { + if (algNames.contains(",")) { + this.setAlgorithms(algNames.split(",")); + } else { + String alg[] = new String[1]; + alg[0] = algNames; + this.setAlgorithms(alg); + } + + } catch (Exception e) { + System.out.println("Problems with algortihms ls options"); + new HelpFormatter().printHelp(ExperimeterCLI.class.getCanonicalName(), options); + } + + //Agorithms ID + if (cmdLine.hasOption("lss")) { + + algShortNames = cmdLine.getOptionValue("lss"); + if (algShortNames.contains(",")) { + this.setAlgorithmsID(algShortNames.split(",")); + } else { + String ash[] = new String[1]; + ash[0] = algShortNames; + this.setAlgorithmsID(ash); + } + + } else { + this.setAlgorithmsID(this.getAlgorithms()); + } + //Streams names + streamNames = cmdLine.getOptionValue("ds"); + + if (streamNames == null) { + throw new org.apache.commons.cli.ParseException("The name of the streams are required"); + } + + if (streamNames.contains(",")) { + this.setStreams(streamNames.split(",")); + for (int i = 0; i < this.getStreams().length; i++) { + String ds = this.getStreams()[i]; + if (ds.contains(":")) { + String dir = ds.split(":")[0]; + if (dir.contains(File.separator)) { + dir = dir.split(File.separator + File.separator)[0]; + ds = dir + ":" + ds.split(":")[1]; + this.setStreamIndex(i, ds); + } + + } + } + } else { + String str[] = new String[1]; + str[0] = FilenameUtils.separatorsToSystem(streamNames); + this.setStreams(str); + + } + + //stream ID + if (cmdLine.hasOption("dss")) { + streamShortNames = cmdLine.getOptionValue("dss"); + if (streamShortNames.contains(",")) { + this.setStreamsID(streamShortNames.split(",")); + } else { + String strh[] = new String[1]; + strh[0] = streamShortNames; + this.setStreamsID(strh); + } + + } else { + this.setStreamsID(this.getStreams()); + } + //Results folder + resultsFolder = cmdLine.getOptionValue("rf"); + + if (resultsFolder == null) { + //throw new org.apache.commons.cli.ParseException("The resuts folder are required"); + File excPath = new File("."); + try { + resultsFolder = excPath.getCanonicalPath(); + } catch (IOException ex) { + Logger.getLogger(ExperimeterCLI.class.getName()).log(Level.SEVERE, null, ex); + } + } + if (resultsFolder.contains(":")) { + String dir = resultsFolder.split(":")[0]; + if (dir.contains(File.separator)) { + dir = dir.split(File.separator + File.separator)[0]; + resultsFolder = dir + ":" + resultsFolder.split(":")[1]; + } + } + this.setResultsFolder(FilenameUtils.separatorsToSystem(resultsFolder)); + // System.out.println("OK"); + // System.out.println(task); + // System.out.println(algNames); + // System.out.println(streamNames); + + } catch (org.apache.commons.cli.ParseException ex) { + System.out.println(ex.getMessage()); + new HelpFormatter().printHelp(ExperimeterCLI.class.getCanonicalName(), options); // Error, print help + return false; + } catch (java.lang.NumberFormatException ex) { + new HelpFormatter().printHelp(ExperimeterCLI.class.getCanonicalName(), options); // Error, print help + return false; + } + return true; + } + + public String[] getAlgorithms() { + return algorithms; + } + + public String[] getAlgorithmsID() { + return algorithmsID; + } + + public String[] getArgs() { + return args; + } + + public String getResultsFolder() { + return resultsFolder; + } + + public String getSaveExperimentsPath() { + return saveExperimentsPath; + } + + public String[] getStreams() { + return streams; + } + + public String[] getStreamsID() { + return streamsID; + } + + public String getTask() { + return task; + } + + public int getThreads() { + return threads; + } + + public void setAlgorithms(String[] algorithms) { + this.algorithms = algorithms; + } + + public void setAlgorithmsID(String[] algorithmsID) { + this.algorithmsID = algorithmsID; + } + + public void setArgs(String[] args) { + this.args = args; + } + + public void setResultsFolder(String resultsFolder) { + this.resultsFolder = resultsFolder; + } + + public void setSaveExperimentsPath(String saveExperimentsPath) { + this.saveExperimentsPath = saveExperimentsPath; + } + + public void setStreams(String[] streams) { + for(int i = 0; i < streams.length; i++){ + streams[i] = FilenameUtils.separatorsToSystem(streams[i]); + } + this.streams = streams; + } + + public void setStreamsID(String[] streamsID) { + this.streamsID = streamsID; + } + public void setStreamIndex(int index, String streamID) { + this.streams[index] = streamID; + } + public void setTask(String task) { + this.task = task; + } + + public void setThreads(int threads) { + this.threads = threads; + } + +} diff --git a/moa/src/main/java/moa/gui/experimentertab/ImageChart.java b/moa/src/main/java/moa/gui/experimentertab/ImageChart.java new file mode 100644 index 000000000..b9e90e46a --- /dev/null +++ b/moa/src/main/java/moa/gui/experimentertab/ImageChart.java @@ -0,0 +1,251 @@ +/* + * ImageChart.java + * Copyright (C) 2007 University of Waikato, Hamilton, New Zealand + * @author Alberto Verdecia Cabrera (averdeciac@gmail.com) + * + * 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 . + * + */ +package moa.gui.experimentertab; + +import java.awt.Color; +import java.awt.Graphics2D; +import java.awt.Rectangle; +import java.awt.geom.Rectangle2D; +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.io.Writer; +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import javax.swing.JFileChooser; +import javax.swing.JOptionPane; +import org.jfree.chart.ChartUtilities; +import org.jfree.chart.JFreeChart; +import org.jibble.epsgraphics.EpsGraphics2D; +import weka.gui.ExtensionFileFilter; + +/** + * This class allows to handle the properties of the graph created by + * JFreeChart. + * + * @author Alberto + */ +public class ImageChart { + + private String name; + + private JFreeChart chart; + + private int width; + + private int height; + + /** + * Default constructor. + */ + public ImageChart() { + } + + /** + * Constructor. + * + * @param name + * @param chart + * @param width + * @param height + */ + public ImageChart(String name, JFreeChart chart, int width, int height) { + this.name = name; + this.chart = chart; + this.width = width; + this.height = height; + } + + /** + * Constructor. + * + * @param name + * @param chart + */ + public ImageChart(String name, JFreeChart chart) { + this.name = name; + this.chart = chart; + } + + /** + * Set the image name. + * + * @param name + */ + public void setName(String name) { + this.name = name; + } + + /** + * Set chart. + * + * @param chart + */ + public void setChart(JFreeChart chart) { + this.chart = chart; + } + + /** + * Set chart height. + * + * @param height + */ + public void setHeight(int height) { + this.height = height; + } + + /** + * Set chart width. + * + * @param width + */ + public void setWidth(int width) { + this.width = width; + } + + /** + * Return the chart. + * + * @return chart + */ + public JFreeChart getChart() { + return chart; + } + + /** + * Return the name. + * + * @return name + */ + public String getName() { + return name; + } + + /** + * Return the height. + * + * @return height + */ + public int getHeight() { + return height; + } + + /** + * Return the width. + * + * @return width + */ + public int getWidth() { + return width; + } + + @Override + public String toString() { + return name; //To change body of generated methods, choose Tools | Templates. + } + + /** + * Export the image to formats JPG, PNG, SVG and EPS. + * + * @param path + * @param type + * @throws IOException + */ + public void exportIMG(String path, String type) throws IOException { + + switch (type) { + case "JPG": + try { + ChartUtilities.saveChartAsJPEG(new File(path + File.separator + name + ".jpg"), chart, width, height); + } catch (IOException e) { + + } + break; + case "PNG": + try { + ChartUtilities.saveChartAsPNG(new File(path + File.separator + name + ".png"), chart, width, height); + } catch (IOException e) { + + } + break; + case "EPS": + Graphics2D g = new EpsGraphics2D(); + g.setColor(Color.gray); + chart.draw(g, new Rectangle(width, height)); + try (Writer out = new FileWriter(new File(path + File.separator + name + ".eps"))) { + out.write(g.toString()); + } + break; + case "SVG": + String svg = generateSVG(width, height); + BufferedWriter writer = null; + try { + writer = new BufferedWriter(new FileWriter(new File(path + File.separator + name + ".svg"))); + writer.write("\n"); + writer.write(svg + "\n"); + writer.flush(); + } finally { + try { + if (writer != null) { + writer.close(); + } + } catch (IOException ex) { + throw new RuntimeException(ex); + } + } + break; + + } + + } + + private String generateSVG(int width, int height) { + Graphics2D g2 = createSVGGraphics2D(width, height); + if (g2 == null) { + throw new IllegalStateException("JFreeSVG library is not present."); + } + // we suppress shadow generation, because SVG is a vector format and + // the shadow effect is applied via bitmap effects... + g2.setRenderingHint(JFreeChart.KEY_SUPPRESS_SHADOW_GENERATION, true); + String svg = null; + Rectangle2D drawArea = new Rectangle2D.Double(0, 0, width, height); + this.chart.draw(g2, drawArea); + try { + Method m = g2.getClass().getMethod("getSVGElement"); + svg = (String) m.invoke(g2); + } catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { + // null will be returned + } + return svg; + } + + private Graphics2D createSVGGraphics2D(int w, int h) { + try { + Class svgGraphics2d = Class.forName("org.jfree.graphics2d.svg.SVGGraphics2D"); + Constructor ctor = svgGraphics2d.getConstructor(int.class, int.class); + return (Graphics2D) ctor.newInstance(w, h); + } catch (ClassNotFoundException | NoSuchMethodException | SecurityException | InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) { + return null; + } + } + +} diff --git a/moa/src/main/java/moa/gui/experimentertab/ImagePanel.java b/moa/src/main/java/moa/gui/experimentertab/ImagePanel.java new file mode 100644 index 000000000..005451970 --- /dev/null +++ b/moa/src/main/java/moa/gui/experimentertab/ImagePanel.java @@ -0,0 +1,156 @@ +/* + * ImagePanel.java + * Copyright (C) 2007 University of Waikato, Hamilton, New Zealand + * @author Alberto Verdecia Cabrera (averdeciac@gmail.com) + * + * 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 . + * + */ +package moa.gui.experimentertab; + +import java.io.File; +import java.io.IOException; +import javax.swing.JFileChooser; +import javax.swing.JMenu; +import javax.swing.JMenuItem; +import javax.swing.JPopupMenu; +import org.jfree.chart.ChartPanel; +import org.jfree.chart.ChartUtilities; +import org.jfree.chart.JFreeChart; +import weka.gui.ExtensionFileFilter; + +/** + * This class creates a panel with an image. + * + * @author Alberto Verdecia Cabrera (averdeciac@gmail.com) + */ +public class ImagePanel extends ChartPanel { + + JFreeChart chart; + + /** + * Class Constructor. + * + * @param chart + */ + public ImagePanel(JFreeChart chart) { + super(chart); + this.chart = chart; + } + + /** + * Method for save the images. + * + * @throws IOException + */ + @Override + public void doSaveAs() throws IOException { + + JFileChooser fileChooser = new JFileChooser(); + ExtensionFileFilter filterPNG = new ExtensionFileFilter("PNG Image Files", ".png"); + fileChooser.addChoosableFileFilter(filterPNG); + + ExtensionFileFilter filterJPG = new ExtensionFileFilter("JPG Image Files", ".jpg"); + fileChooser.addChoosableFileFilter(filterJPG); + + ExtensionFileFilter filterEPS = new ExtensionFileFilter("EPS Image Files", ".eps"); + fileChooser.addChoosableFileFilter(filterEPS); + + ExtensionFileFilter filterSVG = new ExtensionFileFilter("SVG Image Files", ".svg"); + fileChooser.addChoosableFileFilter(filterSVG); + fileChooser.setCurrentDirectory(null); + int option = fileChooser.showSaveDialog(this); + if (option == JFileChooser.APPROVE_OPTION) { + String fileDesc = fileChooser.getFileFilter().getDescription(); + if (fileDesc.startsWith("PNG")) { + if (!fileChooser.getSelectedFile().getName().toUpperCase().endsWith("PNG")) { + ChartUtilities.saveChartAsPNG(new File(fileChooser.getSelectedFile().getAbsolutePath() + ".png"), this.chart, this.getWidth(), this.getHeight()); + } else { + ChartUtilities.saveChartAsPNG(fileChooser.getSelectedFile(), this.chart, this.getWidth(), this.getHeight()); + } + } else if (fileDesc.startsWith("JPG")) { + if (!fileChooser.getSelectedFile().getName().toUpperCase().endsWith("JPG")) { + ChartUtilities.saveChartAsJPEG(new File(fileChooser.getSelectedFile().getAbsolutePath() + ".jpg"), this.chart, this.getWidth(), this.getHeight()); + } else { + ChartUtilities.saveChartAsJPEG(fileChooser.getSelectedFile(), this.chart, this.getWidth(), this.getHeight()); + } + } + + }//else + } + + /** + * + * @param properties + * @param copy + * @param save + * @param print + * @param zoom + * @return JPopupMenu + */ + @Override + protected JPopupMenu createPopupMenu(boolean properties, + boolean copy, boolean save, boolean print, boolean zoom) { + JPopupMenu result = new JPopupMenu(localizationResources.getString("Chart") + ":"); + boolean separator = false; + + if (properties) { + JMenuItem propertiesItem = new JMenuItem( + localizationResources.getString("Properties...")); + propertiesItem.setActionCommand(PROPERTIES_COMMAND); + propertiesItem.addActionListener(this); + result.add(propertiesItem); + separator = true; + } + + if (copy) { + if (separator) { + result.addSeparator(); + } + JMenuItem copyItem = new JMenuItem( + localizationResources.getString("Copy")); + copyItem.setActionCommand(COPY_COMMAND); + copyItem.addActionListener(this); + result.add(copyItem); + separator = !save; + } + + if (save) { + if (separator) { + result.addSeparator(); + } + JMenu saveSubMenu = new JMenu(localizationResources.getString( + "Save_as")); + JMenuItem pngItem = new JMenuItem(localizationResources.getString( + "PNG...")); + + separator = true; + } + + if (print) { + if (separator) { + result.addSeparator(); + } + JMenuItem printItem = new JMenuItem( + localizationResources.getString("Print...")); + printItem.setActionCommand(PRINT_COMMAND); + printItem.addActionListener(this); + result.add(printItem); + separator = true; + } + + return result; + } + +} diff --git a/moa/src/main/java/moa/gui/experimentertab/ImageTreePanel.java b/moa/src/main/java/moa/gui/experimentertab/ImageTreePanel.java new file mode 100644 index 000000000..9bb266003 --- /dev/null +++ b/moa/src/main/java/moa/gui/experimentertab/ImageTreePanel.java @@ -0,0 +1,144 @@ +/* + * ImageTreePanel.java + * Copyright (C) 2007 University of Waikato, Hamilton, New Zealand + * @author Alberto Verdecia Cabrera (averdeciac@gmail.com) + * + * 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 . + * + */ +package moa.gui.experimentertab; + +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.JSplitPane; +import javax.swing.JTree; +import javax.swing.tree.DefaultMutableTreeNode; +import javax.swing.tree.TreeSelectionModel; +import javax.swing.event.TreeSelectionEvent; +import javax.swing.event.TreeSelectionListener; +import java.awt.Dimension; +import java.awt.GridLayout; +import javax.swing.ImageIcon; +import javax.swing.tree.DefaultTreeCellRenderer; +import javax.swing.tree.DefaultTreeModel; + +/** + * This class creates a JTree panel to show the images generated with + * JFreeChart. + * + * @author Alberto + */ +public class ImageTreePanel extends JPanel + implements TreeSelectionListener { + + private JPanel imgPanel; + private JTree tree; + private ImageChart chart[]; + private ImagePanel chartPanel[]; + + /** + * Constructor. + * @param chart + */ + public ImageTreePanel(ImageChart chart[]) { + super(new GridLayout(1, 0)); + this.chart = chart; + //Create the nodes. + DefaultMutableTreeNode top + = new DefaultMutableTreeNode("Images"); + imgPanel = new JPanel(); + imgPanel.setLayout(new GridLayout(1, 0)); + createNodes(top); + tree = new JTree(top); + tree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION); + DefaultTreeModel model = (DefaultTreeModel) tree.getModel(); + tree.setSelectionRow(1); + + tree.addTreeSelectionListener(this); + ImageIcon leafIcon = new ImageIcon("icon/img.png"); + if (leafIcon != null) { + DefaultTreeCellRenderer renderer + = new DefaultTreeCellRenderer(); + renderer.setLeafIcon(leafIcon); + tree.setCellRenderer(renderer); + } + imgPanel.updateUI(); + JScrollPane treeView = new JScrollPane(tree); + treeView.setMinimumSize(new Dimension(100, 50)); + + JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT); + splitPane.setTopComponent(treeView); + splitPane.setBottomComponent(imgPanel); + splitPane.setDividerLocation(100); + splitPane.setPreferredSize(new Dimension(500, 300)); + add(splitPane); + + } + + private void createNodes(DefaultMutableTreeNode top) { + + DefaultMutableTreeNode child = null; + + for (ImageChart chart1 : chart) { + child = new DefaultMutableTreeNode(chart1); + ImagePanel chPanel = new ImagePanel(chart1.getChart()); + chPanel.setMouseWheelEnabled(true); + chPanel.setMouseZoomable(true); + chPanel.repaint(); + this.imgPanel.removeAll(); + this.imgPanel.add(chPanel); + this.imgPanel.updateUI(); + top.add(child); + } + + } + + /** + * @param args the command line arguments + */ + public static void main(String[] args) { + // TODO code application logic here + } + + @Override + public void valueChanged(TreeSelectionEvent e) { + DefaultMutableTreeNode node = (DefaultMutableTreeNode) tree.getLastSelectedPathComponent(); + + if (node == null) { + return; + } + + Object nodeInfo = node.getUserObject(); + if (node.isLeaf()) { + ImageChart chart = (ImageChart) nodeInfo; + ImagePanel chPanel = new ImagePanel(chart.getChart()); + chPanel.setMouseWheelEnabled(true); + chPanel.setMouseZoomable(true); + chPanel.repaint(); + this.imgPanel.removeAll(); + this.imgPanel.add(chPanel); + this.imgPanel.updateUI(); + } + } + + /** + * Return the ImageChart array. + * + * @return chart + */ + public ImageChart[] getChart() { + return chart; + } + +} diff --git a/moa/src/main/java/moa/gui/experimentertab/ImageViewer.java b/moa/src/main/java/moa/gui/experimentertab/ImageViewer.java new file mode 100644 index 000000000..7cafd3903 --- /dev/null +++ b/moa/src/main/java/moa/gui/experimentertab/ImageViewer.java @@ -0,0 +1,116 @@ +/* + * ImageViewer.java + * Copyright (C) 2007 University of Waikato, Hamilton, New Zealand + * @author Alberto Verdecia Cabrera (averdeciac@gmail.com) + * + * 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 . + * + */ +package moa.gui.experimentertab; + +import java.awt.BorderLayout; +import java.awt.HeadlessException; +import java.io.File; +import java.io.IOException; +import javax.swing.JButton; +import javax.swing.JComboBox; +import javax.swing.JFileChooser; +import javax.swing.JFrame; +import javax.swing.JLabel; +import javax.swing.JOptionPane; +import javax.swing.JPanel; +import nz.ac.waikato.cms.gui.core.BaseDirectoryChooser; +import nz.ac.waikato.cms.gui.core.BaseFileChooser; + +/** + * This class creates a window where images generated with JFreeChart are + * displayed. + * + * @author Alberto Verdecia Cabrera (averdeciac@gmail.com) + */ +public class ImageViewer extends JFrame { + + private ImageTreePanel imgPanel; + + private String resultsPath; + + private JButton btn; + + private JComboBox imgType; + + /** + * Class constructor. + * + * @param imgPanel + * @param resultsPath + * @throws HeadlessException + */ + public ImageViewer(ImageTreePanel imgPanel, String resultsPath) throws HeadlessException { + super("Preview"); + this.imgPanel = imgPanel; + this.resultsPath = resultsPath; + setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE); + + // Create and set up the content pane. + JPanel panel = new JPanel(); + JPanel main = new JPanel(); + JLabel label = new JLabel("Output format"); + String op[] = {"PNG", "JPG", "EPS", "SVG"}; + imgType = new JComboBox(op); + imgType.setSelectedIndex(0); + btn = new JButton("Save all images as..."); + btn.addActionListener(this::btnMenuActionPerformed); + panel.add(label); + panel.add(imgType); + panel.add(btn); + + main.setLayout(new BorderLayout()); + main.add(this.imgPanel, BorderLayout.CENTER); + main.add(panel, BorderLayout.SOUTH); + + setContentPane(main); + + // Display the window. + pack(); + setSize(700, 500); + + setVisible(true); + } + + private void btnMenuActionPerformed(java.awt.event.ActionEvent evt) { + + String path = ""; + BaseDirectoryChooser propDir = new BaseDirectoryChooser(); + propDir.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); + propDir.setCurrentDirectory(new File(resultsPath)); + int selection = propDir.showSaveDialog(this); + if (selection == JFileChooser.APPROVE_OPTION) { + path = propDir.getSelectedFile().getAbsolutePath(); + if (!path.equals("")) { + for (ImageChart chart : this.imgPanel.getChart()) { + try { + chart.exportIMG(path, this.imgType.getSelectedItem().toString()); + + } catch (IOException ex) { + JOptionPane.showMessageDialog(this, "Error creating image " + chart.getName()); + return; + } + + } + JOptionPane.showMessageDialog(this, "Images saved at: " + path); + } + } + + } +} diff --git a/moa/src/main/java/moa/gui/experimentertab/Measure.java b/moa/src/main/java/moa/gui/experimentertab/Measure.java new file mode 100644 index 000000000..c82895d0e --- /dev/null +++ b/moa/src/main/java/moa/gui/experimentertab/Measure.java @@ -0,0 +1,188 @@ +/* + * Measure.java + * Copyright (C) 2007 University of Waikato, Hamilton, New Zealand + * @author Alberto Verdecia Cabrera (averdeciac@gmail.com) + * + * 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 . + * + */ +package moa.gui.experimentertab; + +import moa.core.DoubleVector; + +/** + * This class determines the value of each measure for each algorithm + * + * @author Alberto Verdecia Cabrera (averdeciac@gmail.com) + */ +public class Measure { + + private String name; + + private String fileName; + + private Double value; + + private DoubleVector values = new DoubleVector(); + + private Double std; + + private boolean type; + + private int index; + + /** + * Measure Constructor + * @param name + * @param type + * @param index + */ + public Measure(String name,String filename, boolean type, int index) { + this.name = name; + this.fileName = filename; + this.type = type; + this.index = index; + this.value = 0.0; + this.std = 0.0; + } + + /** + * + * @return the name of measure + */ + public String getName() { + return name; + } + + public String getFileName() { + return fileName; + } + + public void setFileName(String fileName) { + this.fileName = fileName; + } + + /** + * Sets the name of measure + * @param name + */ + public void setName(String name) { + this.name = name; + } + + /** + * + * @return the value of measure + */ + public Double getValue() { + return value; + } + + /** + * Sets the value of measure + * @param value + */ + public void setValue(Double value) { + this.value = value; + } + + /** + * Returns the standard deviation + * @return the standard deviation + */ + public Double getStd() { + return std; + } + + /** + * Sets the standard deviation + * @param std + */ + public void setStd(Double std) { + this.std = std; + } + + /** + * Returns the type of measure + * @return the type of measure + */ + public boolean isType() { + return type; + } + + /** + * Sets the type of measure + * @param type + */ + public void setType(boolean type) { + this.type = type; + } + + /** + * Returns the index of measure + * @return the index of measure + */ + public int getIndex() { + return index; + } + + /** + * Sets the index of measure + * @param index + */ + public void setIndex(int index) { + this.index = index; + } + + /** + * + * @return values + */ + public DoubleVector getValues() { + return values; + } + + /** + * + * @param values + */ + public void setValues(DoubleVector values) { + this.values = (DoubleVector) values.copy(); + } + + /** + * Calculates the value of measure + * @param values + */ + public void computeValue(DoubleVector values) { + if (this.isType()) { + setValues(values); + double sumDif = 0.0; + this.value = this.values.sumOfValues() / (double) values.numValues(); + for (int i = 0; i < this.values.numValues(); i++) { + double dif = this.values.getValue(i) - this.value; + sumDif += Math.pow(dif, 2); + } + sumDif = sumDif / this.values.numValues(); + this.std = Math.sqrt(sumDif); + } + + } + + @Override + protected Object clone() throws CloneNotSupportedException { + return super.clone(); + } + +} diff --git a/moa/src/main/java/moa/gui/experimentertab/PlotTab.form b/moa/src/main/java/moa/gui/experimentertab/PlotTab.form new file mode 100644 index 000000000..f15247667 --- /dev/null +++ b/moa/src/main/java/moa/gui/experimentertab/PlotTab.form @@ -0,0 +1,981 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + <Editor/> + <Renderer/> + </Column> + <Column maxWidth="-1" minWidth="-1" prefWidth="-1" resizable="true"> + <Title/> + <Editor/> + <Renderer/> + </Column> + </TableColumnModel> + </Property> + <Property name="tableHeader" type="javax.swing.table.JTableHeader" editor="org.netbeans.modules.form.editors2.JTableHeaderEditor"> + <TableHeader reorderingAllowed="true" resizingAllowed="true"/> + </Property> + </Properties> + </Component> + </SubComponents> + </Container> + <Container class="javax.swing.JScrollPane" name="jScrollPane3"> + <Properties> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="org.netbeans.modules.form.compat2.border.TitledBorderInfo"> + <TitledBorder title="Stream"/> + </Border> + </Property> + </Properties> + <AuxValues> + <AuxValue name="autoScrollPane" type="java.lang.Boolean" value="true"/> + </AuxValues> + + <Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/> + <SubComponents> + <Component class="javax.swing.JTable" name="jTableStreams"> + <Properties> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="org.netbeans.modules.form.compat2.border.TitledBorderInfo"> + <TitledBorder/> + </Border> + </Property> + <Property name="model" type="javax.swing.table.TableModel" editor="org.netbeans.modules.form.editors2.TableModelEditor"> + <Table columnCount="2" rowCount="0"> + <Column editable="true" title="Stream" type="java.lang.Object"/> + <Column editable="true" title="Stream ID" type="java.lang.Object"/> + </Table> + </Property> + <Property name="columnModel" type="javax.swing.table.TableColumnModel" editor="org.netbeans.modules.form.editors2.TableColumnModelEditor"> + <TableColumnModel selectionModel="0"> + <Column maxWidth="-1" minWidth="-1" prefWidth="-1" resizable="true"> + <Title/> + <Editor/> + <Renderer/> + </Column> + <Column maxWidth="-1" minWidth="-1" prefWidth="-1" resizable="true"> + <Title/> + <Editor/> + <Renderer/> + </Column> + </TableColumnModel> + </Property> + <Property name="tableHeader" type="javax.swing.table.JTableHeader" editor="org.netbeans.modules.form.editors2.JTableHeaderEditor"> + <TableHeader reorderingAllowed="true" resizingAllowed="true"/> + </Property> + </Properties> + </Component> + </SubComponents> + </Container> + <Component class="javax.swing.JTextField" name="jTextFieldResultPath"> + </Component> + <Component class="javax.swing.JButton" name="jButtonInPath"> + <Properties> + <Property name="text" type="java.lang.String" value="Browse"/> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jButtonInPathActionPerformed"/> + </Events> + </Component> + <Component class="javax.swing.JLabel" name="jLabel3"> + <Properties> + <Property name="horizontalAlignment" type="int" value="4"/> + <Property name="text" type="java.lang.String" value="Result folder"/> + </Properties> + </Component> + <Component class="javax.swing.JButton" name="jButtonDeletAlgorithm"> + <Properties> + <Property name="text" type="java.lang.String" value="Delete Algorithm"/> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jButtonDeletAlgorithmActionPerformed"/> + </Events> + </Component> + <Component class="javax.swing.JButton" name="jButtonDeleteStream"> + <Properties> + <Property name="text" type="java.lang.String" value="Delete Stream"/> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jButtonDeleteStreamActionPerformed"/> + </Events> + </Component> + </SubComponents> + </Container> + <Container class="javax.swing.JTabbedPane" name="jTabbedPane1"> + + <Layout class="org.netbeans.modules.form.compat2.layouts.support.JTabbedPaneSupportLayout"/> + <SubComponents> + <Container class="javax.swing.JPanel" name="jPanel2"> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.support.JTabbedPaneSupportLayout" value="org.netbeans.modules.form.compat2.layouts.support.JTabbedPaneSupportLayout$JTabbedPaneConstraintsDescription"> + <JTabbedPaneConstraints tabName="Charts"> + <Property name="tabTitle" type="java.lang.String" value="Charts"/> + </JTabbedPaneConstraints> + </Constraint> + </Constraints> + + <Layout> + <DimensionLayout dim="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <EmptySpace min="-2" pref="135" max="-2" attributes="0"/> + <Component id="jButtonAcept" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="jButtonReset" min="-2" max="-2" attributes="0"/> + <EmptySpace max="32767" attributes="0"/> + </Group> + <Component id="jScrollPane1" alignment="1" pref="700" max="32767" attributes="0"/> + </Group> + </DimensionLayout> + <DimensionLayout dim="1"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" alignment="1" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Component id="jScrollPane1" min="-2" pref="247" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jButtonAcept" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jButtonReset" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + </Group> + </Group> + </DimensionLayout> + </Layout> + <SubComponents> + <Component class="javax.swing.JButton" name="jButtonAcept"> + <Properties> + <Property name="text" type="java.lang.String" value="Generate Images"/> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jButtonAceptActionPerformed"/> + </Events> + </Component> + <Component class="javax.swing.JButton" name="jButtonReset"> + <Properties> + <Property name="text" type="java.lang.String" value=" Reset to Default"/> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jButtonResetActionPerformed"/> + </Events> + </Component> + <Container class="javax.swing.JScrollPane" name="jScrollPane1"> + <Properties> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="org.netbeans.modules.form.compat2.border.TitledBorderInfo"> + <TitledBorder/> + </Border> + </Property> + <Property name="horizontalScrollBarPolicy" type="int" value="31"/> + </Properties> + + <Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/> + <SubComponents> + <Container class="javax.swing.JPanel" name="jPanel4"> + <Properties> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="org.netbeans.modules.form.compat2.border.TitledBorderInfo"> + <TitledBorder/> + </Border> + </Property> + </Properties> + + <Layout> + <DimensionLayout dim="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" alignment="0" attributes="0"> + <EmptySpace min="-2" pref="67" max="-2" attributes="0"/> + <Group type="103" groupAlignment="1" attributes="0"> + <Group type="102" attributes="0"> + <EmptySpace min="-2" pref="3" max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="103" alignment="0" groupAlignment="1" attributes="0"> + <Component id="jLabel17" min="-2" max="-2" attributes="0"/> + <Component id="jLabel21" min="-2" max="-2" attributes="0"/> + <Component id="jLabel18" min="-2" max="-2" attributes="0"/> + </Group> + <Component id="jLabel19" alignment="0" min="-2" max="-2" attributes="0"/> + <Component id="jLabel20" alignment="1" min="-2" max="-2" attributes="0"/> + <Component id="jLabel22" alignment="1" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace type="separate" max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="jTextFieldxTitle" alignment="0" max="32767" attributes="0"/> + <Component id="jComboBoxXColumn" alignment="1" max="32767" attributes="0"/> + <Component id="jTextFieldTitle" alignment="1" max="32767" attributes="0"/> + <Component id="jComboBoxYColumn" alignment="0" max="32767" attributes="0"/> + <Component id="jTextFieldyTitle" alignment="0" pref="542" max="32767" attributes="0"/> + <Component id="jSpinnerWidth" alignment="0" max="32767" attributes="0"/> + </Group> + </Group> + <Group type="102" alignment="0" attributes="0"> + <Group type="103" groupAlignment="1" attributes="0"> + <Component id="jLabel23" alignment="1" min="-2" max="-2" attributes="0"/> + <Component id="jLabel2" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace min="-2" pref="18" max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <Component id="jCheckBoxShape" min="-2" pref="91" max="-2" attributes="0"/> + <EmptySpace min="0" pref="0" max="32767" attributes="0"/> + </Group> + <Component id="jComboBoxGrid" alignment="0" max="32767" attributes="0"/> + <Component id="jSpinnerHeight" max="32767" attributes="0"/> + </Group> + </Group> + </Group> + <EmptySpace min="-2" pref="30" max="-2" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + <DimensionLayout dim="1"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" alignment="0" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jTextFieldTitle" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jLabel21" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jComboBoxXColumn" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jLabel17" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jTextFieldxTitle" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jLabel18" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jComboBoxYColumn" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jLabel19" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace max="32767" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jTextFieldyTitle" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jLabel20" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="jSpinnerWidth" min="-2" max="-2" attributes="0"/> + <Component id="jLabel22" alignment="0" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jLabel23" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jSpinnerHeight" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jComboBoxGrid" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jLabel2" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + <Component id="jCheckBoxShape" min="-2" max="-2" attributes="0"/> + <EmptySpace pref="11" max="32767" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + </Layout> + <SubComponents> + <Component class="javax.swing.JLabel" name="jLabel17"> + <Properties> + <Property name="horizontalAlignment" type="int" value="4"/> + <Property name="text" type="java.lang.String" value="xColumn"/> + </Properties> + </Component> + <Component class="javax.swing.JTextField" name="jTextFieldxTitle"> + <Properties> + <Property name="text" type="java.lang.String" value="Instances processed"/> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel18"> + <Properties> + <Property name="horizontalAlignment" type="int" value="4"/> + <Property name="text" type="java.lang.String" value="xTitle"/> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel19"> + <Properties> + <Property name="horizontalAlignment" type="int" value="4"/> + <Property name="text" type="java.lang.String" value="yColumn"/> + </Properties> + </Component> + <Component class="javax.swing.JTextField" name="jTextFieldyTitle"> + <Properties> + <Property name="text" type="java.lang.String" value="% of correctly classified"/> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel20"> + <Properties> + <Property name="horizontalAlignment" type="int" value="4"/> + <Property name="text" type="java.lang.String" value="yTitle"/> + </Properties> + </Component> + <Component class="javax.swing.JComboBox" name="jComboBoxXColumn"> + <Properties> + <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor"> + <StringArray count="0"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JComboBox" name="jComboBoxYColumn"> + <Properties> + <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor"> + <StringArray count="0"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JTextField" name="jTextFieldTitle"> + </Component> + <Component class="javax.swing.JLabel" name="jLabel21"> + <Properties> + <Property name="text" type="java.lang.String" value="title"/> + </Properties> + </Component> + <Component class="javax.swing.JSpinner" name="jSpinnerWidth"> + <Properties> + <Property name="value" type="java.lang.Object" editor="org.netbeans.modules.form.RADConnectionPropertyEditor"> + <Connection code="500" type="code"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JSpinner" name="jSpinnerHeight"> + <Properties> + <Property name="value" type="java.lang.Object" editor="org.netbeans.modules.form.RADConnectionPropertyEditor"> + <Connection code="300" type="code"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel22"> + <Properties> + <Property name="text" type="java.lang.String" value="width"/> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel23"> + <Properties> + <Property name="text" type="java.lang.String" value="height"/> + </Properties> + </Component> + <Component class="javax.swing.JComboBox" name="jComboBoxGrid"> + <Properties> + <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor"> + <StringArray count="2"> + <StringItem index="0" value="White"/> + <StringItem index="1" value="Default"/> + </StringArray> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JCheckBox" name="jCheckBoxShape"> + <Properties> + <Property name="text" type="java.lang.String" value="shapes"/> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel2"> + <Properties> + <Property name="text" type="java.lang.String" value="gridColor"/> + </Properties> + </Component> + </SubComponents> + </Container> + </SubComponents> + </Container> + </SubComponents> + </Container> + <Container class="javax.swing.JPanel" name="jPanel3"> + <Constraints> + <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.support.JTabbedPaneSupportLayout" value="org.netbeans.modules.form.compat2.layouts.support.JTabbedPaneSupportLayout$JTabbedPaneConstraintsDescription"> + <JTabbedPaneConstraints tabName="GnuPlot"> + <Property name="tabTitle" type="java.lang.String" value="GnuPlot"/> + </JTabbedPaneConstraints> + </Constraint> + </Constraints> + + <Layout> + <DimensionLayout dim="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" alignment="0" attributes="0"> + <EmptySpace min="-2" pref="128" max="-2" attributes="0"/> + <Component id="jButtonAceptGnuP" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="jButtonResetGnuP" min="-2" max="-2" attributes="0"/> + <EmptySpace max="32767" attributes="0"/> + </Group> + <Component id="jScrollPaneGnuP" alignment="0" pref="700" max="32767" attributes="0"/> + </Group> + </DimensionLayout> + <DimensionLayout dim="1"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" alignment="1" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Component id="jScrollPaneGnuP" min="-2" pref="247" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jButtonAceptGnuP" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jButtonResetGnuP" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + </Group> + </Group> + </DimensionLayout> + </Layout> + <SubComponents> + <Component class="javax.swing.JButton" name="jButtonAceptGnuP"> + <Properties> + <Property name="text" type="java.lang.String" value="Generate GnuPlot Commands"/> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jButtonAceptGnuPActionPerformed"/> + </Events> + </Component> + <Component class="javax.swing.JButton" name="jButtonResetGnuP"> + <Properties> + <Property name="text" type="java.lang.String" value=" Reset to Default"/> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jButtonResetGnuPActionPerformed"/> + </Events> + </Component> + <Container class="javax.swing.JScrollPane" name="jScrollPaneGnuP"> + <Properties> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="org.netbeans.modules.form.compat2.border.TitledBorderInfo"> + <TitledBorder/> + </Border> + </Property> + <Property name="horizontalScrollBarPolicy" type="int" value="31"/> + </Properties> + + <Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/> + <SubComponents> + <Container class="javax.swing.JPanel" name="jPanelGnuP"> + <Properties> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="org.netbeans.modules.form.compat2.border.TitledBorderInfo"> + <TitledBorder/> + </Border> + </Property> + <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> + <Dimension value="[400, 449]"/> + </Property> + </Properties> + + <Layout> + <DimensionLayout dim="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" alignment="0" attributes="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="103" alignment="0" groupAlignment="0" attributes="0"> + <Group type="102" alignment="0" attributes="0"> + <EmptySpace min="-2" pref="22" max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="jLabel5" alignment="1" min="-2" max="-2" attributes="0"/> + <Component id="jLabel6" alignment="1" min="-2" max="-2" attributes="0"/> + <Component id="jLabel7" alignment="1" min="-2" max="-2" attributes="0"/> + <Component id="jLabel8" alignment="1" min="-2" max="-2" attributes="0"/> + <Component id="jLabel10" alignment="1" min="-2" max="-2" attributes="0"/> + <Component id="jLabel11" alignment="1" min="-2" max="-2" attributes="0"/> + <Component id="jLabel1" alignment="1" min="-2" max="-2" attributes="0"/> + </Group> + </Group> + <Group type="102" alignment="1" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Component id="jLabel27" min="-2" max="-2" attributes="0"/> + </Group> + </Group> + <Group type="102" alignment="1" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="jLabel15" alignment="1" min="-2" max="-2" attributes="0"/> + <Component id="jLabel13" alignment="1" min="-2" max="-2" attributes="0"/> + <Component id="jLabel14" alignment="1" min="-2" max="-2" attributes="0"/> + <Component id="jLabel16" alignment="1" min="-2" max="-2" attributes="0"/> + <Component id="jLabel24" alignment="1" min="-2" max="-2" attributes="0"/> + <Component id="jLabel25" alignment="1" min="-2" max="-2" attributes="0"/> + <Component id="jLabel26" alignment="1" min="-2" max="-2" attributes="0"/> + </Group> + </Group> + </Group> + <EmptySpace type="unrelated" min="-2" max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="jTextFieldAPOptions" alignment="1" max="32767" attributes="0"/> + <Component id="jTextFieldAdcComand" alignment="1" max="32767" attributes="0"/> + <Component id="jComboBoxLegendType" alignment="1" max="32767" attributes="0"/> + <Component id="jSpinnerPlotInterval" alignment="1" max="32767" attributes="0"/> + <Component id="jSpinnerLineWidth" alignment="1" max="32767" attributes="0"/> + <Component id="jTextFieldyTitleGnuP" alignment="1" max="32767" attributes="0"/> + <Component id="jTextFieldxTitleGnuP" alignment="1" max="32767" attributes="0"/> + <Component id="jComboBoxLineStyle" alignment="1" max="32767" attributes="0"/> + <Component id="jComboBoxXColumnGnuP" alignment="0" max="32767" attributes="0"/> + <Component id="jComboBoxYColumnGnuP" alignment="0" max="32767" attributes="0"/> + <Component id="jComboBoxLegendLocation" alignment="0" pref="542" max="32767" attributes="0"/> + <Group type="102" alignment="0" attributes="0"> + <Component id="jTextFieldGNUPath" max="32767" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="jButtonGnuoPath" min="-2" max="-2" attributes="0"/> + </Group> + <Group type="102" alignment="0" attributes="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="jCheckBoxDeleteScript" alignment="0" min="-2" max="-2" attributes="0"/> + <Component id="jCheckBoxSmooth" alignment="0" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace min="0" pref="0" max="32767" attributes="0"/> + </Group> + <Component id="jComboBoxOutPTypeGnuP" alignment="1" max="32767" attributes="0"/> + </Group> + <EmptySpace min="-2" max="-2" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + <DimensionLayout dim="1"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" alignment="0" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jTextFieldGNUPath" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jButtonGnuoPath" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jLabel1" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jComboBoxOutPTypeGnuP" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jLabel5" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="jComboBoxLineStyle" alignment="0" min="-2" max="-2" attributes="0"/> + <Component id="jLabel6" alignment="0" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jComboBoxXColumnGnuP" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jLabel7" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jTextFieldxTitleGnuP" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jLabel8" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jComboBoxYColumnGnuP" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jLabel10" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jTextFieldyTitleGnuP" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jLabel11" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jSpinnerLineWidth" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jLabel13" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jSpinnerPlotInterval" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jLabel14" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="jCheckBoxSmooth" alignment="0" min="-2" max="-2" attributes="0"/> + <Component id="jLabel15" alignment="0" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="jCheckBoxDeleteScript" alignment="0" min="-2" max="-2" attributes="0"/> + <Component id="jLabel16" alignment="0" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jComboBoxLegendLocation" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jLabel24" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jComboBoxLegendType" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jLabel25" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jTextFieldAdcComand" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jLabel26" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jTextFieldAPOptions" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jLabel27" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace min="-2" pref="186" max="-2" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + </Layout> + <SubComponents> + <Component class="javax.swing.JTextField" name="jTextFieldGNUPath"> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jTextFieldGNUPathActionPerformed"/> + </Events> + </Component> + <Component class="javax.swing.JLabel" name="jLabel1"> + <Properties> + <Property name="horizontalAlignment" type="int" value="4"/> + <Property name="text" type="java.lang.String" value="gnuplotBinaryPath "/> + </Properties> + </Component> + <Component class="javax.swing.JButton" name="jButtonGnuoPath"> + <Properties> + <Property name="text" type="java.lang.String" value="Browse"/> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jButtonGnuoPathActionPerformed"/> + </Events> + </Component> + <Component class="javax.swing.JComboBox" name="jComboBoxOutPTypeGnuP"> + <Properties> + <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor"> + <StringArray count="13"> + <StringItem index="0" value="POSTSCRIPT_COLOR"/> + <StringItem index="1" value="EPSLATEX"/> + <StringItem index="2" value="GIF"/> + <StringItem index="3" value="JPEG"/> + <StringItem index="4" value="LATEX"/> + <StringItem index="5" value="PDFCAIRO"/> + <StringItem index="6" value="PNG"/> + <StringItem index="7" value="POSTSCRIPT"/> + <StringItem index="8" value="CANVAS"/> + <StringItem index="9" value="PSLATEX"/> + <StringItem index="10" value="PSTEX"/> + <StringItem index="11" value="PSTRICKS"/> + <StringItem index="12" value="SVG"/> + </StringArray> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel5"> + <Properties> + <Property name="horizontalAlignment" type="int" value="4"/> + <Property name="text" type="java.lang.String" value="outputType"/> + </Properties> + </Component> + <Component class="javax.swing.JComboBox" name="jComboBoxLineStyle"> + <Properties> + <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor"> + <StringArray count="8"> + <StringItem index="0" value="LINES"/> + <StringItem index="1" value="POINTS"/> + <StringItem index="2" value="LINESPOINTS"/> + <StringItem index="3" value="IMPULSES"/> + <StringItem index="4" value="STEPS"/> + <StringItem index="5" value="FSTEPS"/> + <StringItem index="6" value="HISTEPS"/> + <StringItem index="7" value="DOTS;"/> + </StringArray> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel6"> + <Properties> + <Property name="horizontalAlignment" type="int" value="4"/> + <Property name="text" type="java.lang.String" value="plotStyle"/> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel7"> + <Properties> + <Property name="horizontalAlignment" type="int" value="4"/> + <Property name="text" type="java.lang.String" value="xColumn"/> + </Properties> + </Component> + <Component class="javax.swing.JTextField" name="jTextFieldxTitleGnuP"> + <Properties> + <Property name="text" type="java.lang.String" value="Processed instances"/> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel8"> + <Properties> + <Property name="horizontalAlignment" type="int" value="4"/> + <Property name="text" type="java.lang.String" value="xTitle"/> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel10"> + <Properties> + <Property name="horizontalAlignment" type="int" value="4"/> + <Property name="text" type="java.lang.String" value="yColumn"/> + </Properties> + </Component> + <Component class="javax.swing.JTextField" name="jTextFieldyTitleGnuP"> + <Properties> + <Property name="text" type="java.lang.String" value="Accuracy"/> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel11"> + <Properties> + <Property name="horizontalAlignment" type="int" value="4"/> + <Property name="text" type="java.lang.String" value="yTitle"/> + </Properties> + </Component> + <Component class="javax.swing.JSpinner" name="jSpinnerLineWidth"> + <Properties> + <Property name="value" type="java.lang.Object" editor="org.netbeans.modules.form.RADConnectionPropertyEditor"> + <Connection code="2" type="code"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JSpinner" name="jSpinnerPlotInterval"> + </Component> + <Component class="javax.swing.JLabel" name="jLabel13"> + <Properties> + <Property name="horizontalAlignment" type="int" value="4"/> + <Property name="text" type="java.lang.String" value="lineWidth"/> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel14"> + <Properties> + <Property name="horizontalAlignment" type="int" value="4"/> + <Property name="text" type="java.lang.String" value="plotInterval"/> + </Properties> + </Component> + <Component class="javax.swing.JCheckBox" name="jCheckBoxSmooth"> + </Component> + <Component class="javax.swing.JLabel" name="jLabel15"> + <Properties> + <Property name="horizontalAlignment" type="int" value="4"/> + <Property name="text" type="java.lang.String" value="smooth"/> + </Properties> + </Component> + <Component class="javax.swing.JCheckBox" name="jCheckBoxDeleteScript"> + </Component> + <Component class="javax.swing.JLabel" name="jLabel16"> + <Properties> + <Property name="horizontalAlignment" type="int" value="4"/> + <Property name="text" type="java.lang.String" value="deleteScripts"/> + </Properties> + </Component> + <Component class="javax.swing.JComboBox" name="jComboBoxLegendLocation"> + <Properties> + <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor"> + <StringArray count="18"> + <StringItem index="0" value="BOTTOM_CENTER_OUTSIDE"/> + <StringItem index="1" value="TOP_LEFT_INSIDE"/> + <StringItem index="2" value="TOP_CENTER_INSIDE"/> + <StringItem index="3" value="TOP_RIGHT_INSIDE"/> + <StringItem index="4" value="LEFT_INSIDE"/> + <StringItem index="5" value="CENTER_INSIDE"/> + <StringItem index="6" value="RIGHT_INSIDE"/> + <StringItem index="7" value="BOTTOM_LEFT_INSIDE"/> + <StringItem index="8" value="BOTTOM_CENTER_INSIDE"/> + <StringItem index="9" value="BOTTOM_RIGHT_INSIDE"/> + <StringItem index="10" value="TOP_LEFT_OUTSIDE"/> + <StringItem index="11" value="TOP_CENTER_OUTSIDE"/> + <StringItem index="12" value="TOP_RIGHT_OUTSIDE"/> + <StringItem index="13" value="LEFT_OUTSIDE"/> + <StringItem index="14" value="CENTER_OUTSIDE"/> + <StringItem index="15" value="RIGHT_OUTSIDE"/> + <StringItem index="16" value="BOTTOM_LEFT_OUTSIDE"/> + <StringItem index="17" value="BOTTOM_RIGHT_OUTSIDE"/> + </StringArray> + </Property> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jComboBoxLegendLocationActionPerformed"/> + </Events> + </Component> + <Component class="javax.swing.JLabel" name="jLabel24"> + <Properties> + <Property name="horizontalAlignment" type="int" value="4"/> + <Property name="text" type="java.lang.String" value="legendLocation"/> + </Properties> + </Component> + <Component class="javax.swing.JComboBox" name="jComboBoxLegendType"> + <Properties> + <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor"> + <StringArray count="5"> + <StringItem index="0" value="NOBOX_HORIZONTAL"/> + <StringItem index="1" value="BOX_VERTICAL"/> + <StringItem index="2" value="BOX_HORIZONTAL"/> + <StringItem index="3" value="NOBOX_VERTICAL"/> + <StringItem index="4" value=" "/> + </StringArray> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel25"> + <Properties> + <Property name="horizontalAlignment" type="int" value="4"/> + <Property name="text" type="java.lang.String" value="legendType"/> + </Properties> + </Component> + <Component class="javax.swing.JTextField" name="jTextFieldAdcComand"> + </Component> + <Component class="javax.swing.JLabel" name="jLabel26"> + <Properties> + <Property name="horizontalAlignment" type="int" value="4"/> + <Property name="text" type="java.lang.String" value="additionalCommands"/> + </Properties> + </Component> + <Component class="javax.swing.JTextField" name="jTextFieldAPOptions"> + </Component> + <Component class="javax.swing.JLabel" name="jLabel27"> + <Properties> + <Property name="horizontalAlignment" type="int" value="4"/> + <Property name="text" type="java.lang.String" value="additionalPlotOptions"/> + </Properties> + </Component> + <Component class="javax.swing.JComboBox" name="jComboBoxXColumnGnuP"> + <Properties> + <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor"> + <StringArray count="0"/> + </Property> + </Properties> + </Component> + <Component class="javax.swing.JComboBox" name="jComboBoxYColumnGnuP"> + <Properties> + <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor"> + <StringArray count="0"/> + </Property> + </Properties> + </Component> + </SubComponents> + </Container> + </SubComponents> + </Container> + </SubComponents> + </Container> + </SubComponents> + </Container> + </SubComponents> +</Form> diff --git a/moa/src/main/java/moa/gui/experimentertab/PlotTab.java b/moa/src/main/java/moa/gui/experimentertab/PlotTab.java new file mode 100644 index 000000000..b2ba200e0 --- /dev/null +++ b/moa/src/main/java/moa/gui/experimentertab/PlotTab.java @@ -0,0 +1,1333 @@ +/* + * PlotTab.java + * Copyright (C) 2007 University of Waikato, Hamilton, New Zealand + * @author Alberto Verdecia Cabrera (averdeciac@gmail.com) + * + * 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 moa.gui.experimentertab; + +import java.awt.Color; +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileWriter; +import java.io.IOException; +import java.io.InputStreamReader; +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.logging.Level; +import java.util.logging.Logger; +import javax.swing.JFileChooser; +import javax.swing.JFrame; +import javax.swing.JOptionPane; +import javax.swing.JPanel; +import javax.swing.UIManager; +import javax.swing.table.DefaultTableModel; +import static moa.gui.experimentertab.ReadFile.readCSV; +import nz.ac.waikato.cms.gui.core.BaseDirectoryChooser; +import org.apache.commons.io.FilenameUtils; +import org.jfree.chart.ChartFactory; +import org.jfree.chart.JFreeChart; +import org.jfree.chart.plot.PlotOrientation; +import org.jfree.chart.plot.XYPlot; +import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer; +import org.jfree.data.xy.XYSeries; +import org.jfree.data.xy.XYSeriesCollection; + +/** + * Generate figures plotting the performance measurements of various learning + * algorithms over time. + * + * @author Alberto Verdecia Cabrera (averdeciac@gmail.com) + */ +public class PlotTab extends javax.swing.JPanel { + + private String path = ""; + + private LinkedList<String> measures = new LinkedList(); + + private DefaultTableModel algoritmModel; + + private DefaultTableModel streamModel; + + ImageTreePanel imgPanel; + + ImageChart chart[]; + + ReadFile rf; + + public PlotTab() { + initComponents(); + initComponents(); + this.algoritmModel = (DefaultTableModel) jTableAlgoritms.getModel(); + this.streamModel = (DefaultTableModel) jTableStreams.getModel(); + } + + /** + * This method is called from within the constructor to initialize the form. + * WARNING: Do NOT modify this code. The content of this method is always + * regenerated by the Form Editor. + */ + @SuppressWarnings("unchecked") + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents + private void initComponents() { + + jPanel1 = new javax.swing.JPanel(); + jScrollPaneAlgorithms = new javax.swing.JScrollPane(); + jTableAlgoritms = new javax.swing.JTable(); + jScrollPane3 = new javax.swing.JScrollPane(); + jTableStreams = new javax.swing.JTable(); + jTextFieldResultPath = new javax.swing.JTextField(); + jButtonInPath = new javax.swing.JButton(); + jLabel3 = new javax.swing.JLabel(); + jButtonDeletAlgorithm = new javax.swing.JButton(); + jButtonDeleteStream = new javax.swing.JButton(); + jTabbedPane1 = new javax.swing.JTabbedPane(); + jPanel2 = new javax.swing.JPanel(); + jButtonAcept = new javax.swing.JButton(); + jButtonReset = new javax.swing.JButton(); + jScrollPane1 = new javax.swing.JScrollPane(); + jPanel4 = new javax.swing.JPanel(); + jLabel17 = new javax.swing.JLabel(); + jTextFieldxTitle = new javax.swing.JTextField(); + jLabel18 = new javax.swing.JLabel(); + jLabel19 = new javax.swing.JLabel(); + jTextFieldyTitle = new javax.swing.JTextField(); + jLabel20 = new javax.swing.JLabel(); + jComboBoxXColumn = new javax.swing.JComboBox(); + jComboBoxYColumn = new javax.swing.JComboBox(); + jTextFieldTitle = new javax.swing.JTextField(); + jLabel21 = new javax.swing.JLabel(); + jSpinnerWidth = new javax.swing.JSpinner(); + jSpinnerHeight = new javax.swing.JSpinner(); + jLabel22 = new javax.swing.JLabel(); + jLabel23 = new javax.swing.JLabel(); + jComboBoxGrid = new javax.swing.JComboBox(); + jCheckBoxShape = new javax.swing.JCheckBox(); + jLabel2 = new javax.swing.JLabel(); + jPanel3 = new javax.swing.JPanel(); + jButtonAceptGnuP = new javax.swing.JButton(); + jButtonResetGnuP = new javax.swing.JButton(); + jScrollPaneGnuP = new javax.swing.JScrollPane(); + jPanelGnuP = new javax.swing.JPanel(); + jTextFieldGNUPath = new javax.swing.JTextField(); + jLabel1 = new javax.swing.JLabel(); + jButtonGnuoPath = new javax.swing.JButton(); + jComboBoxOutPTypeGnuP = new javax.swing.JComboBox(); + jLabel5 = new javax.swing.JLabel(); + jComboBoxLineStyle = new javax.swing.JComboBox(); + jLabel6 = new javax.swing.JLabel(); + jLabel7 = new javax.swing.JLabel(); + jTextFieldxTitleGnuP = new javax.swing.JTextField(); + jLabel8 = new javax.swing.JLabel(); + jLabel10 = new javax.swing.JLabel(); + jTextFieldyTitleGnuP = new javax.swing.JTextField(); + jLabel11 = new javax.swing.JLabel(); + jSpinnerLineWidth = new javax.swing.JSpinner(); + jSpinnerPlotInterval = new javax.swing.JSpinner(); + jLabel13 = new javax.swing.JLabel(); + jLabel14 = new javax.swing.JLabel(); + jCheckBoxSmooth = new javax.swing.JCheckBox(); + jLabel15 = new javax.swing.JLabel(); + jCheckBoxDeleteScript = new javax.swing.JCheckBox(); + jLabel16 = new javax.swing.JLabel(); + jComboBoxLegendLocation = new javax.swing.JComboBox(); + jLabel24 = new javax.swing.JLabel(); + jComboBoxLegendType = new javax.swing.JComboBox(); + jLabel25 = new javax.swing.JLabel(); + jTextFieldAdcComand = new javax.swing.JTextField(); + jLabel26 = new javax.swing.JLabel(); + jTextFieldAPOptions = new javax.swing.JTextField(); + jLabel27 = new javax.swing.JLabel(); + jComboBoxXColumnGnuP = new javax.swing.JComboBox(); + jComboBoxYColumnGnuP = new javax.swing.JComboBox(); + + jPanel1.setBorder(javax.swing.BorderFactory.createTitledBorder("Configuration")); + + jScrollPaneAlgorithms.setBorder(javax.swing.BorderFactory.createTitledBorder("Algorithm")); + + jTableAlgoritms.setBorder(javax.swing.BorderFactory.createTitledBorder("")); + jTableAlgoritms.setModel(new javax.swing.table.DefaultTableModel( + new Object [][] { + + }, + new String [] { + "Algorithm", "Algorithm ID" + } + )); + jScrollPaneAlgorithms.setViewportView(jTableAlgoritms); + + jScrollPane3.setBorder(javax.swing.BorderFactory.createTitledBorder("Stream")); + + jTableStreams.setBorder(javax.swing.BorderFactory.createTitledBorder("")); + jTableStreams.setModel(new javax.swing.table.DefaultTableModel( + new Object [][] { + + }, + new String [] { + "Stream", "Stream ID" + } + )); + jScrollPane3.setViewportView(jTableStreams); + + jButtonInPath.setText("Browse"); + jButtonInPath.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jButtonInPathActionPerformed(evt); + } + }); + + jLabel3.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT); + jLabel3.setText("Result folder"); + + jButtonDeletAlgorithm.setText("Delete Algorithm"); + jButtonDeletAlgorithm.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jButtonDeletAlgorithmActionPerformed(evt); + } + }); + + jButtonDeleteStream.setText("Delete Stream"); + jButtonDeleteStream.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jButtonDeleteStreamActionPerformed(evt); + } + }); + + javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1); + jPanel1.setLayout(jPanel1Layout); + jPanel1Layout.setHorizontalGroup( + jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel1Layout.createSequentialGroup() + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup() + .addGap(14, 14, 14) + .addComponent(jLabel3) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jTextFieldResultPath) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(jButtonInPath)) + .addGroup(jPanel1Layout.createSequentialGroup() + .addContainerGap() + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jButtonDeletAlgorithm) + .addComponent(jScrollPaneAlgorithms, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jScrollPane3, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE) + .addGroup(jPanel1Layout.createSequentialGroup() + .addComponent(jButtonDeleteStream) + .addGap(0, 0, Short.MAX_VALUE))))) + .addGap(16, 16, 16)) + ); + jPanel1Layout.setVerticalGroup( + jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup() + .addGap(23, 23, 23) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jTextFieldResultPath, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jButtonInPath) + .addComponent(jLabel3)) + .addGap(18, 18, 18) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jScrollPaneAlgorithms, javax.swing.GroupLayout.DEFAULT_SIZE, 89, Short.MAX_VALUE) + .addComponent(jScrollPane3, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jButtonDeleteStream) + .addComponent(jButtonDeletAlgorithm))) + ); + + jButtonAcept.setText("Generate Images"); + jButtonAcept.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jButtonAceptActionPerformed(evt); + } + }); + + jButtonReset.setText(" Reset to Default"); + jButtonReset.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jButtonResetActionPerformed(evt); + } + }); + + jScrollPane1.setBorder(javax.swing.BorderFactory.createTitledBorder("")); + jScrollPane1.setHorizontalScrollBarPolicy(javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); + + jPanel4.setBorder(javax.swing.BorderFactory.createTitledBorder("")); + + jLabel17.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT); + jLabel17.setText("xColumn"); + + jTextFieldxTitle.setText("Instances processed"); + + jLabel18.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT); + jLabel18.setText("xTitle"); + + jLabel19.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT); + jLabel19.setText("yColumn"); + + jTextFieldyTitle.setText("% of correctly classified"); + + jLabel20.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT); + jLabel20.setText("yTitle"); + + jLabel21.setText("title"); + + jSpinnerWidth.setValue(500); + + jSpinnerHeight.setValue(300); + + jLabel22.setText("width"); + + jLabel23.setText("height"); + + jComboBoxGrid.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "White", "Default" })); + + jCheckBoxShape.setText("shapes"); + + jLabel2.setText("gridColor"); + + javax.swing.GroupLayout jPanel4Layout = new javax.swing.GroupLayout(jPanel4); + jPanel4.setLayout(jPanel4Layout); + jPanel4Layout.setHorizontalGroup( + jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel4Layout.createSequentialGroup() + .addGap(67, 67, 67) + .addGroup(jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) + .addGroup(jPanel4Layout.createSequentialGroup() + .addGap(3, 3, 3) + .addGroup(jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) + .addComponent(jLabel17) + .addComponent(jLabel21) + .addComponent(jLabel18)) + .addComponent(jLabel19) + .addComponent(jLabel20, javax.swing.GroupLayout.Alignment.TRAILING) + .addComponent(jLabel22, javax.swing.GroupLayout.Alignment.TRAILING)) + .addGap(18, 18, 18) + .addGroup(jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jTextFieldxTitle) + .addComponent(jComboBoxXColumn, javax.swing.GroupLayout.Alignment.TRAILING, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(jTextFieldTitle, javax.swing.GroupLayout.Alignment.TRAILING) + .addComponent(jComboBoxYColumn, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(jTextFieldyTitle, javax.swing.GroupLayout.DEFAULT_SIZE, 542, Short.MAX_VALUE) + .addComponent(jSpinnerWidth))) + .addGroup(javax.swing.GroupLayout.Alignment.LEADING, jPanel4Layout.createSequentialGroup() + .addGroup(jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) + .addComponent(jLabel23) + .addComponent(jLabel2)) + .addGap(18, 18, 18) + .addGroup(jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel4Layout.createSequentialGroup() + .addComponent(jCheckBoxShape, javax.swing.GroupLayout.PREFERRED_SIZE, 91, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(0, 0, Short.MAX_VALUE)) + .addComponent(jComboBoxGrid, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(jSpinnerHeight)))) + .addGap(30, 30, 30)) + ); + jPanel4Layout.setVerticalGroup( + jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel4Layout.createSequentialGroup() + .addContainerGap() + .addGroup(jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jTextFieldTitle, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel21)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jComboBoxXColumn, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel17)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jTextFieldxTitle, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel18)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jComboBoxYColumn, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel19)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addGroup(jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jTextFieldyTitle, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel20)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jSpinnerWidth, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel22)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel23) + .addComponent(jSpinnerHeight, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jComboBoxGrid, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel2)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jCheckBoxShape) + .addContainerGap(11, Short.MAX_VALUE)) + ); + + jScrollPane1.setViewportView(jPanel4); + + javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2); + jPanel2.setLayout(jPanel2Layout); + jPanel2Layout.setHorizontalGroup( + jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel2Layout.createSequentialGroup() + .addGap(135, 135, 135) + .addComponent(jButtonAcept) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jButtonReset) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addComponent(jScrollPane1, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 700, Short.MAX_VALUE) + ); + jPanel2Layout.setVerticalGroup( + jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel2Layout.createSequentialGroup() + .addContainerGap() + .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 247, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jButtonAcept) + .addComponent(jButtonReset))) + ); + + jTabbedPane1.addTab("Charts", jPanel2); + + jButtonAceptGnuP.setText("Generate GnuPlot Commands"); + jButtonAceptGnuP.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jButtonAceptGnuPActionPerformed(evt); + } + }); + + jButtonResetGnuP.setText(" Reset to Default"); + jButtonResetGnuP.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jButtonResetGnuPActionPerformed(evt); + } + }); + + jScrollPaneGnuP.setBorder(javax.swing.BorderFactory.createTitledBorder("")); + jScrollPaneGnuP.setHorizontalScrollBarPolicy(javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); + + jPanelGnuP.setBorder(javax.swing.BorderFactory.createTitledBorder("")); + jPanelGnuP.setPreferredSize(new java.awt.Dimension(400, 449)); + + jTextFieldGNUPath.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jTextFieldGNUPathActionPerformed(evt); + } + }); + + jLabel1.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT); + jLabel1.setText("gnuplotBinaryPath "); + + jButtonGnuoPath.setText("Browse"); + jButtonGnuoPath.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jButtonGnuoPathActionPerformed(evt); + } + }); + + jComboBoxOutPTypeGnuP.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "POSTSCRIPT_COLOR", "EPSLATEX", "GIF", "JPEG", "LATEX", "PDFCAIRO", "PNG", "POSTSCRIPT", "CANVAS", "PSLATEX", "PSTEX", "PSTRICKS", "SVG" })); + + jLabel5.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT); + jLabel5.setText("outputType"); + + jComboBoxLineStyle.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "LINES", "POINTS", "LINESPOINTS", "IMPULSES", "STEPS", "FSTEPS", "HISTEPS", "DOTS;" })); + + jLabel6.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT); + jLabel6.setText("plotStyle"); + + jLabel7.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT); + jLabel7.setText("xColumn"); + + jTextFieldxTitleGnuP.setText("Processed instances"); + + jLabel8.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT); + jLabel8.setText("xTitle"); + + jLabel10.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT); + jLabel10.setText("yColumn"); + + jTextFieldyTitleGnuP.setText("Accuracy"); + + jLabel11.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT); + jLabel11.setText("yTitle"); + + jSpinnerLineWidth.setValue(2); + + jLabel13.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT); + jLabel13.setText("lineWidth"); + + jLabel14.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT); + jLabel14.setText("plotInterval"); + + jLabel15.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT); + jLabel15.setText("smooth"); + + jLabel16.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT); + jLabel16.setText("deleteScripts"); + + jComboBoxLegendLocation.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "BOTTOM_CENTER_OUTSIDE", "TOP_LEFT_INSIDE", "TOP_CENTER_INSIDE", "TOP_RIGHT_INSIDE", "LEFT_INSIDE", "CENTER_INSIDE", "RIGHT_INSIDE", "BOTTOM_LEFT_INSIDE", "BOTTOM_CENTER_INSIDE", "BOTTOM_RIGHT_INSIDE", "TOP_LEFT_OUTSIDE", "TOP_CENTER_OUTSIDE", "TOP_RIGHT_OUTSIDE", "LEFT_OUTSIDE", "CENTER_OUTSIDE", "RIGHT_OUTSIDE", "BOTTOM_LEFT_OUTSIDE", "BOTTOM_RIGHT_OUTSIDE" })); + jComboBoxLegendLocation.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jComboBoxLegendLocationActionPerformed(evt); + } + }); + + jLabel24.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT); + jLabel24.setText("legendLocation"); + + jComboBoxLegendType.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "NOBOX_HORIZONTAL", "BOX_VERTICAL", "BOX_HORIZONTAL", "NOBOX_VERTICAL", " " })); + + jLabel25.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT); + jLabel25.setText("legendType"); + + jLabel26.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT); + jLabel26.setText("additionalCommands"); + + jLabel27.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT); + jLabel27.setText("additionalPlotOptions"); + + javax.swing.GroupLayout jPanelGnuPLayout = new javax.swing.GroupLayout(jPanelGnuP); + jPanelGnuP.setLayout(jPanelGnuPLayout); + jPanelGnuPLayout.setHorizontalGroup( + jPanelGnuPLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanelGnuPLayout.createSequentialGroup() + .addGroup(jPanelGnuPLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanelGnuPLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanelGnuPLayout.createSequentialGroup() + .addGap(22, 22, 22) + .addGroup(jPanelGnuPLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jLabel5, javax.swing.GroupLayout.Alignment.TRAILING) + .addComponent(jLabel6, javax.swing.GroupLayout.Alignment.TRAILING) + .addComponent(jLabel7, javax.swing.GroupLayout.Alignment.TRAILING) + .addComponent(jLabel8, javax.swing.GroupLayout.Alignment.TRAILING) + .addComponent(jLabel10, javax.swing.GroupLayout.Alignment.TRAILING) + .addComponent(jLabel11, javax.swing.GroupLayout.Alignment.TRAILING) + .addComponent(jLabel1, javax.swing.GroupLayout.Alignment.TRAILING))) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanelGnuPLayout.createSequentialGroup() + .addContainerGap() + .addComponent(jLabel27))) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanelGnuPLayout.createSequentialGroup() + .addContainerGap() + .addGroup(jPanelGnuPLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jLabel15, javax.swing.GroupLayout.Alignment.TRAILING) + .addComponent(jLabel13, javax.swing.GroupLayout.Alignment.TRAILING) + .addComponent(jLabel14, javax.swing.GroupLayout.Alignment.TRAILING) + .addComponent(jLabel16, javax.swing.GroupLayout.Alignment.TRAILING) + .addComponent(jLabel24, javax.swing.GroupLayout.Alignment.TRAILING) + .addComponent(jLabel25, javax.swing.GroupLayout.Alignment.TRAILING) + .addComponent(jLabel26, javax.swing.GroupLayout.Alignment.TRAILING)))) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(jPanelGnuPLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jTextFieldAPOptions, javax.swing.GroupLayout.Alignment.TRAILING) + .addComponent(jTextFieldAdcComand, javax.swing.GroupLayout.Alignment.TRAILING) + .addComponent(jComboBoxLegendType, javax.swing.GroupLayout.Alignment.TRAILING, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(jSpinnerPlotInterval, javax.swing.GroupLayout.Alignment.TRAILING) + .addComponent(jSpinnerLineWidth, javax.swing.GroupLayout.Alignment.TRAILING) + .addComponent(jTextFieldyTitleGnuP, javax.swing.GroupLayout.Alignment.TRAILING) + .addComponent(jTextFieldxTitleGnuP, javax.swing.GroupLayout.Alignment.TRAILING) + .addComponent(jComboBoxLineStyle, javax.swing.GroupLayout.Alignment.TRAILING, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(jComboBoxXColumnGnuP, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(jComboBoxYColumnGnuP, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(jComboBoxLegendLocation, 0, 542, Short.MAX_VALUE) + .addGroup(jPanelGnuPLayout.createSequentialGroup() + .addComponent(jTextFieldGNUPath) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jButtonGnuoPath)) + .addGroup(jPanelGnuPLayout.createSequentialGroup() + .addGroup(jPanelGnuPLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jCheckBoxDeleteScript) + .addComponent(jCheckBoxSmooth)) + .addGap(0, 0, Short.MAX_VALUE)) + .addComponent(jComboBoxOutPTypeGnuP, javax.swing.GroupLayout.Alignment.TRAILING, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addContainerGap()) + ); + jPanelGnuPLayout.setVerticalGroup( + jPanelGnuPLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanelGnuPLayout.createSequentialGroup() + .addContainerGap() + .addGroup(jPanelGnuPLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jTextFieldGNUPath, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jButtonGnuoPath) + .addComponent(jLabel1)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanelGnuPLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jComboBoxOutPTypeGnuP, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel5)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanelGnuPLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jComboBoxLineStyle, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel6)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanelGnuPLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jComboBoxXColumnGnuP, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel7)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanelGnuPLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jTextFieldxTitleGnuP, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel8)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanelGnuPLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jComboBoxYColumnGnuP, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel10)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanelGnuPLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jTextFieldyTitleGnuP, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel11)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanelGnuPLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jSpinnerLineWidth, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel13)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanelGnuPLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jSpinnerPlotInterval, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel14)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanelGnuPLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jCheckBoxSmooth) + .addComponent(jLabel15)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanelGnuPLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jCheckBoxDeleteScript) + .addComponent(jLabel16)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanelGnuPLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jComboBoxLegendLocation, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel24)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanelGnuPLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jComboBoxLegendType, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel25)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanelGnuPLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jTextFieldAdcComand, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel26)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanelGnuPLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jTextFieldAPOptions, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel27)) + .addGap(186, 186, 186)) + ); + + jScrollPaneGnuP.setViewportView(jPanelGnuP); + + javax.swing.GroupLayout jPanel3Layout = new javax.swing.GroupLayout(jPanel3); + jPanel3.setLayout(jPanel3Layout); + jPanel3Layout.setHorizontalGroup( + jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel3Layout.createSequentialGroup() + .addGap(128, 128, 128) + .addComponent(jButtonAceptGnuP) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jButtonResetGnuP) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addComponent(jScrollPaneGnuP, javax.swing.GroupLayout.DEFAULT_SIZE, 700, Short.MAX_VALUE) + ); + jPanel3Layout.setVerticalGroup( + jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel3Layout.createSequentialGroup() + .addContainerGap() + .addComponent(jScrollPaneGnuP, javax.swing.GroupLayout.PREFERRED_SIZE, 247, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jButtonAceptGnuP) + .addComponent(jButtonResetGnuP))) + ); + + jTabbedPane1.addTab("GnuPlot", jPanel3); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); + this.setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(jTabbedPane1, javax.swing.GroupLayout.Alignment.TRAILING)) + .addContainerGap()) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() + .addContainerGap() + .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(jTabbedPane1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(7, 7, 7)) + ); + }// </editor-fold>//GEN-END:initComponents + + private void jButtonInPathActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonInPathActionPerformed + path = getDirectory("open", JFileChooser.DIRECTORIES_ONLY); + if (!path.equals("")) { + reset(); + resetP(); + this.jTextFieldResultPath.setText(path); + rf = new ReadFile(path); + String str = rf.processFiles(); + if (str.equals("")) { + + int algSize = rf.getAlgShortNames().size(); + int streamSize = rf.getStream().size(); + this.measures = rf.getMeasures(); + for (int i = 0; i < algSize; i++) { + this.algoritmModel.addRow(new Object[]{rf.getAlgNames().get(i), rf.getAlgShortNames().get(i)}); + } + for (int i = 0; i < streamSize; i++) { + this.streamModel.addRow(new Object[]{rf.getStream().get(i), rf.getStream().get(i)}); + } + + String measuresNames[] = measures.getFirst().split(","); + for (String measuresName : measuresNames) { + jComboBoxXColumn.addItem(measuresName); + jComboBoxYColumn.addItem(measuresName); + jComboBoxXColumnGnuP.addItem(measuresName); + jComboBoxYColumnGnuP.addItem(measuresName); + if (measuresName.equals("learning evaluation instances") == true) { + jComboBoxXColumn.setSelectedItem(measuresName); + jComboBoxXColumnGnuP.setSelectedItem(measuresName); + } + if (measuresName.equals("classifications correct (percent)") == true + || measuresName.equals("[avg] classifications correct (percent)") == true) { + jComboBoxYColumn.setSelectedItem(measuresName); + jComboBoxYColumnGnuP.setSelectedItem(measuresName); + } + + } + } else { + + JOptionPane.showMessageDialog(this, str, + "Error", JOptionPane.ERROR_MESSAGE); + } + } + }//GEN-LAST:event_jButtonInPathActionPerformed + + private void jButtonDeletAlgorithmActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonDeletAlgorithmActionPerformed + if (this.jTableAlgoritms.getSelectedRow() != -1) { + + this.algoritmModel.removeRow(this.jTableAlgoritms.getSelectedRow()); + String algorithms[] = new String[algoritmModel.getRowCount()]; + for (int i = 0; i < algoritmModel.getRowCount(); i++) { + algorithms[i] = algoritmModel.getValueAt(i, 0).toString(); + } + if (streamModel.getValueAt(0, 0).toString() != null) { + String s = streamModel.getValueAt(0, 0).toString(); + rf.updateMeasures(algorithms, s); + this.measures = rf.getMeasures(); + String measuresNames[] = measures.getFirst().split(","); + jComboBoxXColumn.removeAllItems(); + jComboBoxYColumn.removeAllItems(); + jComboBoxXColumnGnuP.removeAllItems(); + jComboBoxYColumnGnuP.removeAllItems(); + for (String measuresName : measuresNames) { + jComboBoxXColumn.addItem(measuresName); + jComboBoxYColumn.addItem(measuresName); + jComboBoxXColumnGnuP.addItem(measuresName); + jComboBoxYColumnGnuP.addItem(measuresName); + if (measuresName.equals("learning evaluation instances") == true) { + jComboBoxXColumn.setSelectedItem(measuresName); + jComboBoxXColumnGnuP.setSelectedItem(measuresName); + } + if (measuresName.equals("classifications correct (percent)") == true || measuresName.equals("[avg] classifications correct (percent)")) { + jComboBoxYColumn.setSelectedItem(measuresName); + jComboBoxYColumnGnuP.setSelectedItem(measuresName); + } + + } + } + } + }//GEN-LAST:event_jButtonDeletAlgorithmActionPerformed + + private void jButtonDeleteStreamActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonDeleteStreamActionPerformed + this.streamModel.removeRow(this.jTableStreams.getSelectedRow()); + }//GEN-LAST:event_jButtonDeleteStreamActionPerformed + + private void jButtonAceptActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonAceptActionPerformed + + int algCount = this.jTableAlgoritms.getRowCount(); + int streamCount = this.jTableStreams.getRowCount(); + chart = new ImageChart[streamCount]; + + for (int i = 0; i < streamCount; i++) { + String streamName = this.jTableStreams.getModel().getValueAt(i, 0).toString(); + String streamID = this.jTableStreams.getModel().getValueAt(i, 1).toString(); + XYSeriesCollection dataset = new XYSeriesCollection(); + for (int j = 0; j < algCount; j++) { + try { + String algName = this.jTableAlgoritms.getModel().getValueAt(j, 0).toString(); + String algID = this.jTableAlgoritms.getModel().getValueAt(j, 1).toString(); + String algPath = FilenameUtils.separatorsToSystem( + this.path + "\\" + streamName + "\\" + algName); + File inputFile = new File(algPath); + if (!inputFile.exists()) { + JOptionPane.showMessageDialog(this, "File not found: " + + inputFile.getAbsolutePath(), + "Error", JOptionPane.ERROR_MESSAGE); + return; + } + /*Preparing the graph*/ + ArrayList<String[]> data = readCSV(algPath); + XYSeries series = new XYSeries(algID); + int x = ReadFile.getMeasureIndex(algPath,this.jComboBoxXColumn.getSelectedItem().toString()); + int y = ReadFile.getMeasureIndex(algPath,this.jComboBoxYColumn.getSelectedItem().toString()); + + for (String[] s : data) { + series.add(Double.parseDouble(s[x]), Double.parseDouble(s[y])); + } + + dataset.addSeries(series); + + } catch (FileNotFoundException ex) { + Logger.getLogger(PlotTab.class.getName()).log(Level.SEVERE, null, ex); + } catch (IOException ex) { + Logger.getLogger(PlotTab.class.getName()).log(Level.SEVERE, null, ex); + } + }//end for + /*Create chart*/ + JFreeChart imgChart = ChartFactory.createXYLineChart( + this.jTextFieldTitle.getText(), // Title + this.jTextFieldxTitle.getText(), // x-axis Label + this.jTextFieldyTitle.getText(), // y-axis Label + dataset, // Dataset + PlotOrientation.VERTICAL, // Plot Orientation + true, // Show Legend + true, // Use tooltips + false // Configure chart to generate URLs? + ); + final XYPlot plot = imgChart.getXYPlot(); + switch (this.jComboBoxGrid.getSelectedItem().toString()) { + case "White": + plot.setBackgroundPaint(Color.white); + break; + case "Default": + plot.setBackgroundPaint(Color.lightGray); + } + if (this.jCheckBoxShape.isSelected()) { + final XYLineAndShapeRenderer renderer = new XYLineAndShapeRenderer(); + renderer.setSeriesLinesVisible(0, true); + renderer.setSeriesShapesVisible(1, false); + for (int k = 0; k < algCount; k++) { + renderer.setSeriesPaint(k, Color.black); + } + plot.setRenderer(renderer); + } + + this.chart[i] = new ImageChart(streamID, imgChart, + (int) this.jSpinnerWidth.getValue(), (int) this.jSpinnerHeight.getValue()); + + } + this.imgPanel = new ImageTreePanel(chart); + new ImageViewer(imgPanel, path); + + }//GEN-LAST:event_jButtonAceptActionPerformed + + private void jButtonResetActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonResetActionPerformed + reset(); + }//GEN-LAST:event_jButtonResetActionPerformed + + private void jButtonAceptGnuPActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonAceptGnuPActionPerformed + + if (!this.jTextFieldResultPath.getText().equals("")) { + String outPath = getDirectory("open", JFileChooser.DIRECTORIES_ONLY); + if(!outPath.equals("")){ + + File resultFile = new File(this.jTextFieldResultPath.getText()); + String resultDirectory = resultFile.getAbsolutePath(); + String gnuPlotPath = this.jTextFieldGNUPath.getText(); + String gnuplotScriptPath = null; + File gnuplotDir = new File(gnuPlotPath); + if (!gnuplotDir.exists()) { + JOptionPane.showMessageDialog(this, "Gnuplot directory not found: " + gnuPlotPath, "Error", JOptionPane.ERROR_MESSAGE); + return; + } + String algShortName[] = new String[this.jTableAlgoritms.getRowCount()]; + String algName[] = new String[this.jTableAlgoritms.getRowCount()]; + for (int i = 0; i < this.jTableStreams.getRowCount(); i++) { + String streamName = this.jTableStreams.getModel().getValueAt(i, 0).toString(); + String streamShortName = this.jTableStreams.getModel().getValueAt(i, 1).toString(); + for (int j = 0; j < this.jTableAlgoritms.getRowCount(); j++) { + algName[j] = this.jTableAlgoritms.getModel().getValueAt(j, 0).toString(); + algShortName[j] = this.jTableAlgoritms.getModel().getValueAt(j, 1).toString(); + File inputFile = new File(FilenameUtils.separatorsToSystem( + this.path + "\\" + streamName + "\\" + algName[j])); + + if (!inputFile.exists()) { + JOptionPane.showMessageDialog(this, "File not found: " + + inputFile.getAbsolutePath(), + "Error", JOptionPane.ERROR_MESSAGE); + return; + } + + } + + gnuplotScriptPath = resultDirectory + File.separator + + resultFile.getName() + ".plt"; + String script = createScript(streamName, algName, algShortName, outPath); + File scriptFile = writeScriptToFile(gnuplotScriptPath, script); + String gnuplotCommand = gnuPlotPath + File.separator + "gnuplot \"" + + gnuplotScriptPath + "\""; + String line, gnuplotOutput = ""; + try { + Process p = Runtime.getRuntime().exec(gnuplotCommand); + + BufferedReader err = new BufferedReader(new InputStreamReader(p + .getErrorStream())); + while ((line = err.readLine()) != null) { + gnuplotOutput += line + System.getProperty("line.separator"); + } + err.close(); + } catch (IOException ex) { + JOptionPane.showMessageDialog(this, "Error while executing gnuplot script", + "Error", JOptionPane.ERROR_MESSAGE); + throw new RuntimeException("Error while executing gnuplot script:" + + scriptFile, ex); + + } + if (this.jCheckBoxDeleteScript.isSelected()) { + scriptFile.delete(); + } + } + + //Completed + JOptionPane.showMessageDialog(this, "Figures created at " + (new File(resultFile.getAbsolutePath())).getParent(), + "", JOptionPane.INFORMATION_MESSAGE); + } + } else { + JOptionPane.showMessageDialog(this, "Plot output file option not set!", + "Error", JOptionPane.ERROR_MESSAGE); + } + + }//GEN-LAST:event_jButtonAceptGnuPActionPerformed + + private void jButtonResetGnuPActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonResetGnuPActionPerformed + resetP(); + }//GEN-LAST:event_jButtonResetGnuPActionPerformed + + private void jButtonGnuoPathActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonGnuoPathActionPerformed + this.jTextFieldGNUPath.setText(getDirectory("open", JFileChooser.DIRECTORIES_ONLY)); + }//GEN-LAST:event_jButtonGnuoPathActionPerformed + + private void jComboBoxLegendLocationActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jComboBoxLegendLocationActionPerformed + // TODO add your handling code here: + }//GEN-LAST:event_jComboBoxLegendLocationActionPerformed + + private void jTextFieldGNUPathActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jTextFieldGNUPathActionPerformed + // TODO add your handling code here: + }//GEN-LAST:event_jTextFieldGNUPathActionPerformed + + /** + * Allows to read the results file and update the corresponding fields. + * + * @param path + */ + public void readData(String path) { + reset(); + resetP(); + this.jTextFieldResultPath.setText(path); + this.path = path; + rf = new ReadFile(path); + String str = rf.processFiles(); + if (str.equals("")) { + + int algSize = rf.getAlgShortNames().size(); + int streamSize = rf.getStream().size(); + this.measures = rf.getMeasures(); + for (int i = 0; i < algSize; i++) { + this.algoritmModel.addRow(new Object[]{rf.getAlgNames().get(i), rf.getAlgShortNames().get(i)}); + } + for (int i = 0; i < streamSize; i++) { + this.streamModel.addRow(new Object[]{rf.getStream().get(i), rf.getStream().get(i)}); + } + String measuresNames[] = measures.getFirst().split(","); + for (String measuresName : measuresNames) { + jComboBoxXColumn.addItem(measuresName); + jComboBoxYColumn.addItem(measuresName); + jComboBoxXColumnGnuP.addItem(measuresName); + jComboBoxYColumnGnuP.addItem(measuresName); + if (measuresName.equals("learning evaluation instances") == true) { + jComboBoxXColumn.setSelectedItem(measuresName); + jComboBoxXColumnGnuP.setSelectedItem(measuresName); + } + if (measuresName.equals("classifications correct (percent)") == true || measuresName.equals("[avg] classifications correct (percent)")) { + jComboBoxYColumn.setSelectedItem(measuresName); + jComboBoxYColumnGnuP.setSelectedItem(measuresName); + } + + } + } else { + + JOptionPane.showMessageDialog(this, str, + "Error", JOptionPane.ERROR_MESSAGE); + } + + } + + private String getDirectory(String type, int filter) { + BaseDirectoryChooser gnuPlotDir = new BaseDirectoryChooser(); + gnuPlotDir.setFileSelectionMode(filter); + int selection = -1; + if (type.equals("open")) + selection = gnuPlotDir.showOpenDialog(this); + if (selection == JFileChooser.APPROVE_OPTION) { + + try { + return gnuPlotDir.getSelectedFile().getAbsolutePath(); + + } catch (Exception exp) { + } + + } + return ""; + } + + /** + * Clean the tables + */ + public void cleanTables() { + try { + DefaultTableModel algModel = (DefaultTableModel) jTableAlgoritms.getModel(); + DefaultTableModel strModel = (DefaultTableModel) jTableStreams.getModel(); + int rows = jTableAlgoritms.getRowCount(); + int srow = jTableStreams.getRowCount(); + for (int i = 0; i < rows; i++) { + algModel.removeRow(0); + } + for (int i = 0; i < srow; i++) { + strModel.removeRow(0); + } + + } catch (Exception e) { + JOptionPane.showMessageDialog(null, "Error cleaning the table."); + } + } + + private void reset() { + cleanTables(); + this.jTextFieldResultPath.setText(""); + + this.jTextFieldxTitle.setText("Instances processed"); + + this.jTextFieldyTitle.setText("% of correctly classified"); + + //Combobox + this.jComboBoxXColumn.removeAllItems(); + this.jComboBoxYColumn.removeAllItems(); + //spinner + this.jSpinnerWidth.setValue(500); + this.jSpinnerHeight.setValue(300); + + this.jCheckBoxShape.setSelected(false); + this.jComboBoxGrid.setSelectedItem("White"); + + } + + private void resetP() { + cleanTables(); + this.jTextFieldGNUPath.setText(""); + this.jTextFieldResultPath.setText(""); + this.jTextFieldAPOptions.setText(""); + this.jTextFieldAdcComand.setText(""); + this.jTextFieldxTitleGnuP.setText("Instances processed"); + this.jTextFieldyTitleGnuP.setText("% of correctly classified"); + //Combobox + this.jComboBoxLegendLocation.setSelectedIndex(0); + + this.jComboBoxLegendType.setSelectedIndex(0); + this.jComboBoxLineStyle.setSelectedIndex(0); + this.jComboBoxOutPTypeGnuP.setSelectedIndex(0); + this.jComboBoxXColumnGnuP.removeAllItems(); + this.jComboBoxYColumnGnuP.removeAllItems(); + //spinner + this.jSpinnerLineWidth.setValue(2); + this.jSpinnerPlotInterval.setValue(0); + + } + + private String createScript(String streamName, String algName[], String algShortName[], String outPath) { + String newLine = System.getProperty("line.separator"); + int sourceFileIdx = 0; + + String imgName; + boolean eps = false; + switch (this.jComboBoxOutPTypeGnuP.getSelectedItem().toString()) { + case "GIF": + imgName = outPath + File.separator + streamName + "GP" + ".gif"; + break; + case "JPEG": + imgName = outPath + File.separator + streamName + "GP" + ".JPEG"; + break; + case "LATEX": + imgName = outPath + File.separator + streamName + "GP" + ".tex"; + break; + case "PDFCAIRO": + imgName = outPath + File.separator + streamName + "GP" + ".pdf"; + break; + case "PNG": + imgName = outPath + File.separator + streamName + "GP" + ".PNG"; + break; + case "PSTEX": + imgName = outPath + File.separator + streamName + "GP" + ".tex"; + break; + case "PSTRICKS": + imgName = outPath + File.separator + streamName + "GP" + ".tex"; + break; + case "PSLATEX": + imgName = outPath + File.separator + streamName + "GP" + ".tex"; + break; + case "SVG": + imgName = outPath + File.separator + streamName + "GP" + ".SVG"; + break; + default: + imgName = outPath + File.separator + streamName + "GP" + ".eps"; + eps = true; + + } + // terminal options; + String script; + if (eps) { + script = "set term " + + terminalOptions(Terminal.valueOf(this.jComboBoxOutPTypeGnuP.getSelectedItem().toString())) + " eps " + newLine; + } else { + script = "set term " + + terminalOptions(Terminal.valueOf(this.jComboBoxOutPTypeGnuP.getSelectedItem().toString())) + newLine; + } + script += "set loadpath '" + FilenameUtils.separatorsToSystem(path + File.separator + streamName) + "'" + newLine; + script += "set output '" + imgName + "'" + newLine; + script += "set datafile separator ','" + newLine; + //script += "set grid" + newLine; + script += "set style line 1 pt 8" + newLine; + script += "set style line 2 lt rgb '#00C000'" + newLine; + script += "set style line 5 lt rgb '#FFD800'" + newLine; + script += "set style line 6 lt rgb '#4E0000'" + newLine; +// script += "set format x '%.0s %c" + getAxisUnit(this.jTextFieldxUnit.getText()) +// + "'" + newLine; +// script += "set format y '%.1f" + getAxisUnit(this.jTextFieldyUnit.getText()) +// + "'" + newLine; + script += "set ylabel '" + this.jTextFieldyTitleGnuP.getText() + "'" + newLine; + script += "set xlabel '" + this.jTextFieldxTitleGnuP.getText() + "'" + newLine; + if (!this.jComboBoxLegendType.getSelectedItem().toString().equals(LegendType.NONE)) { + script += "set key " + + this.jComboBoxLegendType.getSelectedItem().toString().toLowerCase().replace( + '_', ' ') + + " " + + this.jComboBoxLegendLocation.getSelectedItem().toString().toLowerCase() + .replace('_', ' ') + newLine; + } + + // additional commands + script += this.jTextFieldAdcComand.getText(); + + // plot command + script += "plot " + this.jTextFieldAPOptions.getText() + " "; + + // plot for each input file + for (int i = 0; i < algName.length; i++) { + + if (sourceFileIdx > 0) { + script += ", "; + } + sourceFileIdx++; + script += "'" + algName[i] + "' using " + + (this.jComboBoxXColumnGnuP.getSelectedIndex() + 1) + ":" + (this.jComboBoxYColumnGnuP.getSelectedIndex() + 1); + + if (this.jCheckBoxSmooth.isSelected()) { + script += ":(1.0) smooth bezier"; + } + + script += " with " + this.jComboBoxLineStyle.getSelectedItem().toString().toLowerCase() + + " ls " + sourceFileIdx + " lw " + + this.jSpinnerLineWidth.getValue().toString(); + if (this.jComboBoxLineStyle.getSelectedItem().toString().equals( + PlotStyle.LINESPOINTS.toString()) + && Integer.parseInt(this.jSpinnerPlotInterval.getValue().toString()) > 0) { + script += " pointinterval " + this.jSpinnerPlotInterval.getValue().toString(); + } + script += " title '" + algShortName[i] + "'"; + } + script += newLine; + return script; + } + + private File writeScriptToFile(String gnuplotScriptPath, String script) { + File scriptFile = new File(gnuplotScriptPath); + BufferedWriter writer; + try { + writer = new BufferedWriter(new FileWriter(scriptFile)); + writer.write(script); + writer.close(); + } catch (IOException ex) { + throw new RuntimeException( + "Unable to create or write to script file: " + scriptFile, + ex); + } + return scriptFile; + } + + private String terminalOptions(Terminal term) { + String options; + + switch (term) { + case POSTSCRIPT: + options = "postscript enhanced"; + break; + case POSTSCRIPT_COLOR: + options = "postscript color enhanced"; + break; + default: + options = term.toString().toLowerCase(); + break; + } + return options; + } + + /** + * Lgend type + */ + public enum LegendType { + + NONE, BOX_VERTICAL, BOX_HORIZONTAL, NOBOX_VERTICAL, NOBOX_HORIZONTAL; + } + + /** + * Plot style + */ + public enum PlotStyle { + + LINES, POINTS, LINESPOINTS, IMPULSES, STEPS, FSTEPS, HISTEPS, DOTS; + + } + + /** + * Terminal + */ + public enum Terminal { + + CANVAS, EPSLATEX, GIF, JPEG, LATEX, PDFCAIRO, PNG, POSTSCRIPT, POSTSCRIPT_COLOR, PSLATEX, PSTEX, PSTRICKS, SVG; + + } + + private static void createAndShowGUI() { + + // Create and set up the window. + JFrame frame = new JFrame("Test"); + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + + // Create and set up the content pane. + JPanel panel = new PlotTab(); + panel.setOpaque(true); // content panes must be opaque + frame.setContentPane(panel); + + // Display the window. + frame.pack(); + //frame.setSize(400, 400); + frame.setVisible(true); + } + + /** + * @param args the command line arguments + */ + public static void main(String[] args) { + try { + UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); + javax.swing.SwingUtilities.invokeLater(new Runnable() { + + @Override + public void run() { + createAndShowGUI(); + } + }); + } catch (Exception e) { + e.printStackTrace(); + } + } + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JButton jButtonAcept; + private javax.swing.JButton jButtonAceptGnuP; + private javax.swing.JButton jButtonDeletAlgorithm; + private javax.swing.JButton jButtonDeleteStream; + private javax.swing.JButton jButtonGnuoPath; + private javax.swing.JButton jButtonInPath; + private javax.swing.JButton jButtonReset; + private javax.swing.JButton jButtonResetGnuP; + private javax.swing.JCheckBox jCheckBoxDeleteScript; + private javax.swing.JCheckBox jCheckBoxShape; + private javax.swing.JCheckBox jCheckBoxSmooth; + private javax.swing.JComboBox jComboBoxGrid; + private javax.swing.JComboBox jComboBoxLegendLocation; + private javax.swing.JComboBox jComboBoxLegendType; + private javax.swing.JComboBox jComboBoxLineStyle; + private javax.swing.JComboBox jComboBoxOutPTypeGnuP; + private javax.swing.JComboBox jComboBoxXColumn; + private javax.swing.JComboBox jComboBoxXColumnGnuP; + private javax.swing.JComboBox jComboBoxYColumn; + private javax.swing.JComboBox jComboBoxYColumnGnuP; + private javax.swing.JLabel jLabel1; + private javax.swing.JLabel jLabel10; + private javax.swing.JLabel jLabel11; + private javax.swing.JLabel jLabel13; + private javax.swing.JLabel jLabel14; + private javax.swing.JLabel jLabel15; + private javax.swing.JLabel jLabel16; + private javax.swing.JLabel jLabel17; + private javax.swing.JLabel jLabel18; + private javax.swing.JLabel jLabel19; + private javax.swing.JLabel jLabel2; + private javax.swing.JLabel jLabel20; + private javax.swing.JLabel jLabel21; + private javax.swing.JLabel jLabel22; + private javax.swing.JLabel jLabel23; + private javax.swing.JLabel jLabel24; + private javax.swing.JLabel jLabel25; + private javax.swing.JLabel jLabel26; + private javax.swing.JLabel jLabel27; + private javax.swing.JLabel jLabel3; + private javax.swing.JLabel jLabel5; + private javax.swing.JLabel jLabel6; + private javax.swing.JLabel jLabel7; + private javax.swing.JLabel jLabel8; + private javax.swing.JPanel jPanel1; + private javax.swing.JPanel jPanel2; + private javax.swing.JPanel jPanel3; + private javax.swing.JPanel jPanel4; + private javax.swing.JPanel jPanelGnuP; + private javax.swing.JScrollPane jScrollPane1; + private javax.swing.JScrollPane jScrollPane3; + private javax.swing.JScrollPane jScrollPaneAlgorithms; + private javax.swing.JScrollPane jScrollPaneGnuP; + private javax.swing.JSpinner jSpinnerHeight; + private javax.swing.JSpinner jSpinnerLineWidth; + private javax.swing.JSpinner jSpinnerPlotInterval; + private javax.swing.JSpinner jSpinnerWidth; + private javax.swing.JTabbedPane jTabbedPane1; + private javax.swing.JTable jTableAlgoritms; + private javax.swing.JTable jTableStreams; + private javax.swing.JTextField jTextFieldAPOptions; + private javax.swing.JTextField jTextFieldAdcComand; + private javax.swing.JTextField jTextFieldGNUPath; + private javax.swing.JTextField jTextFieldResultPath; + private javax.swing.JTextField jTextFieldTitle; + private javax.swing.JTextField jTextFieldxTitle; + private javax.swing.JTextField jTextFieldxTitleGnuP; + private javax.swing.JTextField jTextFieldyTitle; + private javax.swing.JTextField jTextFieldyTitleGnuP; + // End of variables declaration//GEN-END:variables +} diff --git a/moa/src/main/java/moa/gui/experimentertab/PreviewExperimets.java b/moa/src/main/java/moa/gui/experimentertab/PreviewExperimets.java new file mode 100644 index 000000000..c90097c25 --- /dev/null +++ b/moa/src/main/java/moa/gui/experimentertab/PreviewExperimets.java @@ -0,0 +1,40 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package moa.gui.experimentertab; + +import javax.swing.JFrame; + +/** + * + * @author Alberto + */ +public class PreviewExperimets extends JFrame{ + + private ExpPreviewPanel previewPanel; + + public PreviewExperimets(ExpPreviewPanel previewPanel) { + this.previewPanel = previewPanel; + + setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE); + + setContentPane(this.previewPanel); + + // Display the window. + pack(); + setSize(700, 500); + + } + + @Override + public void setVisible(boolean b) { + super.setVisible(b); //To change body of generated methods, choose Tools | Templates. + this.repaint(); + } + + + + +} diff --git a/moa/src/main/java/moa/gui/experimentertab/RankingGraph.java b/moa/src/main/java/moa/gui/experimentertab/RankingGraph.java new file mode 100644 index 000000000..4ebc1b1d3 --- /dev/null +++ b/moa/src/main/java/moa/gui/experimentertab/RankingGraph.java @@ -0,0 +1,613 @@ +/* + * RankingGraph.java + * Copyright (C) 2007 University of Waikato, Hamilton, New Zealand + * @author Alberto Verdecia Cabrera (averdeciac@gmail.com) + * + * 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 moa.gui.experimentertab; + +import java.awt.BasicStroke; +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Container; +import java.awt.Dimension; +import java.awt.Font; +import java.awt.FontMetrics; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.GridLayout; +import java.awt.RenderingHints; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.MouseEvent; +import java.awt.event.MouseListener; +import java.awt.event.MouseMotionListener; +import java.awt.event.MouseWheelEvent; +import java.awt.event.MouseWheelListener; +import java.awt.event.WindowEvent; +import java.awt.geom.Line2D; +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.io.Writer; +import java.util.ArrayList; +import java.util.logging.Level; +import java.util.logging.Logger; +import javax.imageio.ImageIO; +import javax.swing.BorderFactory; +import javax.swing.JButton; +import javax.swing.JComboBox; +import javax.swing.JFileChooser; +import javax.swing.JFrame; +import javax.swing.JLabel; +import javax.swing.JOptionPane; +import javax.swing.JPanel; +import javax.swing.JSlider; +import javax.swing.JSpinner; +import javax.swing.JTextField; +import javax.swing.border.TitledBorder; +import javax.swing.event.ChangeEvent; +import moa.gui.experimentertab.statisticaltests.PValuePerTwoAlgorithm; +import moa.gui.experimentertab.statisticaltests.RankPerAlgorithm; +import nz.ac.waikato.cms.gui.core.BaseDirectoryChooser; +import nz.ac.waikato.cms.gui.core.BaseFileChooser; +import org.jfree.ui.FontChooserPanel; +import org.jfree.ui.StrokeChooserPanel; +import org.jfree.ui.StrokeSample; +import org.jibble.epsgraphics.EpsGraphics2D; +import weka.gui.ExtensionFileFilter; + +/** + * Shows the comparison of several online learning algorithms on multiple + * datasets by performing appropriate statistical tests. + * + * @author Alberto Verdecia Cabrera (averdeciac@gmail.com) + */ +public class RankingGraph extends JFrame { + + JPanel zoomPanel; + JPanel graphPanel; + JPanel graphPanelDisplay = new JPanel(); + JPanel controlPanelDisplay = new JPanel(); + JPanel controlPanel; + JPanel imgOptionsPanel; + JPanel exportPanel; + JButton btnSave, btnLineStroke, btnFont, btnLineDifStronke, btnDir; + //JComboBox imgType; + //JTextField JtextFieldimgName; + JSlider xSlider, ySlider; + int height, width; + int x0, y0; + int xScale, yScale; + double pvalue; + + Font textFont = new Font("Arial", Font.PLAIN, 14); + ArrayList<RankPerAlgorithm> algRank; + ArrayList<PValuePerTwoAlgorithm> PValues; + final static BasicStroke currentStroke = new BasicStroke(1.0f); + final static float dash1[] = {1.5f}; + final static BasicStroke dashed = new BasicStroke(1.5f, + BasicStroke.CAP_BUTT, + BasicStroke.JOIN_MITER, + 10.0f, dash1, 0.0f); + private StrokeSample[] availableStrokeSamples; + private StrokeSample stroke = new StrokeSample(currentStroke); + private StrokeSample difStroke = new StrokeSample(new BasicStroke(3.0f)); + + public EpsGraphics2D g1 = new EpsGraphics2D(); + public BufferedImage image; + public Graphics2D gb; + public String imgPath; + + /** + * Class constructor. + * + * @param algRank + * @param PValues + * @param imgPath + * @param pvalue + */ + public RankingGraph(ArrayList<RankPerAlgorithm> algRank, ArrayList<PValuePerTwoAlgorithm> PValues, String imgPath, double pvalue) { + super("Ranking Viewer"); + this.algRank = algRank; + this.PValues = PValues; + this.imgPath = imgPath; + this.pvalue = pvalue; + setSize(800, 640); + initComponents(); + setDefaultCloseOperation(HIDE_ON_CLOSE); + setVisible(true); + } + + private void initComponents() { + Container container = getContentPane(); + width = getSize().width - 10; + height = 70 * getSize().height / 100; + graphPanel = new Graph(); + zoomPanel = new SliderPanel(); + controlPanel = new JPanel(); + imgOptionsPanel = new JPanel(); + exportPanel = new JPanel(); + btnSave = new JButton("Save"); + btnLineStroke = new JButton("Line 1 Stroke"); + btnFont = new JButton("Text Font"); + btnLineDifStronke = new JButton("Line 2 Stroke"); + btnDir = new JButton("Save as"); + + graphPanelDisplay.setLayout(new BorderLayout()); + graphPanelDisplay.add(graphPanel, BorderLayout.CENTER); + TitledBorder titleborder; + titleborder = BorderFactory.createTitledBorder(" Zoom"); + zoomPanel.setBorder(titleborder); + //titleborder = BorderFactory.createTitledBorder("Options"); + //controlPanel.setBorder(titleborder); + + titleborder = BorderFactory.createTitledBorder("Properties"); + imgOptionsPanel.setBorder(titleborder); + + titleborder = BorderFactory.createTitledBorder("Export"); + exportPanel.setBorder(titleborder); + + graphPanelDisplay.setPreferredSize(new Dimension(width, height)); + controlPanel.setPreferredSize(new Dimension(60 * width / 100, + 20 * getSize().height / 100)); + zoomPanel.setPreferredSize(new Dimension(30 * width / 100, + 20 * getSize().height / 100)); + + EventControl evt = new EventControl(); + btnFont.addActionListener(evt); + btnLineDifStronke.addActionListener(evt); + btnLineStroke.addActionListener(evt); + btnSave.addActionListener(evt); + btnDir.addActionListener(evt); + imgOptionsPanel.add(btnFont); + imgOptionsPanel.add(btnLineStroke); + imgOptionsPanel.add(btnLineDifStronke); + + exportPanel.setLayout(new BorderLayout()); + JPanel panel = new JPanel(); + //panel.add(new JLabel("Export as ")); + // panel.add(imgType); + // panel.add(btnSave); + + JPanel panelName = new JPanel(); + //panelName.add(new JLabel("File name ")); + // panelName.add(JtextFieldimgName); + panelName.add(btnDir); + exportPanel.add(panelName, BorderLayout.CENTER); + exportPanel.add(panel, BorderLayout.SOUTH); + + controlPanel.setLayout(new BorderLayout()); + controlPanel.add(imgOptionsPanel, BorderLayout.CENTER); + controlPanel.add(exportPanel, BorderLayout.EAST); + controlPanelDisplay.setLayout(new BorderLayout(1, 1)); + controlPanelDisplay.add(controlPanel, BorderLayout.CENTER); + controlPanelDisplay.add(zoomPanel, BorderLayout.EAST); + container.setLayout(new BorderLayout(1, 1)); + container.add("Center", graphPanelDisplay); + container.add("South", controlPanelDisplay); + xScale = 20; + yScale = 20; + x0 = width / 2; + y0 = height / 5; + this.availableStrokeSamples = new StrokeSample[4]; + this.availableStrokeSamples[0] = new StrokeSample(new BasicStroke(1.5f, + BasicStroke.CAP_BUTT, + BasicStroke.JOIN_MITER, + 10.0f, dash1, 0.0f)); + this.availableStrokeSamples[1] = new StrokeSample( + new BasicStroke(1.0f)); + this.availableStrokeSamples[2] = new StrokeSample( + new BasicStroke(2.0f)); + this.availableStrokeSamples[3] = new StrokeSample( + new BasicStroke(3.0f)); + + addWindowStateListener((WindowEvent arg0) -> { + width = getSize().width - 10; + height = 70 * getSize().height / 100; + x0 = width / 2; + y0 = height / 5; + xScale = 20; + yScale = 20; + xSlider.setValue(50); + ySlider.setValue(20); + }); + + } + + private void strokeSelection(StrokeSample str) { + StrokeChooserPanel panel = new StrokeChooserPanel( + str, availableStrokeSamples); + int result = JOptionPane.showConfirmDialog(this, panel, + "Stroke Selection", + JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE); + + if (result == JOptionPane.OK_OPTION) { + str.setStroke(panel.getSelectedStroke()); + + } + + } + + /** + * Allow to select the text font. + */ + public void fontSelection() { + + FontChooserPanel panel = new FontChooserPanel(textFont); + int result + = JOptionPane.showConfirmDialog( + this, panel, "Font Selection", + JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE + ); + + if (result == JOptionPane.OK_OPTION) { + textFont = panel.getSelectedFont(); + + } + } + + private class EventControl implements ActionListener { + + @Override + public void actionPerformed(ActionEvent evt) { + Object source = evt.getSource(); + + if (source == btnSave) { + + } else if (source == btnFont) { + fontSelection(); + } else if (source == btnLineStroke) { + strokeSelection(stroke); + } else if (source == btnLineDifStronke) { + strokeSelection(difStroke); + } else if (source == btnDir) { +// String path = ""; +// JFileChooser propDir = new JFileChooser(); +// int selection = propDir.showSaveDialog(JtextFieldimgName); +// if (selection == JFileChooser.APPROVE_OPTION) { +// path = propDir.getSelectedFile().getAbsolutePath(); +// } +// if (!path.equals("")) { +// JtextFieldimgName.setText(path); +// +// } + + BaseFileChooser fileChooser = new BaseFileChooser(); + ExtensionFileFilter filterPNG = new ExtensionFileFilter(".png","PNG Image Files"); + fileChooser.addChoosableFileFilter(filterPNG); + + ExtensionFileFilter filterJPG = new ExtensionFileFilter(".jpg","JPG Image Files"); + fileChooser.addChoosableFileFilter(filterJPG); + + ExtensionFileFilter filterEPS = new ExtensionFileFilter(".eps","EPS Image Files"); + fileChooser.addChoosableFileFilter(filterEPS); + + + fileChooser. setAcceptAllFileFilterUsed(false); + fileChooser.setCurrentDirectory(new File(imgPath)); + int option = fileChooser.showSaveDialog(null); + if (option == JFileChooser.APPROVE_OPTION) { + String fileDesc = fileChooser.getFileFilter().getDescription(); + + if (fileDesc.startsWith("PNG")) { + + if (fileChooser.getSelectedFile().getName().toUpperCase().endsWith("PNG")==true) { + try { + ImageIO.write(image, "png",fileChooser.getSelectedFile()); + } catch (IOException e) { + e.printStackTrace(); + } + } else { + try { + ImageIO.write(image, "png", new File(fileChooser.getSelectedFile().getAbsolutePath()+".png")); + } catch (IOException e) { + e.printStackTrace(); + } + } + } else if (fileDesc.startsWith("JPG")) { + if (fileChooser.getSelectedFile().getName().toUpperCase().endsWith("JPG")==true) { + try { + ImageIO.write(image, "jpg", fileChooser.getSelectedFile()); + } catch (IOException e) { + e.printStackTrace(); + } + } else { + try { + ImageIO.write(image, "jpg", new File(fileChooser.getSelectedFile().getAbsolutePath()+".jpg")); + } catch (IOException e) { + e.printStackTrace(); + } + } + } else if (fileDesc.startsWith("EPS")) { + if (fileChooser.getSelectedFile().getName().toUpperCase().endsWith("EPS")==true) { + try (Writer out = new FileWriter(fileChooser.getSelectedFile())) { + out.write(g1.toString()); + } catch (IOException ex) { + Logger.getLogger(RankingGraph.class.getName()).log(Level.SEVERE, null, ex); + } + g1 = new EpsGraphics2D(); + + } else { + try (Writer out = new FileWriter(new File(fileChooser.getSelectedFile().getAbsolutePath()+".eps"))) { + out.write(g1.toString()); + } catch (IOException ex) { + Logger.getLogger(RankingGraph.class.getName()).log(Level.SEVERE, null, ex); + } + g1 = new EpsGraphics2D(); + } + } + + }//else + } + graphPanel.repaint(); + + } + } + + class Graph extends JPanel implements MouseListener, + MouseMotionListener, MouseWheelListener { + + int offsetX, offsetY; + boolean dragging; + + Graph() { + setBackground(Color.white); + offsetX = x0; + offsetY = y0; + addMouseListener(this); + addMouseMotionListener(this); + addMouseWheelListener(this); + } + + @Override + public void mousePressed(MouseEvent evt) { + + if (dragging) { + return; + } + int x = evt.getX(); + int y = evt.getY(); + offsetX = x - x0; + offsetY = y - y0; + dragging = true; + } + + @Override + public void mouseReleased(MouseEvent evt) { + dragging = false; + repaint(); + } + + @Override + public void mouseDragged(MouseEvent evt) { + if (dragging == false) { + return; + } + + int x = evt.getX(); + int y = evt.getY(); + x0 = x - offsetX; + y0 = y - offsetY; + + repaint(); + } + + @Override + public void mouseWheelMoved(MouseWheelEvent e) { + double value = 0.05f * e.getPreciseWheelRotation(); + int xleft = x0 - width / 3; + int xrigth = x0 + width / 3; + + if(value > 0 && (xrigth + xScale) - (xleft - xScale) <= 50){ + return; + } + else{ + xScale -= value * 100; + } + repaint(); + } + + @Override + public void mouseMoved(MouseEvent evt) { + } + + @Override + public void mouseClicked(MouseEvent evt) { + } + + @Override + public void mouseEntered(MouseEvent evt) { + } + + @Override + public void mouseExited(MouseEvent evt) { + } + + @Override + public void paintComponent(Graphics g) { + super.paintComponent(g); + Graficar(g, x0, y0); + + } + + void Graficar(Graphics ap, int xg, int yg) { + + g1 = new EpsGraphics2D(); + + Graphics2D g = (Graphics2D) ap; + image = new BufferedImage(width, height, BufferedImage.TYPE_INT_BGR); + gb = image.createGraphics(); + g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, + RenderingHints.VALUE_ANTIALIAS_ON); + g1.setRenderingHint(RenderingHints.KEY_ANTIALIASING, + RenderingHints.VALUE_ANTIALIAS_ON); + gb.setRenderingHint(RenderingHints.KEY_ANTIALIASING, + RenderingHints.VALUE_ANTIALIAS_ON); + g.setFont(textFont); + g1.setFont(textFont); + gb.setFont(textFont); + // X axis + g.setPaint(Color.BLACK); + g1.setColor(Color.BLACK); + + gb.setBackground(Color.WHITE); + gb.clearRect(0, 0, image.getWidth(), image.getHeight()); + gb.setColor(Color.BLACK); + + int xleft = xg - width / 3; + int xrigth = xg + width / 3; + g.setStroke(stroke.getStroke()); + g1.setStroke(stroke.getStroke()); + gb.setStroke(stroke.getStroke()); + //Values + int xin = xleft - xScale; + int xfin = xrigth + xScale; + int rank1 = (int)Math.floor(algRank.get(0).rank); + //ticks number + int ticks = (int) (Math.ceil(algRank.get(algRank.size() - 1).rank)); + int xdiv = (xfin - xin) / ticks; //number of divisions in the axis + int xinr = rank1*xdiv + xin; + //axis + g.draw(new Line2D.Double(xinr, yg, xrigth + xScale, yg)); + g1.draw(new Line2D.Double(xinr, yg, xrigth + xScale, yg)); + gb.draw(new Line2D.Double(xinr, yg, xrigth + xScale, yg)); + + int j = rank1; + //put the ticks + g.setStroke(currentStroke); + g1.setStroke(currentStroke); + gb.setStroke(currentStroke); + for (int i = /*xin*/xinr; i <= xfin; i += xdiv) { + g.draw(new Line2D.Double(i, yg - 4, i, yg)); + g.drawString("" + j, i, yg - 6); + g1.draw(new Line2D.Double(i, yg - 4, i, yg)); + g1.drawString("" + j, i, yg - 6); + gb.draw(new Line2D.Double(i, yg - 4, i, yg)); + gb.drawString("" + j, i, yg - 6); + j++; + } + int ydiv = (height / 2) / 4 - (height / 10); + + int ya = ydiv + yScale; + FontMetrics fm = g.getFontMetrics(); + g.setStroke(stroke.getStroke()); + g1.setStroke(stroke.getStroke()); + gb.setStroke(stroke.getStroke()); + boolean visited[][] = new boolean[algRank.size()][algRank.size()]; + for (int i = 0; i < algRank.size(); i++) { + for (int k = 0; k < algRank.size(); k++) { + visited[i][k] = false; + } + } + + //Draw algorithms Lines + for (int i = 0; i < algRank.size(); i++) { + g.draw(new Line2D.Double((double) (xdiv * algRank.get(i).rank + xin), yg + ya, (double) (xdiv * algRank.get(i).rank + xin), yg)); + g1.draw(new Line2D.Double((double) (xdiv * algRank.get(i).rank + xin), yg + ya, (double) (xdiv * algRank.get(i).rank + xin), yg)); + gb.draw(new Line2D.Double((double) (xdiv * algRank.get(i).rank + xin), yg + ya, (double) (xdiv * algRank.get(i).rank + xin), yg)); + int k; + for (k = i + 1; k <= algRank.size() - 1; k++) { + int index = PValuePerTwoAlgorithm.getIndex(PValues, + algRank.get(i).algName, algRank.get(k).algName); + boolean v = PValues.get(index).isSignicativeBetterThan(pvalue); + if (v == true) { + visited[i][k] = true; + } else { + break; + } + } + g.setStroke(difStroke.getStroke()); + g1.setStroke(difStroke.getStroke()); + gb.setStroke(difStroke.getStroke()); + if (i == 0 && k - 1 != 0) { + g.draw(new Line2D.Double((double) (xdiv * algRank.get(i).rank + xin), (yg + ya + yg) / 2, (double) (xdiv * algRank.get(k - 1).rank + xin), (yg + ya + yg) / 2)); + g1.draw(new Line2D.Double((double) (xdiv * algRank.get(i).rank + xin), (yg + ya + yg) / 2, (double) (xdiv * algRank.get(k - 1).rank + xin), (yg + ya + yg) / 2)); + gb.draw(new Line2D.Double((double) (xdiv * algRank.get(i).rank + xin), (yg + ya + yg) / 2, (double) (xdiv * algRank.get(k - 1).rank + xin), (yg + ya + yg) / 2)); + } else if (i != 0) { + //If the last visited by the current algorithm is not in the visited of the previous one then draw a line + if (visited[i - 1][k - 1] == false && (i != k - 1)) { + g.draw(new Line2D.Double((double) (xdiv * algRank.get(i).rank + xin), (yg + ya + yg) / 2, (double) (xdiv * algRank.get(k - 1).rank + xin), (yg + ya + yg) / 2)); + g1.draw(new Line2D.Double((double) (xdiv * algRank.get(i).rank + xin), (yg + ya + yg) / 2, (double) (xdiv * algRank.get(k - 1).rank + xin), (yg + ya + yg) / 2)); + gb.draw(new Line2D.Double((double) (xdiv * algRank.get(i).rank + xin), (yg + ya + yg) / 2, (double) (xdiv * algRank.get(k - 1).rank + xin), (yg + ya + yg) / 2)); + } + } + g.setStroke(stroke.getStroke()); + g1.setStroke(stroke.getStroke()); + gb.setStroke(stroke.getStroke()); + if (i < algRank.size() / 2) { + int lenght = fm.stringWidth(algRank.get(i).algName); + g.draw(new Line2D.Double((double) (xdiv * algRank.get(i).rank + xin), yg + ya, xinr-3, yg + ya)); + g.drawString(algRank.get(i).algName, xinr-3 - lenght - 10, yg + ya); + g1.draw(new Line2D.Double((double) (xdiv * algRank.get(i).rank + xin), yg + ya, xinr-3, yg + ya)); + g1.drawString(algRank.get(i).algName, xinr-3 - lenght - 10, yg + ya); + gb.draw(new Line2D.Double((double) (xdiv * algRank.get(i).rank + xin), yg + ya, xinr-3, yg + ya)); + gb.drawString(algRank.get(i).algName, xinr-3 - lenght - 10, yg + ya); + } else { + g.draw(new Line2D.Double((double) (xdiv * algRank.get(i).rank + xin), yg + ya, xfin+3, yg + ya)); + g.drawString(algRank.get(i).algName, xfin+3 + 10, yg + ya); + g1.draw(new Line2D.Double((double) (xdiv * algRank.get(i).rank + xin), yg + ya, xfin+3, yg + ya)); + g1.drawString(algRank.get(i).algName, xfin+3 + 10, yg + ya); + gb.draw(new Line2D.Double((double) (xdiv * algRank.get(i).rank + xin), yg + ya, xfin+3, yg + ya)); + gb.drawString(algRank.get(i).algName, xfin+3 + 10, yg + ya); + } + ya += 20; + + } + + } + + } + + /** + * Allows you to increase or decrease the scale of the graph. + */ + public class SliderPanel extends JPanel { + + /** + * Constructor. + */ + public SliderPanel() { + setLayout(new GridLayout(1, 2)); + + xSlider = new JSlider(JSlider.VERTICAL, -400, 400, 50); + xSlider.addChangeListener((ChangeEvent e) -> { + xScale = (int) xSlider.getValue(); + graphPanel.repaint(); + }); + + add(xSlider); + + ySlider = new JSlider(JSlider.VERTICAL, 1, 400, 20); + ySlider.addChangeListener((ChangeEvent e) -> { + yScale = (int) ySlider.getValue(); + graphPanel.repaint(); + }); + add(ySlider); + + xSlider.setMinorTickSpacing(20); + xSlider.setPaintTicks(true); + xSlider.setPaintLabels(true); + ySlider.setMinorTickSpacing(20); + ySlider.setPaintTicks(true); + ySlider.setPaintLabels(true); + + } + + } + +} // class diff --git a/moa/src/main/java/moa/gui/experimentertab/ReadFile.java b/moa/src/main/java/moa/gui/experimentertab/ReadFile.java new file mode 100644 index 000000000..d8ef7a719 --- /dev/null +++ b/moa/src/main/java/moa/gui/experimentertab/ReadFile.java @@ -0,0 +1,349 @@ +/* + * ReadFile.java + * Copyright (C) 2007 University of Waikato, Hamilton, New Zealand + * @author Alberto Verdecia Cabrera (averdeciac@gmail.com) + * + * 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 moa.gui.experimentertab; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.UnsupportedEncodingException; +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; +import java.util.logging.Level; +import java.util.logging.Logger; +import org.apache.commons.io.FilenameUtils; + +/** + * This class processes the results files of the algorithms in each directory. + * + * @author Alberto Verdecia Cabrera (averdeciac@gmail.com). + */ +public class ReadFile { + + private String path; + private LinkedList<String> stream; + private LinkedList<String> algNames; + private LinkedList<String> measures; + private ArrayList<String> algShortNames; + private List<Algorithm> algorithm = new ArrayList<>(); + /** + * File Constructor + * + * @param path + */ + public ReadFile(String path) { + this.path = path; + this.stream = new LinkedList<>(); + this.algNames = new LinkedList<>(); + this.measures = new LinkedList<>(); + this.algShortNames = new ArrayList<>(); + } + + /** + * Processes the results files of the algorithms in each directory. + * + * @return If all the files were processed correctly it returns an empty + * string, else return the problem file. + */ + public String processFiles() { + + //read files + File file = new File(path); + File listFiles[] = file.listFiles(); + boolean addFirst = true; + for (int i = 0; i < listFiles.length; i++) { + + if (listFiles[i].isDirectory()) { + stream.add(listFiles[i].getName()); + File files = new File(listFiles[i].getAbsolutePath()); + File algorithm[] = files.listFiles(); + for (int j = 0; j < algorithm.length; j++) { + if (algorithm[j].isFile()) { + if (algNames.remove(algorithm[j].getName())) { + algNames.add(algorithm[j].getName()); + } else { + algNames.add(algorithm[j].getName()); + } + FileReader fr = null; + try { + fr = new FileReader(algorithm[j].getAbsolutePath()); + } catch (FileNotFoundException ex) { + return "Problem with file: " + listFiles[j].getAbsolutePath(); + + } + BufferedReader br = new BufferedReader(fr); + try { + String line = br.readLine(); + if (addFirst) { + measures.add(line); + addFirst = false; + } else if (measures.remove(line)) { + measures.add(line); + } else { + String lineArray[] = line.split(","); + String measureArray[] = measures.getFirst().split(","); + String newMeasure = ""; + for (int l = 0; l < lineArray.length; l++) { + for (int m = 0; m < measureArray.length; m++) { + if (lineArray[l].equals(measureArray[m])) { + newMeasure += lineArray[l] + ","; + } + + } + } + String s[]; + if (newMeasure.endsWith(",")) { + s = newMeasure.split(","); + newMeasure = ""; + for (int k = 0; k < s.length; k++) { + newMeasure += s[k]; + if (k != s.length - 1) { + newMeasure += ","; + } + } + } + + measures.removeFirst(); + measures.add(newMeasure); + } + + } catch (IOException ex) { + return "Problem with file: " + listFiles[j].getAbsolutePath(); + + } + } + + } + } + }//end files + algNames.stream().forEach((algName) -> { + this.algShortNames.add(FilenameUtils.getBaseName(algName)); + }); + return ""; + } + + public String updateMeasures(String algNames[], String stream) { + this.measures = new LinkedList<>(); + //read files + boolean addFirst = true; + for (int i = 0; i < algNames.length; i++) { + File algorithm = new File(path + File.separator + stream + File.separator + algNames[i]); + FileReader fr = null; + try { + fr = new FileReader(algorithm.getAbsolutePath()); + } catch (FileNotFoundException ex) { + return "Problem with file: " + algorithm.getAbsolutePath(); + } + BufferedReader br = new BufferedReader(fr); + try { + String line = br.readLine(); + if (addFirst) { + measures.add(line); + addFirst = false; + } else if (measures.remove(line)) { + measures.add(line); + } else { + String lineArray[] = line.split(","); + String measureArray[] = measures.getFirst().split(","); + String newMeasure = ""; + for (int l = 0; l < lineArray.length; l++) { + for (int m = 0; m < measureArray.length; m++) { + if (lineArray[l].equals(measureArray[m])) { + newMeasure += lineArray[l] + ","; + } + + } + } + String s[]; + if (newMeasure.endsWith(",")) { + s = newMeasure.split(","); + newMeasure = ""; + for (int k = 0; k < s.length; k++) { + newMeasure += s[k]; + if (k != s.length - 1) { + newMeasure += ","; + } + } + } + + measures.removeFirst(); + measures.add(newMeasure); + } + + } catch (IOException ex) { + return "Problem with file: " + algorithm.getAbsolutePath(); + + } + } + return null; + } + + static int getMeasureIndex(String algPath, String mesasure){ + + FileReader fr = null; + try { + fr = new FileReader(new File(algPath)); + BufferedReader br = new BufferedReader(fr); + String line = br.readLine(); + String measures[] = line.split(","); + for(int i = 0; i < measures.length; i++){ + if(measures[i].equals(mesasure)==true) + return i; + } + + } catch (FileNotFoundException ex) { + Logger.getLogger(ReadFile.class.getName()).log(Level.SEVERE, null, ex); + } catch (IOException ex) { + Logger.getLogger(ReadFile.class.getName()).log(Level.SEVERE, null, ex); + } + + return 0; + } + + /* public ArrayList<Algorithm> getAlgorithms(List<String> algPath,List<String> algNames, List<Measure> measures){ + + for(int i = 0; i < algPath.size(); i++){ + FileReader fr = null; + try { + fr = new FileReader(new File(algPath.get(i))); + } catch (FileNotFoundException ex) { + Logger.getLogger(ReadFile.class.getName()).log(Level.SEVERE, null, ex); + } + BufferedReader br = new BufferedReader(fr); + + try { + String line = br.readLine(); + String measures1[] = line.split(","); + for(int j = 0; j < measures1.length; j++){ + + } + } catch (IOException ex) { + Logger.getLogger(ReadFile.class.getName()).log(Level.SEVERE, null, ex); + } + Algorithm algorithm = new Algorithm(algNames.get(i), measures, br); + this.algorithm.add(algorithm); + } + }*/ + /** + * Returns the name of the algorithms. + * + * @return a LinkedList with the name of the algorithms. + */ + public LinkedList<String> getAlgNames() { + return algNames; + } + + /** + * Returns the common measures to all algorithms. + * + * @return a LinkedList with the measures. + */ + public LinkedList<String> getMeasures() { + return measures; + } + + /** + * Returns the name of the streams. + * + * @return a LinkedList with the streams. + */ + public LinkedList<String> getStream() { + return stream; + } + + /** + * Returns the short name of the algorithms. + * + * @return an ArrayList with the short name of the algorithms. + */ + public ArrayList<String> getAlgShortNames() { + return algShortNames; + } + + /** + * Returns the path of the results. + * + * @return the path of the results. + */ + public String getPath() { + return path; + } + + /** + * Sets the directory of the results file. + * + * @param path + */ + public void setPath(String path) { + this.path = path; + } + + /** + * Delete the selected directory. + * + * @param directory + */ + public static void deleteDirectory(File directory) { + File[] files = directory.listFiles(); + for (File file : files) { + if (file.isDirectory()) { + deleteDirectory(file); + } + file.delete(); + } + } + + /** + * Allow to read a csv file. + * + * @param path + * @return + * @throws UnsupportedEncodingException + * @throws FileNotFoundException + * @throws IOException + */ + public static ArrayList<String[]> readCSV(String path) + throws UnsupportedEncodingException, FileNotFoundException, IOException { + + ArrayList<String[]> data = new ArrayList<>(); + + try (FileInputStream csv = new FileInputStream(path); + InputStreamReader reader = new InputStreamReader(csv); + BufferedReader br = new BufferedReader(reader)) { + + String linea = br.readLine(); + + while ((linea = br.readLine()) != null) { + + data.add(linea.split(",")); + + } + + } + + return data; + + } + +} diff --git a/moa/src/main/java/moa/gui/experimentertab/Stream.java b/moa/src/main/java/moa/gui/experimentertab/Stream.java new file mode 100644 index 000000000..342d5771c --- /dev/null +++ b/moa/src/main/java/moa/gui/experimentertab/Stream.java @@ -0,0 +1,103 @@ +/* + * Stream.java + * Copyright (C) 2007 University of Waikato, Hamilton, New Zealand + * @author Alberto Verdecia Cabrera (averdeciac@gmail.com) + * + * 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 moa.gui.experimentertab; + +import java.io.BufferedReader; +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.util.ArrayList; +import java.util.List; +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * This class contains the name of a stream and a list of algorithms. + * + * @author Alberto Verdecia Cabrera (averdeciac@gmail.com). + */ +public class Stream { + + /** + * The name of the stream + */ + public String name; + + /** + * The list of algorithms within of the stream + */ + public List<Algorithm> algorithm = new ArrayList<>(); + + /** + * Stream Constructor + * @param name + * @param algPath + * @param algNames + * @param measures + */ + public Stream(String name, List<String> algPath, List<String> algNames, List<Measure> measures) { + this.name = name; + readBuffer(algPath, algNames, measures); + } + + /** + * Read each algorithm file. + * @param algPath + * @param algNames + * @param measures + */ + public void readBuffer(List<String> algPath, List<String> algNames, List<Measure> measures) { + BufferedReader buffer = null; + for (int i = 0; i < algPath.size(); i++) { + try { + buffer = new BufferedReader(new FileReader(algPath.get(i))); + } catch (FileNotFoundException ex) { + Logger.getLogger(Stream.class.getName()).log(Level.SEVERE, null, ex); + } + Algorithm algorithm = new Algorithm(algNames.get(i), measures, buffer,algPath.get(i)); + this.algorithm.add(algorithm); + } + + } + + /** + * Sets the name of stream + * @param name + */ + public void setName(String name) { + this.name = name; + } + + /** + * Returns the name of the stream + * @return the name of the stream + */ + public String getName() { + return name; + } + + /** + * Returns the list of the algorithms + * @return the list of the algorithms + */ + public List<Algorithm> getAlgorithm() { + return algorithm; + } + +} diff --git a/moa/src/main/java/moa/gui/experimentertab/Summary.java b/moa/src/main/java/moa/gui/experimentertab/Summary.java new file mode 100644 index 000000000..376f5de35 --- /dev/null +++ b/moa/src/main/java/moa/gui/experimentertab/Summary.java @@ -0,0 +1,670 @@ +/* + * Summary.java + * Copyright (C) 2007 University of Waikato, Hamilton, New Zealand + * @author Alberto Verdecia Cabrera (averdeciac@gmail.com) + * + * 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 moa.gui.experimentertab; + +import java.io.BufferedOutputStream; +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.FileWriter; +import java.io.IOException; +import java.io.PrintStream; +import java.util.ArrayList; +import java.util.List; +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * This class performs the different summaries. + * + * @author Alberto Verdecia Cabrera (averdeciac@gmail.com). + */ +public class Summary { + + /** + * The list of the streams + */ + public List<Stream> streams = new ArrayList<>(); + + /** + * The path of the results + */ + public String path = ""; + public SummaryTable []summary; + + /** + * Summary Constructor + * + * @param streams + * @param path + */ + public Summary(List<Stream> streams, String path) { + this.streams = streams; + this.path = path; +// generateHTML(); +// generateCSV(); +// generateLatex(); +// computeWinsTiesLossesLatex(); +// invertedSumariesPerMeasure(); +// computeWinsTiesLossesHTML(); + } + + /** + * Generates a latex summary, in which the rows are the algorithms and the + * columns the datasets. + */ + public void generateLatex(String path) { + String output = ""; + output += "\\documentclass{article}\n"; + output += "\\usepackage{multirow}\n\\usepackage{booktabs}\n\\begin{document}\n\\begin{table}[htbp]\n\\caption{Add caption}"; + output += "\\begin{tabular}"; + output += "{"; + for (int i = 0; i < this.streams.size() + 4; i++) { + output += "r"; + } + output += "}\n\\toprule\nAlgorithm & \\multicolumn{2}{r}{Measure}"; + for (int i = 0; i < this.streams.size(); i++) { + output += "& " + this.streams.get(i).getName(); + } + output += "& AVG\\\\\n\\midrule\n"; + int algorithmSize = this.streams.get(0).algorithm.size(); + String name = ""; + for (int i = 0; i < algorithmSize; i++) { + List<Algorithm> alg = this.streams.get(0).algorithm; + output += "\\multirow{" + alg.get(i).measureStdSize + "}[" + 6 + "]{*}{" + alg.get(i).name + "}"; + List<Measure> measures[] = alg.get(i).getMeasuresPerData(streams); + int cont = 0; + double sum = 0.0; + boolean isType = true; + while (cont != this.streams.get(0).algorithm.get(i).measures.size()) { + sum = 0; + name = measures[0].get(cont).getName(); + if (measures[0].get(cont).isType()) { + output += "&\\multirow{" + 2 + "}[4]{*}{" + name + "} & mean"; + + } else { + output += " & " + name; + output += "& Last value"; + } + for (int j = 0; j < measures.length; j++) { + //sum =0; + if (measures[j].get(cont).isType()) { + output += " & " + Algorithm.format(measures[j].get(cont).getValue()); + + sum += measures[j].get(cont).getValue(); + isType = true; + } else { + output += " & " + Algorithm.format1(measures[j].get(cont).getValue()); + isType = false; + } + + } + if (isType) { + double size = (double) this.streams.size(); + output += "& " + Algorithm.format(sum / size); + output += "\\\\\n"; + output += " & & std"; + for (int j = 0; j < measures.length; j++) { + output += " & " + Algorithm.format(measures[j].get(cont).getStd()); + } + output += " & -"; + } else { + output += " & -"; + + } + output += "\\\\\n"; + cont++; + } + } + output += "\\bottomrule\n\\end{tabular}%\n\\label{tab:addlabel}%\n\\end{table}%\n\\end{document}"; +// PrintStream out = null; +// try { +// out = new PrintStream(new BufferedOutputStream(new FileOutputStream(path + "summary.tex"))); +// } catch (FileNotFoundException ex) { +// Logger.getLogger(Summary.class.getName()).log(Level.SEVERE, null, ex); +// } +// System.setOut(out); +// System.out.println(output); +// out.close(); + try { + BufferedWriter out = new BufferedWriter(new FileWriter(path + "summary.tex")); + out.write(output); //Replace with the string + //you are trying to write + out.close(); + } catch (IOException e) { + System.out.println(" Error saving summary.tex"); + + } + } + + /** + * Generates a latex summary, in which the rows are the datasets and the + * columns the algorithms. + */ + public void invertedSumariesPerMeasure( String path) { + + int cont = 0; + int algorithmSize = this.streams.get(0).algorithm.size(); + int streamSize = this.streams.size(); + int measureSize = this.streams.get(0).algorithm.get(0).measures.size(); + while (cont != measureSize) { + String output = ""; + output += "\\documentclass{article}\n"; + output += "\\usepackage{multirow}\n\\usepackage{booktabs}\n\\begin{document}\n\\begin{table}[htbp]\n\\caption{Add caption}"; + output += "\\begin{tabular}"; + output += "{"; + for (int i = 0; i < algorithmSize + 1; i++) { + output += "r"; + } + + output += "}\n\\toprule\nAlgorithm"; + for (int i = 0; i < algorithmSize; i++) { + output += "& " + this.streams.get(0).algorithm.get(i).name; + } + output += "\\\\"; + output += "\n\\midrule\n"; + + for (int i = 0; i < streamSize; i++) { + List<Algorithm> alg = this.streams.get(i).algorithm; + output += this.streams.get(i).name; + for (int j = 0; j < algorithmSize; j++) { + if (alg.get(j).measures.get(cont).isType()) { + output += "&" + Algorithm.format(alg.get(j).measures.get(cont).getValue()) + "$\\,\\pm$" + + Algorithm.format(alg.get(j).measures.get(cont).getStd()); + } else { + output += "&" + Algorithm.format1(alg.get(j).measures.get(cont).getValue()); + } + } + output += "\\\\\n"; + } + output += "\\bottomrule\n\\end{tabular}%\n\\label{tab:addlabel}%\n\\end{table}%\n\\end{document}"; + //PrintStream out = null; + String name = this.streams.get(0).algorithm.get(0).measures.get(cont).getName(); +// try { +// out = new PrintStream(new BufferedOutputStream(new FileOutputStream(path + name + ".tex"))); +// } catch (FileNotFoundException ex) { +// Logger.getLogger(Summary.class.getName()).log(Level.SEVERE, null, ex); +// } +// System.setOut(out); +// System.out.println(output); +// out.close(); + try { + BufferedWriter out = new BufferedWriter(new FileWriter(path + name + ".tex")); + out.write(output); //Replace with the string + //you are trying to write + out.close(); + } catch (IOException e) { + System.out.println("Error saving "+name + ".tex"); + + } + cont++; + } + + } + /** + * The summaries are performed for each measure to be displayed in the user interface + * + * @return SummaryTable + */ + public SummaryTable[] showSummary(){ + int cont = 0; + int algorithmSize = this.streams.get(0).algorithm.size(); + int streamSize = this.streams.size(); + int measureSize = this.streams.get(0).algorithm.get(0).measures.size(); + summary = new SummaryTable[measureSize]; + while (cont != measureSize) { + + summary[cont] = new SummaryTable(); + summary[cont].measureName = this.streams.get(0).algorithm.get(0).measures.get(cont).getName(); + summary[cont].algNames = new String[algorithmSize+1]; + summary[cont].algNames[0] ="Algorithm"; + summary[cont].value = new Object[streamSize][algorithmSize+1]; + + for (int i = 0; i < algorithmSize; i++) { + + summary[cont].algNames[i+1] = this.streams.get(0).algorithm.get(i).name; + } + for (int i = 0; i < streamSize; i++) { + List<Algorithm> alg = this.streams.get(i).algorithm; + summary[cont].value[i][0] = this.streams.get(i).name; + for (int j = 0; j < algorithmSize; j++) { + if (alg.get(j).measures.get(cont).isType()) { + summary[cont].value[i][j+1] = Algorithm.format(alg.get(j).measures.get(cont).getValue())+"±"+ + Algorithm.format(alg.get(j).measures.get(cont).getStd()); + } else { + summary[cont].value[i][j+1] = Algorithm.format1(alg.get(j).measures.get(cont).getValue()); + + } + } + + } + + cont++; + } + return summary; + } + + /** + * Generates an HTML summary, in which the rows are the datasets and the + * columns the algorithms. + */ + public void generateHTML(String path) { + + String output = ""; + output += "<TABLE BORDER=1 WIDTH=\"100%\" ALIGN=CENTER>\n"; + output += "<CAPTION> Experiment"; + output += "<TR> <TD>Algorithm <TD COLSPAN = 2>Measure"; + + //set algorithms names + + for (int i = 0; i < this.streams.size(); i++) { + output += "<TD>" + this.streams.get(i).getName(); + } + output += "<TD>AVG"; + int algorithmSize = this.streams.get(0).algorithm.size(); + String name = ""; + for (int i = 0; i < algorithmSize; i++) { + List<Algorithm> alg = this.streams.get(0).algorithm; + output += "<TR><TD ROWSPAN = " + /*alg.get(i).measures.size()*/ alg.get(i).measureStdSize + ">" + + alg.get(i).name; + List<Measure> measures[] = alg.get(i).getMeasuresPerData(streams); + int cont = 0; + double sum = 0.0; + boolean isType = true; + while (cont != this.streams.get(0).algorithm.get(i).measures.size()) { + sum = 0; + name = measures[0].get(cont).getName(); + if (measures[0].get(cont).isType()) { + output += "<TD ROWSPAN = 2>" + name; + output += "<TD>mean"; + } else { + output += "<TD>" + name; + output += "<TD>Last value"; + } + for (int j = 0; j < measures.length; j++) { + //sum =0; + if (measures[j].get(cont).isType()) { + output += "<TD>" + Algorithm.format(measures[j].get(cont).getValue()); + + sum += measures[j].get(cont).getValue(); + isType = true; + } else { + output += "<TD>" + Algorithm.format1(measures[j].get(cont).getValue()); + isType = false; + } + + } + if (isType) { + double size = (double) this.streams.size(); + output += "<TD>" + Algorithm.format(sum / size); + output += "<TR>"; + output += "<TD>std"; + for (int j = 0; j < measures.length; j++) { + output += "<TD>" + Algorithm.format(measures[j].get(cont).getStd()); + } + output += "<TD>" + "-"; + } else { + output += "<TD>" + "-"; + + } + output += "<TR>"; + cont++; + } + } + + output += "</TABLE>"; +// PrintStream out = null; +// try { +// out = new PrintStream(new BufferedOutputStream(new FileOutputStream(path + "summary.html"))); +// } catch (FileNotFoundException ex) { +// Logger.getLogger(Summary.class.getName()).log(Level.SEVERE, null, ex); +// } +// System.setOut(out); +// System.out.println(output); +// out.close(); + try { + BufferedWriter out = new BufferedWriter(new FileWriter(path + "summary.html")); + out.write(output); //Replace with the string + //you are trying to write + out.close(); + } catch (IOException e) { + System.out.println("Error saving summary.html"); + + } + + } + + /** + * Generates a latex summary that shows the gains, loses or ties of each + * algorithm against each other, in a specific measure.. + */ + public void computeWinsTiesLossesLatex(String path) { + + List<Algorithm> alg = this.streams.get(0).algorithm; + int algorithmSize = this.streams.get(0).algorithm.size(); + String output = ""; + output += "\\documentclass{article}\n"; + output += "\\usepackage[latin9]{inputenc}\n" + + "\\usepackage{array}\n" + + "\\usepackage{rotfloat}\n" + + "\\usepackage{multirow}\n" + + "\n" + + "\\makeatletter\n" + + "\\providecommand{\\tabularnewline}{\\\\}\n" + + "\\usepackage{multirow}\n" + + "\\usepackage{booktabs}\n" + + "\\makeatother\n" + + "\n" + + "\\begin{document}\n" + + "\\begin{sidewaystable}\n" + + "\\centering \\caption{Add caption}\n\\begin{tabular}"; + output += "{|r|r|"; + + for (int i = 2; i <= algorithmSize * 3; i++) { + if (i <= algorithmSize) { + output += "r"; + } else { + if (i == algorithmSize * 3) { + output += "|"; + } else { + output += "|r"; + } + } + } + output += "}\n\\hline\n"; + output += "\\multirow{2}{*}{Algorithm } & \\multirow{2}{*}{PM} &"; + output += "\\multicolumn{3}{r|}{" + alg.get(1).name + "}"; + for (int i = 2; i < algorithmSize; i++) { + output += " & \\multicolumn{3}{r|}{" + alg.get(i).name + "}"; + } + output += "& \\multirow{2}{*}{AVG}\\tabularnewline\n"; + output += "\\cline{3-" + (algorithmSize * 3 - 1) + "}\n"; + output += " & & "; + output += "\\multicolumn{1}{r|}{W} & \\multicolumn{1}{r|}{L} & \\multicolumn{1}{r|}{T} & "; + for (int i = 2; i < algorithmSize; i++) { + output += "\\multicolumn{1}{r|}{W} & \\multicolumn{1}{r|}{L} & \\multicolumn{1}{r|}{T} & "; + } + output += "\\tabularnewline\n\\hline\n"; + int range = 3; + int measuresSize = this.streams.get(0).algorithm.get(0).measures.size(); + for (int i = 0; i < algorithmSize; i++) { + output += "\\multirow{" + alg.get(i).measures.size() + "}{*}" + "{" + alg.get(i).name + "}"; + List<Measure> measureRow[] = alg.get(i).getMeasuresPerData(streams); + int cont = 0; + + while (cont != measuresSize) { + + //String name = measureRow[i].get(cont).getName(); + String name = alg.get(i).measures.get(cont).getName(); + output += " & " + name; + double sum = 0.0; + + for (int j = 1; j < algorithmSize; j++) { + List<Measure> measureCol[] = alg.get(j).getMeasuresPerData(streams); + int win = 0, losses = 0, ties = 0; + for (int k = 0; k < measureCol.length; k++) { + double alg1 = measureRow[k].get(cont).getValue(); + double alg2 = measureCol[k].get(cont).getValue(); + if (j == 1) { + sum += measureRow[k].get(cont).getValue(); + } + if (measureRow[k].get(cont).isType()) { + + if (Algorithm.Round(alg1) > Algorithm.Round(alg2)) { + win++; + } else if (Algorithm.Round(alg1) < Algorithm.Round(alg2)) { + losses++; + } else { + ties++; + } + } else { + if (alg1 < alg2) { + win++; + } else if (alg1 > alg2) { + losses++; + } else { + ties++; + } + } + + } + if (i < j) { + + output += " & \\multicolumn{1}{r|}{" + win + "}"; + output += " & \\multicolumn{1}{r|}{" + losses + "}"; + output += " & \\multicolumn{1}{r|}{" + ties + "}"; + + } else if (i == j) { + output += " & \\multicolumn{1}{r}{}"; + output += " & \\multicolumn{1}{r}{}"; + output += " & \\multicolumn{1}{r|}{}"; + } else { + output += " & \\multicolumn{1}{r}{}"; + output += " & \\multicolumn{1}{r}{}"; + output += " & \\multicolumn{1}{r}{}"; + + } + + } + + sum = (double) sum / measureRow.length; + output += " & " + Algorithm.format(sum); + + if (cont < measuresSize - 1) { + output += "\\tabularnewline\n \\cline{2-2} \\cline{" + range + "-" + (algorithmSize * 3) + "}\n"; + } else { + if (i != algorithmSize - 1) { + output += "\\tabularnewline\n \\cline{1-2} \\cline{" + range + "-" + (algorithmSize * 3) + "}\n"; + } else { + output += "\\tabularnewline\n \\cline{1-" + (algorithmSize * 3) + "}\n"; + } + } + + cont++; + + } + + range += 3; + } + output += "\\end{tabular}\\label{tab:addlabel}\n" + + "\\end{sidewaystable}\n" + + "\n" + + "\\end{document}"; +// PrintStream out = null; +// try { +// out = new PrintStream(new BufferedOutputStream(new FileOutputStream(path + "summary.win.ties.losses.tex"))); +// } catch (FileNotFoundException ex) { +// Logger.getLogger(Summary.class.getName()).log(Level.SEVERE, null, ex); +// } +// System.setOut(out); +// System.out.println(output); +// out.close(); + try { + BufferedWriter out = new BufferedWriter(new FileWriter(path + "summary.win.ties.losses.tex")); + out.write(output); //Replace with the string + //you are trying to write + out.close(); + } catch (IOException e) { + System.out.println("Error saving summary.win.ties.losses.tex"); + + } + + } + + /** + * Generate a csv file for the statistical analysis. + */ + public void generateCSV() { + + int cont = 0; + int algorithmSize = this.streams.get(0).algorithm.size(); + int streamSize = this.streams.size(); + int measureSize = this.streams.get(0).algorithm.get(0).measures.size(); + + while (cont != measureSize) { + String output = ""; + output += "Algorithm,"; + output += this.streams.get(0).algorithm.get(0).name; + //Inicialize summary table + + for (int i = 1; i < algorithmSize; i++) { + output += "," + this.streams.get(0).algorithm.get(i).name; + + } + output += "\n"; + + for (int i = 0; i < streamSize; i++) { + List<Algorithm> alg = this.streams.get(i).algorithm; + output += this.streams.get(i).name; + for (int j = 0; j < algorithmSize; j++) { + output += "," + alg.get(j).measures.get(cont).getValue(); + + } + output += "\n"; + } + //PrintStream out = null; + String name = this.streams.get(0).algorithm.get(0).measures.get(cont).getName(); +// try { +// out = new PrintStream(new BufferedOutputStream(new FileOutputStream(path + name + ".csv"))); +// } catch (FileNotFoundException ex) { +// Logger.getLogger(Summary.class.getName()).log(Level.SEVERE, null, ex); +// } +// System.setOut(out); +// System.out.println(output); +// out.close(); + try { + BufferedWriter out = new BufferedWriter(new FileWriter(path + name + ".csv")); + out.write(output); //Replace with the string + //you are trying to write + out.close(); + } catch (IOException e) { + System.out.println(name + ".csv"); + + } + cont++; + } + + } + + /** + * Generates a HTML summary that shows the gains, loses or ties of each + * algorithm against each other, in a specific measure.. + */ + public void computeWinsTiesLossesHTML(String path) { + + List<Algorithm> alg = this.streams.get(0).algorithm; + int algorithmSize = this.streams.get(0).algorithm.size(); + String tablaSalida = ""; + tablaSalida += "<TABLE BORDER=1 WIDTH=\"100%\" ALIGN=CENTER>\n"; + tablaSalida += "<CAPTION> Experiment"; + tablaSalida += "<TR> <TD ROWSPAN = 2>Algorithm <TD TD ROWSPAN = 2>PM"; + + for (int i = 1; i < algorithmSize; i++) { + tablaSalida += "<TD COLSPAN = 3>" + alg.get(i).name; + } + tablaSalida += "<TD>AVG"; + tablaSalida += "<TR>"; + for (int i = 1; i < algorithmSize; i++) { + tablaSalida += "<TD>" + "Wins" + "<TD>" + "Losses" + "<TD>" + "Ties"; + } + for (int i = 0; i < algorithmSize; i++) { + tablaSalida += "<TR><TD ROWSPAN = " + alg.get(i).measures.size() + ">" + alg.get(i).name; + List<Measure> measureRow[] = alg.get(i).getMeasuresPerData(streams); + int cont = 0; + while (cont != this.streams.get(0).algorithm.get(i).measures.size()) { + + //String name = measureRow[i].get(cont).getName(); + String name = alg.get(i).measures.get(cont).getName(); + tablaSalida += "<TD>" + name; + double sum = 0.0; + + for (int j = 1; j < algorithmSize; j++) { + List<Measure> measureCol[] = alg.get(j).getMeasuresPerData(streams); + int win = 0, losses = 0, ties = 0; + for (int k = 0; k < measureCol.length; k++) { + double alg1 = measureRow[k].get(cont).getValue(); + double alg2 = measureCol[k].get(cont).getValue(); + if (j == 1) { + sum += measureRow[k].get(cont).getValue(); + } + if (measureRow[k].get(cont).isType()) { + if (Algorithm.Round(alg1) > Algorithm.Round(alg2)) { + win++; + } else if (Algorithm.Round(alg1) < Algorithm.Round(alg2)) { + losses++; + } else { + ties++; + } + } else { + if (alg1 < alg2) { + win++; + } else if (alg1 > alg2) { + losses++; + } else { + ties++; + } + } + + } + + if (i < j) { + tablaSalida += "<TD>" + win; + tablaSalida += "<TD>" + losses; + tablaSalida += "<TD>" + ties; + } else { + tablaSalida += "<TD> "; + tablaSalida += "<TD> "; + tablaSalida += "<TD> "; + } + + } + + sum = (double) sum / measureRow.length; + tablaSalida += "<TD>" + Algorithm.format(sum); + tablaSalida += "<TR>"; + cont++; + } + + } + tablaSalida += "</TABLE>"; +// PrintStream salida = null; +// try { +// salida = new PrintStream(new BufferedOutputStream(new FileOutputStream(path + "summary.win.ties.losses.html"))); +// } catch (FileNotFoundException ex) { +// Logger.getLogger(Summary.class.getName()).log(Level.SEVERE, null, ex); +// } +// System.setOut(salida); +// System.out.println(tablaSalida); +// salida.close(); + try { + BufferedWriter out = new BufferedWriter(new FileWriter(path + "summary.win.ties.losses.html")); + out.write(tablaSalida); //Replace with the string + //you are trying to write + out.close(); + } catch (IOException e) { + System.out.println("Error saving summary.win.ties.losses.html"); + + } + + + } + +} diff --git a/moa/src/main/java/moa/gui/experimentertab/SummaryTab.java b/moa/src/main/java/moa/gui/experimentertab/SummaryTab.java new file mode 100644 index 000000000..38f0997da --- /dev/null +++ b/moa/src/main/java/moa/gui/experimentertab/SummaryTab.java @@ -0,0 +1,600 @@ +/* + * SummaryTab.java + * Copyright (C) 2007 University of Waikato, Hamilton, New Zealand + * @author Alberto Verdecia Cabrera (averdeciac@gmail.com) + * + * 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 moa.gui.experimentertab; + +import java.awt.BorderLayout; +import java.awt.Dimension; +import java.awt.GridLayout; +import java.io.File; +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; +import javax.swing.DefaultCellEditor; +import javax.swing.JComboBox; +import javax.swing.JFileChooser; +import javax.swing.JFrame; +import javax.swing.JLabel; +import javax.swing.JOptionPane; +import javax.swing.JPanel; +import javax.swing.JSplitPane; +import javax.swing.UIManager; +import javax.swing.table.DefaultTableModel; +import javax.swing.table.TableColumn; +import nz.ac.waikato.cms.gui.core.BaseDirectoryChooser; +import org.apache.commons.io.FilenameUtils; + +/** + * Summarize the performance measurements of different learning algorithms over + * time in LaTeX and HTML formats. + * + * @author Alberto Verdecia Cabrera (averdeciac@gmail.com) + */ +public class SummaryTab extends JPanel { + + private javax.swing.JButton jButtonResults; + private javax.swing.JButton jButtonDelAlgoritm; + private javax.swing.JButton jButtonDelStream; + private javax.swing.JButton jButtonDelMeasure; + private javax.swing.JButton jButtonDleteRow; + private javax.swing.JButton jButtonSummarize; + private javax.swing.JButton jButtonAddMeasure; + private javax.swing.JButton jButtonShowSummary; + private javax.swing.JPanel jPanelConfig; + private javax.swing.JScrollPane jScrollPaneAlgorithms; + private javax.swing.JScrollPane jScrollPaneStreams; + private javax.swing.JScrollPane jScrollPaneMeasure; + private javax.swing.JTable jTableAlgoritms; + private javax.swing.JTable jTableStreams; + private javax.swing.JTable jTableMeasures; + private javax.swing.JTextField jTextFieldResultsPath; + private javax.swing.JComboBox jComboBoxMeasure; + private javax.swing.JComboBox option; + private javax.swing.JLabel jLabelResults; + private javax.swing.JLabel jLabelMeasure; + private DefaultTableModel algoritmModel; + private DefaultTableModel streamModel; + private DefaultTableModel measureModel; + public LinkedList<String> measures; + private ArrayList<String> algotithmID; + private LinkedList<String> algorithmNames; + private LinkedList<String> streamNames; + Summary summary; + ReadFile rf; + + /** + * SummaryTab Constructor + */ + public SummaryTab() { + initComponents(); + measures = new LinkedList<>(); + algotithmID = new ArrayList<>(); + algorithmNames = new LinkedList<>(); + streamNames = new LinkedList<>(); + this.algoritmModel = (DefaultTableModel) jTableAlgoritms.getModel(); + this.streamModel = (DefaultTableModel) jTableStreams.getModel(); + this.measureModel = (DefaultTableModel) jTableMeasures.getModel(); + TableColumn col = jTableMeasures.getColumnModel().getColumn(2); + String op[] = {"Mean", "Last Value"}; + option = new JComboBox(op); + option.setSelectedIndex(0); + col.setCellEditor(new DefaultCellEditor(option)); + TableColumn col1 = jTableMeasures.getColumnModel().getColumn(0); + } + + private void initComponents() { + jPanelConfig = new javax.swing.JPanel(); + jScrollPaneAlgorithms = new javax.swing.JScrollPane(); + jTableAlgoritms = new javax.swing.JTable(); + jScrollPaneStreams = new javax.swing.JScrollPane(); + jTableStreams = new javax.swing.JTable(); + jTextFieldResultsPath = new javax.swing.JTextField(); + jButtonResults = new javax.swing.JButton(); + jButtonAddMeasure = new javax.swing.JButton(); + jButtonShowSummary = new javax.swing.JButton(); + jScrollPaneMeasure = new javax.swing.JScrollPane(); + jTableMeasures = new javax.swing.JTable(); + jButtonDelAlgoritm = new javax.swing.JButton(); + jButtonDelStream = new javax.swing.JButton(); + jButtonDleteRow = new javax.swing.JButton(); + jButtonSummarize = new javax.swing.JButton(); + jButtonDelMeasure = new javax.swing.JButton(); + jLabelResults = new javax.swing.JLabel(); + jLabelMeasure = new javax.swing.JLabel(); + jComboBoxMeasure = new javax.swing.JComboBox(); + + jPanelConfig.setBorder(javax.swing.BorderFactory.createTitledBorder(null, "Configure", javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION, javax.swing.border.TitledBorder.DEFAULT_POSITION, new java.awt.Font("Tahoma", 0, 12))); // NOI18N + + jScrollPaneAlgorithms.setBorder(javax.swing.BorderFactory.createTitledBorder("Algorithms")); + + jTableAlgoritms.setModel(new javax.swing.table.DefaultTableModel( + new Object[][]{}, + new String[]{ + "Algorithm", "Algorithm ID" + } + )); + jTableAlgoritms.setEditingColumn(1); + jScrollPaneAlgorithms.setViewportView(jTableAlgoritms); + + jScrollPaneStreams.setBorder(javax.swing.BorderFactory.createTitledBorder("Streams")); + + jTableStreams.setModel(new javax.swing.table.DefaultTableModel( + new Object[][]{}, + new String[]{ + "Stream", "Stream ID" + } + )); + jScrollPaneStreams.setViewportView(jTableStreams); + + jTextFieldResultsPath.setEditable(true); + jLabelResults.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT); + jLabelResults.setLabelFor(jTextFieldResultsPath); + jLabelResults.setText("Result folder"); + jButtonResults.setText("Browse"); + jButtonResults.addActionListener(this::jButtonResultsActionPerformed); + + jButtonAddMeasure.setText("Add Measure"); + jButtonAddMeasure.setToolTipText("Add Measure"); + jButtonAddMeasure.addActionListener((java.awt.event.ActionEvent evt) -> { + // jButtonRunActionPerformed(evt); + }); + + jTableMeasures.setModel(new javax.swing.table.DefaultTableModel( + new Object[][]{}, + new String[]{ + "Measure", "Measure ID", "Option" + } + )); + + jScrollPaneMeasure.setBorder(javax.swing.BorderFactory.createTitledBorder("Performance measures")); + jScrollPaneMeasure.setViewportView(jTableMeasures); + + jButtonDelAlgoritm.setText("Delete Algorithm"); + jButtonDelAlgoritm.addActionListener(this::jButtonDelAlgoritmActionPerformed); + + jButtonDelStream.setText("Delete Stream"); + jButtonDelStream.addActionListener(this::jButtonDelStreamActionPerformed); + + jButtonDelMeasure.setText("Delete Measure"); + jButtonDelMeasure.addActionListener(this::jButtonDelMeasureActionPerformed); + + jButtonSummarize.setText("Export Summary"); + jButtonSummarize.setEnabled(false); + jButtonSummarize.addActionListener(this::jButtonSummaryActionPerformed); + + jButtonShowSummary.setText("Show Summary"); + jButtonShowSummary.setEnabled(true); + jButtonShowSummary.addActionListener(this::jButtonShowSummaryActionPerformed); + + jLabelMeasure.setText("Measures"); + jComboBoxMeasure.setModel(new javax.swing.DefaultComboBoxModel(new String[]{"--Slect--"})); + jButtonAddMeasure.addActionListener(this::jButtonAddMeasureActionPerformed); + /*prueba*/ + JPanel jPanel1 = new JPanel(); + jPanel1.setBorder(javax.swing.BorderFactory.createTitledBorder("Configuration")); + JLabel jLabelDirectory = new JLabel("Result folder"); + + javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1); + jPanel1.setLayout(jPanel1Layout); + jPanel1Layout.setHorizontalGroup( + jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel1Layout.createSequentialGroup() + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup() + .addGap(14, 14, 14) + .addComponent(jLabelDirectory) + .addGap(18, 18, 18) + .addComponent(jTextFieldResultsPath) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(jButtonResults)) + .addGroup(jPanel1Layout.createSequentialGroup() + .addContainerGap() + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jButtonDelAlgoritm) + .addComponent(jScrollPaneAlgorithms, javax.swing.GroupLayout.DEFAULT_SIZE, 341, Short.MAX_VALUE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jScrollPaneStreams, javax.swing.GroupLayout.DEFAULT_SIZE, 332, Short.MAX_VALUE) + .addGroup(jPanel1Layout.createSequentialGroup() + .addComponent(jButtonDelStream) + .addGap(0, 0, Short.MAX_VALUE))))) + .addGap(16, 16, 16)) + ); + jPanel1Layout.setVerticalGroup( + jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup() + .addGap(23, 23, 23) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jTextFieldResultsPath, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jButtonResults) + .addComponent(jLabelDirectory)) + .addGap(18, 18, 18) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jScrollPaneAlgorithms, javax.swing.GroupLayout.DEFAULT_SIZE, 305, Short.MAX_VALUE) + .addComponent(jScrollPaneStreams, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jButtonDelStream) + .addComponent(jButtonDelAlgoritm))) + ); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); + this.setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGap(0, 741, Short.MAX_VALUE) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addContainerGap())) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGap(0, 443, Short.MAX_VALUE) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addContainerGap())) + ); + /*fin prueba*/ + JPanel panelMeasure = new JPanel(); + // JSplitPane splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT); + + panelMeasure.setLayout(new BorderLayout()); + panelMeasure.add(jLabelMeasure, BorderLayout.WEST); + panelMeasure.add(jComboBoxMeasure, BorderLayout.CENTER); + panelMeasure.add(jButtonAddMeasure, BorderLayout.EAST); + //Configure task table panel + JPanel panelMeasuresTable = new JPanel(); + JPanel panelTaskTableBtn = new JPanel(); + panelTaskTableBtn.add(jButtonShowSummary); + //panelTaskTableBtn.add(jButtonSummarize); + panelTaskTableBtn.add(jButtonDelMeasure); + panelMeasuresTable.setLayout(new BorderLayout()); + panelMeasuresTable.add(panelMeasure, BorderLayout.NORTH); + panelMeasuresTable.add(jScrollPaneMeasure, BorderLayout.CENTER); + panelMeasuresTable.add(panelTaskTableBtn, BorderLayout.SOUTH); + // panelMeasuresTable.setPreferredSize(new Dimension(200,200)); + //splitPane.setTopComponent(jPanel1); + // splitPane.setBottomComponent(panelMeasuresTable); + //splitPane.setDividerLocation(100); + this.setLayout(new BorderLayout()); + this.add(jPanel1, BorderLayout.NORTH); + this.add(panelMeasuresTable, BorderLayout.CENTER); + // this.add(splitPane); + } + + private void jButtonDelAlgoritmActionPerformed(java.awt.event.ActionEvent evt) { + if (this.jTableAlgoritms.getSelectedRow() != -1) { + + this.algoritmModel.removeRow(this.jTableAlgoritms.getSelectedRow()); + String algorithms[] = new String[algoritmModel.getRowCount()]; + for (int i = 0; i < algoritmModel.getRowCount(); i++) { + algorithms[i] = algoritmModel.getValueAt(i, 0).toString(); + } + + if (streamModel.getValueAt(0, 0).toString() != null) { + rf.updateMeasures(algorithms, streamModel.getValueAt(0, 0).toString()); + this.measures = rf.getMeasures(); + String measuresNames[] = measures.getFirst().split(","); + jComboBoxMeasure.removeAllItems(); + for (String measuresName : measuresNames) { + jComboBoxMeasure.addItem(measuresName); + } + } + } + + } + + private void jButtonDelStreamActionPerformed(java.awt.event.ActionEvent evt) { + this.streamModel.removeRow(this.jTableStreams.getSelectedRow()); + } + + private void jButtonDelMeasureActionPerformed(java.awt.event.ActionEvent evt) { + this.measureModel.removeRow(this.jTableMeasures.getSelectedRow()); + } + + private void jButtonAddMeasureActionPerformed(java.awt.event.ActionEvent evt) { + for (int i = 0; i < this.measureModel.getRowCount(); i++) { + if (jComboBoxMeasure.getSelectedItem().equals(this.measureModel.getValueAt(i, 0))) { + JOptionPane.showMessageDialog(this, "The value exist", + "Error", JOptionPane.ERROR_MESSAGE); + return; + } else if (jComboBoxMeasure.getSelectedItem().equals("--Slect--")) { + JOptionPane.showMessageDialog(this, "There are not values", + "Error", JOptionPane.ERROR_MESSAGE); + return; + } + } + + this.measureModel.addRow(new Object[]{jComboBoxMeasure.getSelectedItem(), + jComboBoxMeasure.getSelectedItem(), "Mean"}); + + } + + private void jButtonShowSummaryActionPerformed(java.awt.event.ActionEvent evt) { + + if (this.jTextFieldResultsPath.getText().equals("")) { + JOptionPane.showMessageDialog(this, "Directory not found", + "Error", JOptionPane.ERROR_MESSAGE); + return; + } + List<Measure> algmeasures = new ArrayList<>(); + List<Stream> streams = new ArrayList<>(); + List<String> algPath = new ArrayList<>(); + List<String> algShortNames = new ArrayList<>(); + int count = 0; + for (int i = 0; i < this.measureModel.getRowCount(); i++) { + for (int j = 0; j < this.jComboBoxMeasure.getItemCount(); j++) { + if (this.measureModel.getValueAt(i, 0).equals(this.jComboBoxMeasure.getItemAt(j))) { + count++; + } + if (this.measureModel.getValueAt(i, 0).equals("") || this.measureModel.getValueAt(i, 1).equals("") + || this.measureModel.getValueAt(i, 2) == null) { + JOptionPane.showMessageDialog(this, "There are fields incompleted in Table", + "Error", JOptionPane.ERROR_MESSAGE); + return; + } + + } + } + boolean type = true; + for (int k = 0; k < this.measureModel.getRowCount(); k++) { + type = this.measureModel.getValueAt(k, 2).equals("Mean"); + Measure m = new Measure(this.measureModel.getValueAt(k, 1).toString(),this.measureModel.getValueAt(k, 0).toString(), type,0); + algmeasures.add(m); + + } + String path = this.jTextFieldResultsPath.getText(); + for (int i = 0; i < streamModel.getRowCount(); i++) { + + algPath.clear(); + for (int j = 0; j < algoritmModel.getRowCount(); j++) { + File inputFile = new File(FilenameUtils.separatorsToSystem( + path + "\\" + streamModel.getValueAt(i, 0) + "\\" + algoritmModel.getValueAt(j, 0))); + File streamFile = new File(FilenameUtils.separatorsToSystem( + path + "\\" + streamModel.getValueAt(i, 0))); + if (!inputFile.exists()) { + JOptionPane.showMessageDialog(this, "File not found: " + + inputFile.getAbsolutePath(), + "Error", JOptionPane.ERROR_MESSAGE); + return; + } else { + String algorithmPath = FilenameUtils.separatorsToSystem( + path + "\\" + streamModel.getValueAt(i, 0).toString() + "\\" + + algoritmModel.getValueAt(j, 0).toString()); + algPath.add(algorithmPath); + if (i == 0) { + algShortNames.add(algoritmModel.getValueAt(j, 1).toString()); + } + + } + } + Stream s = new Stream(streamModel.getValueAt(i, 1).toString(), algPath, algShortNames, algmeasures); + streams.add(s); + } + + //create summary + try { + summary = new Summary(streams, FilenameUtils.separatorsToSystem(path + "\\")); + jButtonSummarize.setEnabled(true); + SummaryTable[] table = summary.showSummary(); + SummaryViewer summaryViewer = new SummaryViewer(table, summary,jTextFieldResultsPath.getText()); + + } catch (Exception exc) { + JOptionPane.showMessageDialog(this, "Problems generating summaries", + "Error", JOptionPane.ERROR_MESSAGE); + + } + + } + + private void jButtonSummaryActionPerformed(java.awt.event.ActionEvent evt) { + + } + + private void jButtonResultsActionPerformed(java.awt.event.ActionEvent evt) { + BaseDirectoryChooser resultsDir = new BaseDirectoryChooser(); + resultsDir.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); + int selection = -1; + String path = ""; + selection = resultsDir.showOpenDialog(this); + + if (selection == JFileChooser.APPROVE_OPTION) { + + try { + path = resultsDir.getSelectedFile().getAbsolutePath(); + readData(path); + + } catch (Exception exp) { + JOptionPane.showMessageDialog(this, "Problem with path", + "Error", JOptionPane.ERROR_MESSAGE); + + } + + } + + } + + public void summaryCMD(String[] measures, String[] types){ + List<Measure> algmeasures = new ArrayList<>(); + List<Stream> streams = new ArrayList<>(); + List<String> algPath = new ArrayList<>(); + List<String> algShortNames = new ArrayList<>(); + + + boolean type = true; + for (int k = 0; k < measures.length; k++) { + type = types[k].equals("Mean"); + Measure m = new Measure(measures[k],measures[k], type,0); + algmeasures.add(m); + + } + String path = this.jTextFieldResultsPath.getText(); + for (int i = 0; i < streamModel.getRowCount(); i++) { + + algPath.clear(); + for (int j = 0; j < algoritmModel.getRowCount(); j++) { + File inputFile = new File(FilenameUtils.separatorsToSystem( + path + "\\" + streamModel.getValueAt(i, 0) + "\\" + algoritmModel.getValueAt(j, 0))); + File streamFile = new File(FilenameUtils.separatorsToSystem( + path + "\\" + streamModel.getValueAt(i, 0))); + if (!inputFile.exists()) { + System.out.println("File not found: "+ inputFile.getAbsolutePath()); + + return; + } else { + String algorithmPath = FilenameUtils.separatorsToSystem( + path + "\\" + streamModel.getValueAt(i, 0).toString() + "\\" + + algoritmModel.getValueAt(j, 0).toString()); + algPath.add(algorithmPath); + if (i == 0) { + algShortNames.add(algoritmModel.getValueAt(j, 1).toString()); + } + + } + } + Stream s = new Stream(streamModel.getValueAt(i, 1).toString(), algPath, algShortNames, algmeasures); + streams.add(s); + } + + //create summary + try { + summary = new Summary(streams, FilenameUtils.separatorsToSystem(path + File.separator)); + jButtonSummarize.setEnabled(true); + String summaryPath = this.jTextFieldResultsPath.getText()+File.separator; + + summary.invertedSumariesPerMeasure(summaryPath); + summary.computeWinsTiesLossesHTML(summaryPath); + summary.computeWinsTiesLossesLatex(summaryPath); + summary.generateHTML(summaryPath); + summary.generateLatex(summaryPath); + System.out.println("Summaries created at: " + summaryPath); + + } catch (Exception exc) { + // System.err.println("Problems generating summaries"); + + + } + + } + + /** + * Allows to read the results file and update the corresponding fields. + * + * @param path + */ + public void readData(String path) { + jTextFieldResultsPath.setText(path); + cleanTables(); + rf = new ReadFile(path); + String str = rf.processFiles(); + if (str.equals("")) { + algotithmID = rf.getAlgShortNames(); + algorithmNames = rf.getAlgNames(); + streamNames = rf.getStream(); + this.measures = rf.getMeasures(); + //Set algorithms an streams + for (int i = 0; i < algotithmID.size(); i++) { + this.algoritmModel.addRow(new Object[]{algorithmNames.get(i), algotithmID.get(i)}); + } + streamNames.stream().forEach((streamName) -> { + this.streamModel.addRow(new Object[]{streamName, streamName}); + }); + + // set the measures into the combobox + String measuresNames[] = measures.getFirst().split(","); + jComboBoxMeasure.removeAllItems(); + for (String measuresName : measuresNames) { + jComboBoxMeasure.addItem(measuresName); + } + + } else { + + JOptionPane.showMessageDialog(this, str, + "Error", JOptionPane.ERROR_MESSAGE); + } + + } + + /** + * Clean the tables + */ + public void cleanTables() { + try { + DefaultTableModel algModel = (DefaultTableModel) jTableAlgoritms.getModel(); + DefaultTableModel strModel = (DefaultTableModel) jTableStreams.getModel(); + DefaultTableModel measureModel = (DefaultTableModel) jTableMeasures.getModel(); + int rows = jTableAlgoritms.getRowCount(); + int srow = jTableStreams.getRowCount(); + int trow = this.jTableMeasures.getRowCount(); + for (int i = 0; i < rows; i++) { + algModel.removeRow(0); + } + for (int i = 0; i < srow; i++) { + strModel.removeRow(0); + } + for (int i = 0; i < trow; i++) { + this.measureModel.removeRow(0); + } + } catch (Exception e) { + JOptionPane.showMessageDialog(null, "Error cleaning the table."); + } + jButtonSummarize.setEnabled(false); + } + + private static void createAndShowGUI() { + + // Create and set up the window. + JFrame frame = new JFrame("Test"); + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + + // Create and set up the content pane. + JPanel panel = new SummaryTab(); + panel.setOpaque(true); // content panes must be opaque + frame.setContentPane(panel); + + // Display the window. + frame.pack(); + frame.setVisible(true); + } + + /** + * The main method + * + * @param args + */ + public static void main(String[] args) { + try { + UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); + javax.swing.SwingUtilities.invokeLater(new Runnable() { + + @Override + public void run() { + createAndShowGUI(); + } + }); + } catch (Exception e) { + e.printStackTrace(); + } + } + +} diff --git a/moa/src/main/java/moa/gui/experimentertab/SummaryTable.java b/moa/src/main/java/moa/gui/experimentertab/SummaryTable.java new file mode 100644 index 000000000..00fedfe00 --- /dev/null +++ b/moa/src/main/java/moa/gui/experimentertab/SummaryTable.java @@ -0,0 +1,31 @@ +/* + * SummaryTable.java + * Copyright (C) 2007 University of Waikato, Hamilton, New Zealand + * @author Alberto Verdecia Cabrera (averdeciac@gmail.com) + * + * 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 moa.gui.experimentertab; + +/** + * Class to create the fields needed to display the summaries in the gui. + * @author Alberto Verdecia Cabrera (averdeciac@gmail.com) + */ +public class SummaryTable { + public String algNames[]; + public String measureName; + public Object value[][]; + +} diff --git a/moa/src/main/java/moa/gui/experimentertab/SummaryViewer.java b/moa/src/main/java/moa/gui/experimentertab/SummaryViewer.java new file mode 100644 index 000000000..8f6d45915 --- /dev/null +++ b/moa/src/main/java/moa/gui/experimentertab/SummaryViewer.java @@ -0,0 +1,138 @@ +/* + * SummaryViewer.java + * Copyright (C) 2007 University of Waikato, Hamilton, New Zealand + * @author Alberto Verdecia Cabrera (averdeciac@gmail.com) + * + * 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 moa.gui.experimentertab; + +import java.awt.BorderLayout; +import java.awt.GridLayout; +import java.awt.HeadlessException; +import java.io.File; +import javax.swing.JButton; +import javax.swing.JComboBox; +import javax.swing.JFileChooser; +import javax.swing.JFrame; +import javax.swing.JLabel; +import javax.swing.JOptionPane; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.JTable; +import nz.ac.waikato.cms.gui.core.BaseDirectoryChooser; + +/** + * Class to display summaries in the gui. + * @author Alberto Verdecia Cabrera (averdeciac@gmail.com) + */ +public class SummaryViewer extends JFrame { + + public JTable tableSummary; + public JScrollPane scroll; + public JPanel jTablePanel; + public JComboBox summaryType; + public JButton bntExport; + public SummaryTable[] summaryTable; + public Summary summary; + public String resultsPath; + + /** + * Constructor. + * @param summaryTable + * @param summary + * @throws HeadlessException + */ + public SummaryViewer(SummaryTable[] summaryTable, Summary summary, String resultsPath) throws HeadlessException { + super("Summary Viewer"); + + setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE); + this.summaryTable = summaryTable; + this.summary = summary; + this.resultsPath = resultsPath; + JLabel label = new JLabel("Summary"); + tableSummary = new JTable(); + String op[] = new String[this.summaryTable.length]; + for (int i = 0; i < this.summaryTable.length; i++) { + op[i] = this.summaryTable[i].measureName; + } + tableSummary.setModel(new javax.swing.table.DefaultTableModel( + this.summaryTable[0].value, + this.summaryTable[0].algNames + )); + scroll = new JScrollPane(); + scroll.setViewportView(tableSummary); + JPanel panel = new JPanel(); + JPanel main = new JPanel(); + jTablePanel = new JPanel(); + jTablePanel.setLayout(new GridLayout(1, 0)); + jTablePanel.add(scroll); + summaryType = new JComboBox(op); + summaryType.setSelectedIndex(0); + bntExport = new JButton("Export Summaries"); + + summaryType.addItemListener(this::summaryTypeItemStateChanged); + bntExport.addActionListener(this::btnExportActionPerformed); + panel.add(label); + panel.add(summaryType); + panel.add(bntExport); + + main.setLayout(new BorderLayout()); + main.add(this.jTablePanel, BorderLayout.CENTER); + main.add(panel, BorderLayout.SOUTH); + + setContentPane(main); + + // Display the window. + pack(); + setSize(700, 500); + + setVisible(true); + } + + + private void summaryTypeItemStateChanged(java.awt.event.ItemEvent evt) { + for (SummaryTable summary1 : this.summaryTable) { + if (summaryType.getSelectedItem().equals(summary1.measureName) == true) { + tableSummary.setModel(new javax.swing.table.DefaultTableModel(summary1.value, summary1.algNames)); + break; + } + } + } + private void btnExportActionPerformed(java.awt.event.ActionEvent evt) { + + String path = ""; + BaseDirectoryChooser propDir = new BaseDirectoryChooser(); + propDir.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); + propDir.setCurrentDirectory(new File(resultsPath)); + int selection = propDir.showSaveDialog(this); + if (selection == JFileChooser.APPROVE_OPTION) { + path = propDir.getSelectedFile().getAbsolutePath(); + } + if (!path.equals("")) { + path += File.separator; + summary.invertedSumariesPerMeasure(path); + summary.computeWinsTiesLossesHTML(path); + summary.computeWinsTiesLossesLatex(path); + summary.generateHTML(path); + summary.generateLatex(path); + JOptionPane.showMessageDialog(this, "Summaries created at: " + path, + "", JOptionPane.INFORMATION_MESSAGE); + } + + + } + +} diff --git a/moa/src/main/java/moa/gui/experimentertab/TaskManagerForm.form b/moa/src/main/java/moa/gui/experimentertab/TaskManagerForm.form new file mode 100644 index 000000000..3fe214de6 --- /dev/null +++ b/moa/src/main/java/moa/gui/experimentertab/TaskManagerForm.form @@ -0,0 +1,291 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<Form version="1.5" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JPanelFormInfo"> + <AuxValues> + <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/> + <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/> + <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/> + <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/> + <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/> + </AuxValues> + + <Layout> + <DimensionLayout dim="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <EmptySpace min="0" pref="400" max="32767" attributes="0"/> + <Group type="103" rootIndex="1" groupAlignment="0" attributes="0"> + <Group type="102" alignment="0" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Component id="jPanel1" max="32767" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + </Group> + </Group> + </Group> + </DimensionLayout> + <DimensionLayout dim="1"> + <Group type="103" groupAlignment="0" attributes="0"> + <EmptySpace min="0" pref="393" max="32767" attributes="0"/> + <Group type="103" rootIndex="1" groupAlignment="0" attributes="0"> + <Group type="102" alignment="0" attributes="0"> + <EmptySpace max="-2" attributes="0"/> + <Component id="jPanel1" min="-2" max="-2" attributes="0"/> + <EmptySpace max="32767" attributes="0"/> + </Group> + </Group> + </Group> + </DimensionLayout> + </Layout> + <SubComponents> + <Container class="javax.swing.JPanel" name="jPanel1"> + <Properties> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="org.netbeans.modules.form.compat2.border.TitledBorderInfo"> + <TitledBorder title="Config Algorithms/Data"/> + </Border> + </Property> + </Properties> + + <Layout> + <DimensionLayout dim="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" alignment="0" attributes="0"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <EmptySpace min="-2" max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="jScrollPaneAlgorithms" pref="0" max="32767" attributes="0"/> + <Group type="102" alignment="1" attributes="0"> + <Component id="jButtonAlgorithm" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="jButtonDelAlgoritm" min="-2" max="-2" attributes="0"/> + <EmptySpace min="0" pref="111" max="32767" attributes="0"/> + </Group> + </Group> + <EmptySpace type="unrelated" min="-2" max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="jScrollPaneStreams" pref="311" max="32767" attributes="0"/> + <Group type="102" attributes="0"> + <Component id="jButtonStream" min="-2" max="-2" attributes="0"/> + <EmptySpace type="unrelated" max="-2" attributes="0"/> + <Component id="jButtonDelStream" min="-2" max="-2" attributes="0"/> + </Group> + </Group> + </Group> + <Group type="102" alignment="0" attributes="0"> + <EmptySpace min="-2" pref="14" max="-2" attributes="0"/> + <Group type="103" groupAlignment="1" attributes="0"> + <Component id="jLabel1" min="-2" max="-2" attributes="0"/> + <Component id="jLabelDirectory" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace min="14" pref="14" max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="jTextFieldDir" max="32767" attributes="0"/> + <Component id="jTextFieldTask" max="32767" attributes="0"/> + </Group> + <EmptySpace min="-2" pref="14" max="-2" attributes="0"/> + <Component id="jButtonDir" min="-2" max="-2" attributes="0"/> + </Group> + </Group> + <EmptySpace min="-2" pref="16" max="-2" attributes="0"/> + </Group> + <Group type="102" alignment="0" attributes="0"> + <EmptySpace min="-2" pref="113" max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" attributes="0"> + <Component id="jButtonOpenConfig" min="-2" max="-2" attributes="0"/> + <EmptySpace max="-2" attributes="0"/> + <Component id="jButtonSaveConfig" min="-2" max="-2" attributes="0"/> + <EmptySpace min="0" pref="0" max="32767" attributes="0"/> + </Group> + <Group type="102" alignment="0" attributes="0"> + <EmptySpace min="0" pref="0" max="32767" attributes="0"/> + <Component id="jButtonTask" min="-2" max="-2" attributes="0"/> + </Group> + </Group> + <EmptySpace min="-2" pref="14" max="-2" attributes="0"/> + </Group> + </Group> + </DimensionLayout> + <DimensionLayout dim="1"> + <Group type="103" groupAlignment="0" attributes="0"> + <Group type="102" alignment="1" attributes="0"> + <EmptySpace min="-2" max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jButtonOpenConfig" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jButtonSaveConfig" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace min="-2" max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jTextFieldTask" alignment="3" min="-2" pref="23" max="-2" attributes="0"/> + <Component id="jButtonTask" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jLabel1" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace min="-2" max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jTextFieldDir" alignment="3" min="-2" pref="23" max="-2" attributes="0"/> + <Component id="jLabelDirectory" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jButtonDir" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + <EmptySpace min="-2" max="-2" attributes="0"/> + <Group type="103" groupAlignment="0" attributes="0"> + <Component id="jScrollPaneAlgorithms" pref="288" max="32767" attributes="0"/> + <Component id="jScrollPaneStreams" pref="0" max="32767" attributes="0"/> + </Group> + <EmptySpace min="-2" max="-2" attributes="0"/> + <Group type="103" groupAlignment="3" attributes="0"> + <Component id="jButtonDelStream" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jButtonDelAlgoritm" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jButtonAlgorithm" alignment="3" min="-2" max="-2" attributes="0"/> + <Component id="jButtonStream" alignment="3" min="-2" max="-2" attributes="0"/> + </Group> + </Group> + </Group> + </DimensionLayout> + </Layout> + <SubComponents> + <Container class="javax.swing.JScrollPane" name="jScrollPaneAlgorithms"> + <Properties> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="org.netbeans.modules.form.compat2.border.TitledBorderInfo"> + <TitledBorder title="Algorithm"/> + </Border> + </Property> + </Properties> + <AuxValues> + <AuxValue name="autoScrollPane" type="java.lang.Boolean" value="true"/> + </AuxValues> + + <Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/> + <SubComponents> + <Component class="javax.swing.JTable" name="jTableAlgorithms"> + <Properties> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="org.netbeans.modules.form.compat2.border.TitledBorderInfo"> + <TitledBorder/> + </Border> + </Property> + <Property name="model" type="javax.swing.table.TableModel" editor="org.netbeans.modules.form.editors2.TableModelEditor"> + <Table columnCount="2" rowCount="0"> + <Column editable="true" title="Algorithm" type="java.lang.Object"/> + <Column editable="true" title="Algorithm ID" type="java.lang.Object"/> + </Table> + </Property> + <Property name="tableHeader" type="javax.swing.table.JTableHeader" editor="org.netbeans.modules.form.editors2.JTableHeaderEditor"> + <TableHeader reorderingAllowed="true" resizingAllowed="true"/> + </Property> + </Properties> + </Component> + </SubComponents> + </Container> + <Container class="javax.swing.JScrollPane" name="jScrollPaneStreams"> + <Properties> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="org.netbeans.modules.form.compat2.border.TitledBorderInfo"> + <TitledBorder title="Stram"/> + </Border> + </Property> + </Properties> + <AuxValues> + <AuxValue name="autoScrollPane" type="java.lang.Boolean" value="true"/> + </AuxValues> + + <Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/> + <SubComponents> + <Component class="javax.swing.JTable" name="jTableStreams"> + <Properties> + <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor"> + <Border info="org.netbeans.modules.form.compat2.border.TitledBorderInfo"> + <TitledBorder/> + </Border> + </Property> + <Property name="model" type="javax.swing.table.TableModel" editor="org.netbeans.modules.form.editors2.TableModelEditor"> + <Table columnCount="2" rowCount="0"> + <Column editable="true" title="Stream" type="java.lang.Object"/> + <Column editable="true" title="Stream ID" type="java.lang.Object"/> + </Table> + </Property> + <Property name="tableHeader" type="javax.swing.table.JTableHeader" editor="org.netbeans.modules.form.editors2.JTableHeaderEditor"> + <TableHeader reorderingAllowed="true" resizingAllowed="true"/> + </Property> + </Properties> + </Component> + </SubComponents> + </Container> + <Component class="javax.swing.JTextField" name="jTextFieldTask"> + <Properties> + <Property name="editable" type="boolean" value="false"/> + </Properties> + </Component> + <Component class="javax.swing.JButton" name="jButtonDir"> + <Properties> + <Property name="text" type="java.lang.String" value="Browse"/> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jButtonDirActionPerformed"/> + </Events> + </Component> + <Component class="javax.swing.JLabel" name="jLabelDirectory"> + <Properties> + <Property name="horizontalAlignment" type="int" value="4"/> + <Property name="text" type="java.lang.String" value="Result folder"/> + </Properties> + </Component> + <Component class="javax.swing.JButton" name="jButtonDelAlgoritm"> + <Properties> + <Property name="text" type="java.lang.String" value="Delete Algorithm"/> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jButtonDelAlgoritmActionPerformed"/> + </Events> + </Component> + <Component class="javax.swing.JButton" name="jButtonDelStream"> + <Properties> + <Property name="text" type="java.lang.String" value="Delete Stream"/> + </Properties> + <Events> + <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jButtonDelStreamActionPerformed"/> + </Events> + </Component> + <Component class="javax.swing.JButton" name="jButtonAlgorithm"> + <Properties> + <Property name="text" type="java.lang.String" value="Add Algorithm"/> + </Properties> + </Component> + <Component class="javax.swing.JButton" name="jButtonStream"> + <Properties> + <Property name="text" type="java.lang.String" value="Add Stream"/> + </Properties> + </Component> + <Component class="javax.swing.JTextField" name="jTextFieldDir"> + <Properties> + <Property name="editable" type="boolean" value="false"/> + </Properties> + </Component> + <Component class="javax.swing.JButton" name="jButtonTask"> + <Properties> + <Property name="text" type="java.lang.String" value="Add Task"/> + </Properties> + </Component> + <Component class="javax.swing.JLabel" name="jLabel1"> + <Properties> + <Property name="text" type="java.lang.String" value="Task"/> + </Properties> + </Component> + <Component class="javax.swing.JButton" name="jButtonOpenConfig"> + <Properties> + <Property name="text" type="java.lang.String" value="Open Experiment"/> + </Properties> + </Component> + <Component class="javax.swing.JButton" name="jButtonSaveConfig"> + <Properties> + <Property name="text" type="java.lang.String" value="Save Experiment"/> + </Properties> + </Component> + </SubComponents> + </Container> + </SubComponents> +</Form> diff --git a/moa/src/main/java/moa/gui/experimentertab/TaskManagerForm.java b/moa/src/main/java/moa/gui/experimentertab/TaskManagerForm.java new file mode 100644 index 000000000..a08505f92 --- /dev/null +++ b/moa/src/main/java/moa/gui/experimentertab/TaskManagerForm.java @@ -0,0 +1,283 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package moa.gui.experimentertab; + +import javax.swing.JFrame; +import javax.swing.JPanel; +import javax.swing.UIManager; + +/** + * + * @author Alberto + */ +public class TaskManagerForm extends javax.swing.JPanel { + + /** + * Creates new form TaskManagerForm + */ + public TaskManagerForm() { + initComponents(); + } +private static void createAndShowGUI() { + + // Create and set up the window. + JFrame frame = new JFrame("Test"); + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + + // Create and set up the content pane. + JPanel panel = new TaskManagerForm(); + panel.setOpaque(true); // content panes must be opaque + frame.setContentPane(panel); + + // Display the window. + frame.pack(); + //frame.setSize(400, 400); + frame.setVisible(true); + } + + /** + * @param args the command line arguments + */ + public static void main(String[] args) { + try { + UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); + javax.swing.SwingUtilities.invokeLater(new Runnable() { + + @Override + public void run() { + createAndShowGUI(); + } + }); + } catch (Exception e) { + e.printStackTrace(); + } + } + /** + * This method is called from within the constructor to initialize the form. + * WARNING: Do NOT modify this code. The content of this method is always + * regenerated by the Form Editor. + */ + @SuppressWarnings("unchecked") + // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents + private void initComponents() { + + jPanel1 = new javax.swing.JPanel(); + jScrollPaneAlgorithms = new javax.swing.JScrollPane(); + jTableAlgorithms = new javax.swing.JTable(); + jScrollPaneStreams = new javax.swing.JScrollPane(); + jTableStreams = new javax.swing.JTable(); + jTextFieldTask = new javax.swing.JTextField(); + jButtonDir = new javax.swing.JButton(); + jLabelDirectory = new javax.swing.JLabel(); + jButtonDelAlgoritm = new javax.swing.JButton(); + jButtonDelStream = new javax.swing.JButton(); + jButtonAlgorithm = new javax.swing.JButton(); + jButtonStream = new javax.swing.JButton(); + jTextFieldDir = new javax.swing.JTextField(); + jButtonTask = new javax.swing.JButton(); + jLabel1 = new javax.swing.JLabel(); + jButtonOpenConfig = new javax.swing.JButton(); + jButtonSaveConfig = new javax.swing.JButton(); + + jPanel1.setBorder(javax.swing.BorderFactory.createTitledBorder("Config Algorithms/Data")); + + jScrollPaneAlgorithms.setBorder(javax.swing.BorderFactory.createTitledBorder("Algorithm")); + + jTableAlgorithms.setBorder(javax.swing.BorderFactory.createTitledBorder("")); + jTableAlgorithms.setModel(new javax.swing.table.DefaultTableModel( + new Object [][] { + + }, + new String [] { + "Algorithm", "Algorithm ID" + } + )); + jScrollPaneAlgorithms.setViewportView(jTableAlgorithms); + + jScrollPaneStreams.setBorder(javax.swing.BorderFactory.createTitledBorder("Stram")); + + jTableStreams.setBorder(javax.swing.BorderFactory.createTitledBorder("")); + jTableStreams.setModel(new javax.swing.table.DefaultTableModel( + new Object [][] { + + }, + new String [] { + "Stream", "Stream ID" + } + )); + jScrollPaneStreams.setViewportView(jTableStreams); + + jTextFieldTask.setEditable(false); + + jButtonDir.setText("Browse"); + jButtonDir.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jButtonDirActionPerformed(evt); + } + }); + + jLabelDirectory.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT); + jLabelDirectory.setText("Result folder"); + + jButtonDelAlgoritm.setText("Delete Algorithm"); + jButtonDelAlgoritm.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jButtonDelAlgoritmActionPerformed(evt); + } + }); + + jButtonDelStream.setText("Delete Stream"); + jButtonDelStream.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jButtonDelStreamActionPerformed(evt); + } + }); + + jButtonAlgorithm.setText("Add Algorithm"); + + jButtonStream.setText("Add Stream"); + + jTextFieldDir.setEditable(false); + + jButtonTask.setText("Add Task"); + + jLabel1.setText("Task"); + + jButtonOpenConfig.setText("Open Experiment"); + + jButtonSaveConfig.setText("Save Experiment"); + + javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1); + jPanel1.setLayout(jPanel1Layout); + jPanel1Layout.setHorizontalGroup( + jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel1Layout.createSequentialGroup() + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel1Layout.createSequentialGroup() + .addContainerGap() + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jScrollPaneAlgorithms, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup() + .addComponent(jButtonAlgorithm) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jButtonDelAlgoritm) + .addGap(0, 111, Short.MAX_VALUE))) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jScrollPaneStreams, javax.swing.GroupLayout.DEFAULT_SIZE, 311, Short.MAX_VALUE) + .addGroup(jPanel1Layout.createSequentialGroup() + .addComponent(jButtonStream) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(jButtonDelStream)))) + .addGroup(jPanel1Layout.createSequentialGroup() + .addGap(14, 14, 14) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) + .addComponent(jLabel1) + .addComponent(jLabelDirectory)) + .addGap(14, 14, 14) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jTextFieldDir) + .addComponent(jTextFieldTask)) + .addGap(14, 14, 14) + .addComponent(jButtonDir))) + .addGap(16, 16, 16)) + .addGroup(jPanel1Layout.createSequentialGroup() + .addGap(113, 113, 113) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel1Layout.createSequentialGroup() + .addComponent(jButtonOpenConfig) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jButtonSaveConfig) + .addGap(0, 0, Short.MAX_VALUE)) + .addGroup(jPanel1Layout.createSequentialGroup() + .addGap(0, 0, Short.MAX_VALUE) + .addComponent(jButtonTask))) + .addGap(14, 14, 14)) + ); + jPanel1Layout.setVerticalGroup( + jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup() + .addContainerGap() + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jButtonOpenConfig) + .addComponent(jButtonSaveConfig)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jTextFieldTask, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jButtonTask) + .addComponent(jLabel1)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jTextFieldDir, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabelDirectory) + .addComponent(jButtonDir)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jScrollPaneAlgorithms, javax.swing.GroupLayout.DEFAULT_SIZE, 288, Short.MAX_VALUE) + .addComponent(jScrollPaneStreams, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jButtonDelStream) + .addComponent(jButtonDelAlgoritm) + .addComponent(jButtonAlgorithm) + .addComponent(jButtonStream))) + ); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); + this.setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGap(0, 400, Short.MAX_VALUE) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addContainerGap())) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGap(0, 393, Short.MAX_VALUE) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))) + ); + }// </editor-fold>//GEN-END:initComponents + + private void jButtonDirActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonDirActionPerformed + + }//GEN-LAST:event_jButtonDirActionPerformed + + private void jButtonDelAlgoritmActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonDelAlgoritmActionPerformed + + }//GEN-LAST:event_jButtonDelAlgoritmActionPerformed + + private void jButtonDelStreamActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonDelStreamActionPerformed + + }//GEN-LAST:event_jButtonDelStreamActionPerformed + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JButton jButtonAlgorithm; + private javax.swing.JButton jButtonDelAlgoritm; + private javax.swing.JButton jButtonDelStream; + private javax.swing.JButton jButtonDir; + private javax.swing.JButton jButtonOpenConfig; + private javax.swing.JButton jButtonSaveConfig; + private javax.swing.JButton jButtonStream; + private javax.swing.JButton jButtonTask; + private javax.swing.JLabel jLabel1; + private javax.swing.JLabel jLabelDirectory; + private javax.swing.JPanel jPanel1; + private javax.swing.JScrollPane jScrollPaneAlgorithms; + private javax.swing.JScrollPane jScrollPaneStreams; + private javax.swing.JTable jTableAlgorithms; + private javax.swing.JTable jTableStreams; + private javax.swing.JTextField jTextFieldDir; + private javax.swing.JTextField jTextFieldTask; + // End of variables declaration//GEN-END:variables +} diff --git a/moa/src/main/java/moa/gui/experimentertab/TaskManagerTabPanel.java b/moa/src/main/java/moa/gui/experimentertab/TaskManagerTabPanel.java new file mode 100644 index 000000000..7b40fd697 --- /dev/null +++ b/moa/src/main/java/moa/gui/experimentertab/TaskManagerTabPanel.java @@ -0,0 +1,1369 @@ +/* + * TaskManagerTabPanel.java + * Copyright (C) 2007 University of Waikato, Hamilton, New Zealand + * @author Richard Kirkby (rkirkby@cs.waikato.ac.nz) + * @author Manuel Martín (msalvador@bournemouth.ac.uk) + * @modified Alberto Verdecia (averdeciac@gmail.com) + * + * 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 moa.gui.experimentertab; + +import java.awt.BorderLayout; +import java.awt.Component; +import java.awt.Dimension; +import java.awt.event.ActionEvent; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.util.ArrayList; +import java.util.List; +import java.util.Properties; +import java.util.logging.Level; +import java.util.logging.Logger; +import javax.swing.DefaultListModel; +import javax.swing.JFrame; +import javax.swing.JOptionPane; +import javax.swing.JPanel; +import javax.swing.JProgressBar; +import javax.swing.JTable; +import javax.swing.SwingConstants; +import javax.swing.UIManager; +import javax.swing.table.AbstractTableModel; +import javax.swing.table.DefaultTableCellRenderer; +import javax.swing.table.DefaultTableModel; +import javax.swing.table.TableCellRenderer; +import moa.classifiers.Classifier; +import moa.core.StringUtils; +import moa.gui.experimentertab.tasks.myMainTask; +import moa.gui.ClassOptionSelectionPanel; +import moa.options.AbstractOptionHandler; +import moa.options.ClassOption; +import moa.options.OptionHandler; +import moa.streams.ArffFileStream; +import moa.streams.generators.AgrawalGenerator; +import moa.tasks.MainTask; +import java.io.FileOutputStream; +import java.io.IOException; +import java.util.Scanner; +import javax.swing.JFileChooser; +import javax.swing.JLabel; +import javax.swing.JSplitPane; +import javax.swing.event.ListSelectionEvent; +import javax.swing.event.ListSelectionListener; +import moa.core.Globals; +import moa.learners.ChangeDetectorLearner; +import moa.learners.Learner; +import moa.streams.InstanceStream; +import moa.streams.generators.cd.ConceptDriftGenerator; +import moa.streams.generators.cd.GradualChangeGenerator; +import nz.ac.waikato.cms.gui.core.BaseDirectoryChooser; +import nz.ac.waikato.cms.gui.core.BaseFileChooser; +import org.apache.commons.io.FileUtils; +import org.apache.commons.io.FilenameUtils; + +/** + * Run online learning algorithms over multiple datasets and save the + * corresponding experiment results over time: measurements of time, memory, and + * predictive accuracy. + * + * @author Richard Kirkby (rkirkby@cs.waikato.ac.nz) + * @modified Alberto Verdecia (averdeciac@gmail.com) + */ +public class TaskManagerTabPanel extends JPanel { + + protected MainTask currentTask = new moa.tasks.EvaluatePrequential();//LearnModel(); + + protected Classifier learner = new moa.classifiers.bayes.NaiveBayes();//LearnModel(); + + protected AbstractOptionHandler stream = new AgrawalGenerator(); + + protected DefaultTableModel algoritmModel; + + protected DefaultTableModel streamModel; + + protected List<ExpTaskThread> taskList = new ArrayList<>(); + + protected TaskManagerTabPanel.TaskTableModel taskTableModel; + + protected JTable taskTable = new JTable(); + + protected String initialString = "initial"; + + protected ChangeDetectorLearner detector = new ChangeDetectorLearner(); + + protected ConceptDriftGenerator detectorStream = new GradualChangeGenerator(); + + protected ExpPreviewPanel previewPanel = new ExpPreviewPanel(); + + private PreviewExperimets preview = new PreviewExperimets(previewPanel); + + DefaultListModel listModelMonitor = new DefaultListModel(); + + public static final int MILLISECS_BETWEEN_REFRESH = 600; + + /** + * Array of characters to use to animate the progress of tasks running. + */ + public static final char[] progressAnimSequence = new char[]{'-', '\\', + '|', '/'}; + /** + * Maximum length of the status string that shows the progress of tasks + * running. + */ + public static final int MAX_STATUS_STRING_LENGTH = 79; + + public SummaryTab summary = new SummaryTab(); + + public PlotTab plot = new PlotTab(); + + public AnalyzeTab analizeTab = new AnalyzeTab(); + + protected String resultsPath = ""; + private javax.swing.JButton jButtonTask; + private javax.swing.JButton jButtonAlgorithm; + private javax.swing.JButton jButtonCancel; + private javax.swing.JButton jButtonDelAlgoritm; + private javax.swing.JButton jButtonDelStream; + private javax.swing.JButton jButtonDelete; + private javax.swing.JButton jButtonPause; + private javax.swing.JButton jButtonResume; + private javax.swing.JButton jButtonRun; + private javax.swing.JButton jButtonStream; + private javax.swing.JButton jButtonSaveConfig; + private javax.swing.JButton jButtonOpenConfig; + private javax.swing.JButton jButtonReset; + private javax.swing.JButton jButtonDir; + private javax.swing.JButton jButtonPreview; + private javax.swing.JPanel jPanelConfig; + private javax.swing.JScrollPane jScrollPaneAlgorithms; + private javax.swing.JScrollPane jScrollPaneStreams; + private javax.swing.JScrollPane jScrollPaneTaskTable; + private javax.swing.JTable jTableAlgorithms; + private javax.swing.JTable jTableStreams; + private javax.swing.JTextField jTextFieldProcess; + private javax.swing.JTextField jTextFieldTask; + private javax.swing.JTextField jTextFieldDir; + + /** + * Class ProgressCellRenderer + */ + public class ProgressCellRenderer extends JProgressBar implements + TableCellRenderer { + + private static final long serialVersionUID = 1L; + + /** + * ProgressCellRenderer Constructor + */ + public ProgressCellRenderer() { + super(SwingConstants.HORIZONTAL, 0, 10000); + setBorderPainted(false); + setStringPainted(true); + } + + @Override + public Component getTableCellRendererComponent(JTable table, + Object value, boolean isSelected, boolean hasFocus, int row, + int column) { + double frac = -1.0; + if (value instanceof Double) { + frac = ((Double) value).doubleValue(); + } + if (frac >= 0.0) { + setIndeterminate(false); + setValue((int) (frac * 10000.0)); + setString(StringUtils.doubleToString(frac * 100.0, 2, 2)); + } else { + setValue(0); + + } + return this; + } + + @Override + public void validate() { + } + + @Override + public void revalidate() { + } + + @Override + protected void firePropertyChange(String propertyName, Object oldValue, + Object newValue) { + } + + @Override + public void firePropertyChange(String propertyName, boolean oldValue, + boolean newValue) { + } + } + + /** + * Class TaskTableModel + */ + protected class TaskTableModel extends AbstractTableModel { + + private static final long serialVersionUID = 1L; + + @Override + public String getColumnName(int col) { + switch (col) { + case 0: + return "command"; + case 1: + return "status"; + case 2: + return "time elapsed"; + case 3: + return "current activity"; + case 4: + return "% complete"; + } + return null; + } + + @Override + public int getColumnCount() { + return 5; + } + + @Override + public int getRowCount() { + return TaskManagerTabPanel.this.taskList.size(); + } + + @Override + public Object getValueAt(int row, int col) { + ExpTaskThread thread = TaskManagerTabPanel.this.taskList.get(row); + switch (col) { + case 0: + try { + return ((OptionHandler) thread.getTask()).getCLICreationString(MainTask.class); + } catch (Exception e) { + } + case 1: + return thread.getCurrentStatusString(); + case 2: + return StringUtils.secondsToDHMSString(thread.getCPUSecondsElapsed()); + case 3: + return thread.getCurrentActivityString(); + case 4: + return thread.getCurrentActivityFracComplete(); + } + return null; + } + + @Override + public boolean isCellEditable(int row, int col) { + return false; + } + } + + /** + * TaskManagerTabPanel Constructor + */ + public TaskManagerTabPanel() { + initComponents(); + this.algoritmModel = (DefaultTableModel) jTableAlgorithms.getModel(); + this.streamModel = (DefaultTableModel) jTableStreams.getModel(); + this.taskTableModel = new TaskManagerTabPanel.TaskTableModel(); + this.taskTable.setModel(this.taskTableModel); + DefaultTableCellRenderer centerRenderer = new DefaultTableCellRenderer(); + centerRenderer.setHorizontalAlignment(SwingConstants.CENTER); + this.taskTable.getColumnModel().getColumn(1).setCellRenderer( + centerRenderer); + this.taskTable.getColumnModel().getColumn(2).setCellRenderer( + centerRenderer); + this.taskTable.getColumnModel().getColumn(4).setCellRenderer(new TaskManagerTabPanel.ProgressCellRenderer()); + this.taskTable.getSelectionModel().addListSelectionListener( + new ListSelectionListener() { + + @Override + public void valueChanged(ListSelectionEvent arg0) { + taskSelectionChanged(); + } + }); + javax.swing.Timer updateListTimer = new javax.swing.Timer( + MILLISECS_BETWEEN_REFRESH, (ActionEvent e) -> { + TaskManagerTabPanel.this.taskTable.repaint(); + }); + updateListTimer.start(); + + } + + private static void createAndShowGUI() { + + // Create and set up the window. + JFrame frame = new JFrame("Test"); + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + + // Create and set up the content pane. + JPanel panel = new TaskManagerTabPanel(); + panel.setOpaque(true); // content panes must be opaque + frame.setContentPane(panel); + + // Display the window. + frame.pack(); + frame.setVisible(true); + } + + private void initComponents() { + + jPanelConfig = new javax.swing.JPanel(); + jScrollPaneAlgorithms = new javax.swing.JScrollPane(); + jTableAlgorithms = new javax.swing.JTable(); + jScrollPaneStreams = new javax.swing.JScrollPane(); + jTableStreams = new javax.swing.JTable(); + jTextFieldTask = new javax.swing.JTextField(); + jButtonTask = new javax.swing.JButton(); + jButtonAlgorithm = new javax.swing.JButton(); + jButtonStream = new javax.swing.JButton(); + jButtonRun = new javax.swing.JButton(); + jScrollPaneTaskTable = new javax.swing.JScrollPane(); + taskTable = new javax.swing.JTable(); + jTextFieldProcess = new javax.swing.JTextField(); + jTextFieldDir = new javax.swing.JTextField(); + jButtonDelAlgoritm = new javax.swing.JButton(); + jButtonDelStream = new javax.swing.JButton(); + jButtonPause = new javax.swing.JButton(); + jButtonResume = new javax.swing.JButton(); + jButtonCancel = new javax.swing.JButton(); + jButtonDelete = new javax.swing.JButton(); + jButtonSaveConfig = new javax.swing.JButton(); + jButtonOpenConfig = new javax.swing.JButton(); + jButtonReset = new javax.swing.JButton(); + jButtonDir = new javax.swing.JButton(); + jButtonPreview = new javax.swing.JButton(); + + jPanelConfig.setBorder(javax.swing.BorderFactory.createTitledBorder(null, + "Configure", javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION, + javax.swing.border.TitledBorder.DEFAULT_POSITION, + new java.awt.Font("Tahoma", 0, 12))); // NOI18N + + jScrollPaneAlgorithms.setBorder(javax.swing.BorderFactory.createTitledBorder("Algorithms")); + + jTableAlgorithms.setModel(new javax.swing.table.DefaultTableModel( + new Object[][]{}, + new String[]{ + "Algorithm", "Algorithm ID" + } + )); + jTableAlgorithms.setEditingColumn(1); + jScrollPaneAlgorithms.setViewportView(jTableAlgorithms); + + jScrollPaneStreams.setBorder(javax.swing.BorderFactory.createTitledBorder("Streams")); + + jTableStreams.setModel(new javax.swing.table.DefaultTableModel( + new Object[][]{}, + new String[]{ + "Stream", "Stream ID" + } + )); + jScrollPaneStreams.setViewportView(jTableStreams); + + jTextFieldTask.setEditable(false); + //jTextFieldTask.setBorder(javax.swing.BorderFactory.createTitledBorder("Task")); + + jButtonTask.setText("Add Task"); + jButtonTask.addActionListener(this::jButtonTaskActionPerformed); + jButtonDir.setText("Browse"); + jButtonDir.addActionListener(this::jButtonDirActionPerformed); + + jButtonPreview.setText("Preview"); + jButtonPreview.addActionListener(this::jButtonPreviewActionPerformed); + + jButtonAlgorithm.setText("Add Algorithm"); + jButtonAlgorithm.addActionListener(this::jButtonAlgorithmActionPerformed); + + jButtonStream.setText("Add Stream"); + jButtonStream.addActionListener(this::jButtonStreamActionPerformed); + + jButtonRun.setText("Run Experiment"); + jButtonRun.setToolTipText("Run task"); + jButtonRun.addActionListener(this::jButtonRunActionPerformed); + + jButtonOpenConfig.setText("Open Experiment"); + jButtonOpenConfig.setToolTipText("Open saved configuration file"); + jButtonOpenConfig.addActionListener(this::jButtonOpenConfigActionPerformed); + + jButtonSaveConfig.setText("Save Experiment"); + jButtonSaveConfig.setToolTipText("Save Configuration to file"); + jButtonSaveConfig.addActionListener(this::jButtonSaveConfigActionPerformed); + + jButtonReset.setText("Reset to Default"); + jButtonReset.setToolTipText("Reset all"); + jButtonReset.addActionListener(this::jButtonResetActionPerformed); + + taskTable.setModel(new javax.swing.table.DefaultTableModel( + new Object[][]{}, + new String[]{} + )); + jScrollPaneTaskTable.setViewportView(taskTable); + + jTextFieldProcess.setText("1"); + jTextFieldProcess.setBorder(javax.swing.BorderFactory.createTitledBorder("Threads")); + + jTextFieldDir.setText(""); + //jTextFieldDir.setBorder(javax.swing.BorderFactory.createTitledBorder("Results directory")); + + jButtonDelAlgoritm.setText("Delete Algorithm"); + jButtonDelAlgoritm.addActionListener(this::jButtonDelAlgoritmActionPerformed); + + jButtonDelStream.setText("Delete Stream"); + jButtonDelStream.addActionListener(this::jButtonDelStreamActionPerformed); + + jButtonPause.setText("Pause"); + jButtonPause.addActionListener(this::jButtonPauseActionPerformed); + + jButtonResume.setText("Resume"); + jButtonResume.addActionListener(this::jButtonResumeActionPerformed); + + jButtonCancel.setText("Cancel"); + jButtonCancel.addActionListener(this::jButtonCancelActionPerformed); + + jButtonDelete.setText("Delete"); + jButtonDelete.addActionListener(this::jButtonDeleteActionPerformed); + + /*prueba*/ + JPanel jPanel1 = new JPanel(); + jPanel1.setBorder(javax.swing.BorderFactory.createTitledBorder("Configuration")); + JLabel jLabelDirectory = new JLabel("Result folder"); + JLabel jLabel1 = new JLabel("Task"); + + javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1); + jPanel1.setLayout(jPanel1Layout); + jPanel1Layout.setHorizontalGroup( + jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel1Layout.createSequentialGroup() + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel1Layout.createSequentialGroup() + .addContainerGap() + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jScrollPaneAlgorithms, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup() + .addComponent(jButtonAlgorithm) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jButtonDelAlgoritm) + .addGap(0, 111, Short.MAX_VALUE))) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jScrollPaneStreams, javax.swing.GroupLayout.DEFAULT_SIZE, 311, Short.MAX_VALUE) + .addGroup(jPanel1Layout.createSequentialGroup() + .addComponent(jButtonStream) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(jButtonDelStream)))) + .addGroup(jPanel1Layout.createSequentialGroup() + .addGap(14, 14, 14) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) + .addComponent(jLabel1) + .addComponent(jLabelDirectory)) + .addGap(14, 14, 14) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jTextFieldDir) + .addComponent(jTextFieldTask)) + .addGap(14, 14, 14) + .addComponent(jButtonDir))) + .addGap(16, 16, 16)) + .addGroup(jPanel1Layout.createSequentialGroup() + .addGap(113, 113, 113) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel1Layout.createSequentialGroup() + .addComponent(jButtonOpenConfig) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jButtonSaveConfig) + .addGap(0, 0, Short.MAX_VALUE)) + .addGroup(jPanel1Layout.createSequentialGroup() + .addGap(0, 0, Short.MAX_VALUE) + .addComponent(jButtonTask))) + .addGap(14, 14, 14)) + ); + jPanel1Layout.setVerticalGroup( + jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup() + .addContainerGap() + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jButtonOpenConfig) + .addComponent(jButtonSaveConfig)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jTextFieldTask, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jButtonTask) + .addComponent(jLabel1)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jTextFieldDir, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabelDirectory) + .addComponent(jButtonDir)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jScrollPaneAlgorithms, javax.swing.GroupLayout.DEFAULT_SIZE, 288, Short.MAX_VALUE) + .addComponent(jScrollPaneStreams, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jButtonDelStream) + .addComponent(jButtonDelAlgoritm) + .addComponent(jButtonAlgorithm) + .addComponent(jButtonStream))) + ); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); + this.setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGap(0, 400, Short.MAX_VALUE) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addContainerGap())) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGap(0, 393, Short.MAX_VALUE) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))) + ); + + JPanel panelSRB = new JPanel(); + jTextFieldProcess.setPreferredSize(new Dimension(80, 40)); + panelSRB.add(jTextFieldProcess); + panelSRB.add(jButtonRun); + //Configure task table panel + jScrollPaneAlgorithms.setPreferredSize(new Dimension(461, 260)); + jScrollPaneStreams.setPreferredSize(new Dimension(461, 260)); + jScrollPaneTaskTable.setPreferredSize(new Dimension(350, 180)); + JPanel panelTaskTable = new JPanel(); + JPanel panelTaskTableBtn = new JPanel(); + panelTaskTableBtn.add(jButtonPreview); + panelTaskTableBtn.add(jButtonPause); + panelTaskTableBtn.add(jButtonResume); + panelTaskTableBtn.add(jButtonCancel); + panelTaskTableBtn.add(jButtonDelete); + panelTaskTableBtn.add(jButtonReset); + panelTaskTable.setLayout(new BorderLayout()); + panelTaskTable.add(panelSRB, BorderLayout.NORTH); + panelTaskTable.add(jScrollPaneTaskTable, BorderLayout.CENTER); + panelTaskTable.add(panelTaskTableBtn, BorderLayout.SOUTH); + setLayout(new BorderLayout()); + this.add(jPanel1, BorderLayout.CENTER); + this.add(panelTaskTable, BorderLayout.SOUTH); + +// JPanel panel = new JPanel(new BorderLayout()); +// panel.add(panelTaskTable,BorderLayout.NORTH); +// panel.add(this.previewPanel,BorderLayout.CENTER); +// setLayout(new BorderLayout()); +// JSplitPane splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT); +// splitPane.setTopComponent(jPanel1); +// splitPane.setBottomComponent(panel); +// splitPane.setDividerLocation(100); +// // this.add(splitPane, BorderLayout.CENTER); +// splitPane.setPreferredSize(new Dimension(500, 700)); +// this.add(splitPane, BorderLayout.SOUTH); + }// </editor-fold> + + private void jButtonSaveConfigActionPerformed(java.awt.event.ActionEvent evt) { + String path = ""; + BaseFileChooser propDir = new BaseFileChooser(); + int selection = propDir.showSaveDialog(this); + if (selection == JFileChooser.APPROVE_OPTION) { + path = propDir.getSelectedFile().getAbsolutePath(); + SaveConfig(path); + } + + } + + private void jButtonOpenConfigActionPerformed(java.awt.event.ActionEvent evt) { + String path = ""; + + BaseFileChooser fileChooser = new BaseFileChooser(); + int option = fileChooser.showOpenDialog(null); + if (option == JFileChooser.APPROVE_OPTION) { + path = fileChooser.getSelectedFile().getAbsolutePath(); + openConfig(path); + } + } + + private String openDirectory() { + String path = ""; + BaseDirectoryChooser propDir = new BaseDirectoryChooser(); + int selection = propDir.showOpenDialog(this); + if (selection == JFileChooser.APPROVE_OPTION) { + path = propDir.getSelectedFile().getAbsolutePath(); + return path; + } + return ""; + } + + private void jButtonResetActionPerformed(java.awt.event.ActionEvent evt) { + this.jTextFieldTask.setText(""); + this.jTextFieldDir.setText(""); + this.jTextFieldProcess.setText("1"); + this.jButtonRun.setEnabled(true); + cleanTables(); + } + + private void jButtonDirActionPerformed(ActionEvent evt) { + + String path = openDirectory(); + + if (!path.equals("")) { + this.jTextFieldDir.setText(path); + this.resultsPath = jTextFieldDir.getText() + File.separator + "Results"; +// File file= new File(this.resultsPath); +// file.mkdir(); + + } + } + + private void jButtonPreviewActionPerformed(ActionEvent evt) { + + preview.setVisible(true); + } + + private void jButtonTaskActionPerformed(java.awt.event.ActionEvent evt) { + + String initial = TaskManagerTabPanel.this.currentTask.getCLICreationString(MainTask.class); + if (initial.split(" ") != null) { + String split[] = initial.split(" "); + String temp = initial.split(" ")[0]; + if (split.length >= 3 && split[1].equals("-l") == true) { + for (int i = 3; i < split.length; i++) { + temp += " " + split[i]; + } + initial = temp; + } + + } + String newTaskString = ClassOptionSelectionPanel.showSelectClassDialog(TaskManagerTabPanel.this, + "Configure task", myMainTask.class, + initial, null); + + try { + this.currentTask = (MainTask) ClassOption.cliStringToObject( + newTaskString, MainTask.class, null); + } catch (Exception ex) { + Logger.getLogger(TaskManagerTabPanel.class.getName()).log(Level.SEVERE, null, ex); + } + this.jTextFieldTask.setText(newTaskString); + } + + private void jButtonAlgorithmActionPerformed(java.awt.event.ActionEvent evt) { + String newTaskString; + if (this.currentTask instanceof moa.tasks.EvaluateConceptDrift) { + newTaskString = ClassOptionSelectionPanel.showSelectClassDialog(TaskManagerTabPanel.this, + "Configure learner", ChangeDetectorLearner.class, this.initialString, null); + + if (newTaskString.equals(this.initialString) == true) { + return; + } + this.initialString = newTaskString; + try { + this.detector = (ChangeDetectorLearner) ClassOption.cliStringToObject( + newTaskString, ChangeDetectorLearner.class, null); + } catch (Exception ex) { + Logger.getLogger(TaskManagerTabPanel.class.getName()).log(Level.SEVERE, null, ex); + } + } else { + newTaskString = ClassOptionSelectionPanel.showSelectClassDialog(TaskManagerTabPanel.this, + "Configure learner", Learner.class, this.initialString, null); + if (newTaskString.equals(this.initialString) == true) { + return; + } + this.initialString = newTaskString; + try { + this.learner = (Classifier) ClassOption.cliStringToObject( + newTaskString, Learner.class, null); + } catch (Exception ex) { + Logger.getLogger(TaskManagerTabPanel.class.getName()).log(Level.SEVERE, null, ex); + } + } + + for (int i = 0; i < this.algoritmModel.getRowCount(); i++) { + if (this.algoritmModel.getValueAt(i, 0).equals(newTaskString)) { + JOptionPane.showMessageDialog(this, "The value exist", + "Error", JOptionPane.ERROR_MESSAGE); + return; + } + } + this.algoritmModel.addRow(new Object[]{newTaskString, newTaskString}); + + } + + private void jButtonStreamActionPerformed(java.awt.event.ActionEvent evt) { + + boolean arff = false; + String newTaskString = ""; + String streamOption = ""; + if (this.currentTask instanceof moa.tasks.EvaluateConceptDrift) { + newTaskString = ClassOptionSelectionPanel.showSelectClassDialog(TaskManagerTabPanel.this, + "Configure stream", ConceptDriftGenerator.class, this.initialString, null); + + if (newTaskString.equals(this.initialString) == true) { + return; + } + this.initialString = newTaskString; + try { + this.detectorStream = (ConceptDriftGenerator) ClassOption.cliStringToObject( + newTaskString, ConceptDriftGenerator.class, null); + } catch (Exception ex) { + Logger.getLogger(TaskManagerTabPanel.class.getName()).log(Level.SEVERE, null, ex); + } + + } else { + newTaskString = ClassOptionSelectionPanel.showSelectClassDialog(TaskManagerTabPanel.this, + "Configure stream", InstanceStream.class, this.initialString, null); + + if (newTaskString.equals(this.initialString) == true) { + return; + } + this.initialString = newTaskString; + try { + this.stream = (AbstractOptionHandler) ClassOption.cliStringToObject( + newTaskString, InstanceStream.class, null); + } catch (Exception ex) { + Logger.getLogger(TaskManagerTabPanel.class.getName()).log(Level.SEVERE, null, ex); + } + + if (this.stream instanceof ArffFileStream) { + streamOption = FilenameUtils.getBaseName(((ArffFileStream) this.stream).arffFileOption.getFile().getName()); + arff = true; + } + } + for (int i = 0; i < this.streamModel.getRowCount(); i++) { + if (this.streamModel.getValueAt(i, 0).equals(newTaskString)) { + JOptionPane.showMessageDialog(this, "The value exist", + "Error", JOptionPane.ERROR_MESSAGE); + return; + } + } + if (arff == true) { + this.streamModel.addRow(new Object[]{newTaskString, streamOption}); + } else { + this.streamModel.addRow(new Object[]{newTaskString, newTaskString}); + } + + } + + private void jButtonRunActionPerformed(java.awt.event.ActionEvent evt) { + + //Validations + if (this.jTextFieldTask.getText().equals("")) { + + JOptionPane.showMessageDialog(this, "The task is not specified", + "Error", JOptionPane.ERROR_MESSAGE); + } else if (this.jTextFieldDir.getText().equals("")) { + JOptionPane.showMessageDialog(this, "The result directory is not specified", + "Error", JOptionPane.ERROR_MESSAGE); + } else { + if (this.jTableAlgorithms.getRowCount() != 0) { + if (this.jTableStreams.getRowCount() != 0) { + List<String> stream = new ArrayList<>(); + for (int i = 0; i < this.streamModel.getRowCount(); i++) { + if (this.streamModel.getValueAt(i, 0).equals("") + || this.streamModel.getValueAt(i, 1).equals("")) { + JOptionPane.showMessageDialog(this, "Fields incompleted in Table Stream", + "Error", JOptionPane.ERROR_MESSAGE); + return; + } + if (i == 0) { + stream.add(this.streamModel.getValueAt(i, 1).toString()); + } else { + if (stream.remove(this.streamModel.getValueAt(i, 1).toString())) { + stream.add(this.streamModel.getValueAt(i, 1).toString()); + JOptionPane.showMessageDialog(this, "There are reapeted values in Table Stream", + "Error", JOptionPane.ERROR_MESSAGE); + return; + } else { + stream.add(this.streamModel.getValueAt(i, 1).toString()); + } + } + + } + List<String> algorithm = new ArrayList<>(); + for (int i = 0; i < this.algoritmModel.getRowCount(); i++) { + if (this.algoritmModel.getValueAt(i, 0).equals("") + || this.algoritmModel.getValueAt(i, 1).equals("")) { + JOptionPane.showMessageDialog(this, "Fields incompleted in Table Algorithm", + "Error", JOptionPane.ERROR_MESSAGE); + return; + } + if (i == 0) { + algorithm.add(this.algoritmModel.getValueAt(i, 1).toString()); + } else { + if (algorithm.remove(this.algoritmModel.getValueAt(i, 1).toString())) { + algorithm.add(this.algoritmModel.getValueAt(i, 1).toString()); + JOptionPane.showMessageDialog(this, "There are reapeted values in Table Algorithm", + "Error", JOptionPane.ERROR_MESSAGE); + return; + } else { + algorithm.add(this.algoritmModel.getValueAt(i, 1).toString()); + } + } + + }//End Validations + runTask(); + } else { + JOptionPane.showMessageDialog(this, "You must select at least one dataset", + "Error", JOptionPane.ERROR_MESSAGE); + } + } else { + JOptionPane.showMessageDialog(this, "You must select at least one algorithm", + "Error", JOptionPane.ERROR_MESSAGE); + } + + } + + } + + private void jButtonDelAlgoritmActionPerformed(java.awt.event.ActionEvent evt) { + this.algoritmModel.removeRow(this.jTableAlgorithms.getSelectedRow()); + } + + private void jButtonDelStreamActionPerformed(java.awt.event.ActionEvent evt) { + this.streamModel.removeRow(this.jTableStreams.getSelectedRow()); + } + + private void jButtonPauseActionPerformed(java.awt.event.ActionEvent evt) { + pauseSelectedTasks(); + } + + private void jButtonResumeActionPerformed(java.awt.event.ActionEvent evt) { + resumeSelectedTasks(); + } + + private void jButtonCancelActionPerformed(java.awt.event.ActionEvent evt) { + cancelSelectedTasks(); + } + + private void jButtonDeleteActionPerformed(java.awt.event.ActionEvent evt) { + deleteSelectedTasks(); + } + + /** + * Executes the Task + */ + public void runTask() { + MainTask tasks[] = new MainTask[jTableAlgorithms.getModel().getRowCount() * jTableStreams.getModel().getRowCount()]; + int taskCount = 0; + + String dir = ""; + + try { + this.currentTask = (MainTask) ClassOption.cliStringToObject( + this.jTextFieldTask.getText(), MainTask.class, null); + } catch (Exception ex) { + Logger.getLogger(TaskManagerTabPanel.class.getName()).log(Level.SEVERE, null, ex); + } + MainTask auxTask = (MainTask) this.currentTask.copy(); + + dir += this.resultsPath; + + File f = new File(dir); + if (f.exists()) { + Object[] options = {"Yes", "No"}; + String cancel = "NO"; + int resp = JOptionPane.showOptionDialog(this, + "The selected folder is not empty. This action may overwrite " + + "previous experiment results. Do you want to continue?", "Warning", + JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE, null, options, cancel); + if (resp == JOptionPane.OK_OPTION) { + ReadFile.deleteDirectory(f); + + + } else { + JOptionPane.showMessageDialog(this, "Please specify another directory", "Message", + JOptionPane.INFORMATION_MESSAGE); + return; + } + } + f.mkdir(); + + String algNames = ""; + String streamNames = ""; + + for (int i = 0; i < jTableAlgorithms.getModel().getRowCount(); i++) { + String alg = jTableAlgorithms.getModel().getValueAt(i, 0).toString(); + String algFile = jTableAlgorithms.getModel().getValueAt(i, 1).toString(); + algNames += algFile; + if (i != jTableAlgorithms.getModel().getRowCount() - 1) { + algNames += ","; + } + for (int j = 0; j < jTableStreams.getModel().getRowCount(); j++) { + String stream = jTableStreams.getModel().getValueAt(j, 0).toString(); + String streamFile = jTableStreams.getModel().getValueAt(j, 1).toString(); + streamNames += streamFile.split(" ")[0]; + if (j != jTableStreams.getModel().getRowCount() - 1) { + streamNames += ","; + } + if (i == 0) { + String sfile = FilenameUtils.separatorsToSystem(dir + "\\\\" + streamFile); + f = new File(sfile); + f.mkdir(); + } + String task = " -l "; + if (alg.split(" ") != null) { + + task += "(" + alg + ") -s (" + stream + ")" + " -d (" + dir + File.separator + + streamFile + File.separator + algFile + ".txt" + ")"; + } else { + + task += alg + " -s (" + stream + ")" + " -d (" + dir + File.separator + + streamFile + File.separator + algFile + ".txt" + ")"; + } + auxTask.getOptions().setViaCLIString(task); + + try { + tasks[taskCount] = (MainTask) auxTask.copy(); + } catch (Exception ex) { + Logger.getLogger(TaskManagerTabPanel.class.getName()).log(Level.SEVERE, null, ex); + } + + taskCount++; + } + } + this.jButtonRun.setEnabled(false); + Buffer buffer = new Buffer(tasks); + int proc = 1; + if (!this.jTextFieldProcess.getText().equals("")) { + proc = Integer.parseInt(this.jTextFieldProcess.getText()); + } + if (proc > tasks.length) { + proc = tasks.length; + } + for (int i = 0; i < proc; i++) { + ExpTaskThread thread = new ExpTaskThread(buffer); + thread.start(); + this.taskList.add(0, thread); + this.taskTableModel.fireTableDataChanged(); + this.taskTable.setRowSelectionInterval(0, 0); + + } + Thread obs = new Thread() { + public void run() { + while (true) { + int count = 0; + for (ExpTaskThread thread : TaskManagerTabPanel.this.taskList) { + if (thread.isCompleted == true) { + count++; + } + } + if (count == TaskManagerTabPanel.this.taskList.size()) { + TaskManagerTabPanel.this.summary.readData(resultsPath); + TaskManagerTabPanel.this.plot.readData(resultsPath); + TaskManagerTabPanel.this.analizeTab.readData(resultsPath); + TaskManagerTabPanel.this.jButtonRun.setEnabled(true); + break; + } + } + } + }; + obs.start(); + } + + public void runTaskCLI(String[] args) { + ExperimeterCLI expCLI = new ExperimeterCLI(args); + boolean Ok = expCLI.proccesCMD(); + if (Ok == true) { + MainTask tasks[] = new MainTask[expCLI.getAlgorithms().length * expCLI.getStreams().length]; + int taskCount = 0; + + String dir = ""; + + try { + this.currentTask = (MainTask) ClassOption.cliStringToObject( + expCLI.getTask(), MainTask.class, null); + } catch (Exception ex) { + Logger.getLogger(TaskManagerTabPanel.class.getName()).log(Level.SEVERE, null, ex); + } + MainTask auxTask = (MainTask) this.currentTask.copy(); + + resultsPath = expCLI.getResultsFolder() + File.separator + "Results"; + dir += resultsPath; + + File f = new File(dir); + if (f.exists()) { + ReadFile.deleteDirectory(f); + } + f.mkdir(); + + String algNames = ""; + String streamNames = ""; + for (int i = 0; i < expCLI.getAlgorithms().length; i++) { + String alg = expCLI.getAlgorithms()[i]; + String algFile = expCLI.getAlgorithmsID()[i]; + algNames += algFile; + if (i != expCLI.getAlgorithms().length - 1) { + algNames += ","; + } + for (int j = 0; j < expCLI.getStreams().length; j++) { + String stream = expCLI.getStreams()[j]; + String streamFile = expCLI.getStreamsID()[j]; + streamNames += streamFile.split(" ")[0]; + if (j != expCLI.getStreams().length - 1) { + streamNames += ","; + } + if (i == 0) { + String sfile = FilenameUtils.separatorsToSystem(dir + "\\\\" + streamFile); + f = new File(sfile); + f.mkdir(); + } + String task = " -l "; + if (alg.split(" ") != null) { + task += "(" + alg + ") -s (" + stream + ")" + " -d (" + dir + File.separator + + streamFile + File.separator + algFile + ".txt" + ")"; + } else { + task += alg + " -s (" + stream + ")" + " -d (" + dir + File.separator + + streamFile + File.separator + algFile + ".txt" + ")"; + } + + auxTask.getOptions().setViaCLIString(task); + + try { + tasks[taskCount] = (MainTask) auxTask.copy(); + } catch (Exception ex) { + Logger.getLogger(TaskManagerTabPanel.class.getName()).log(Level.SEVERE, null, ex); + } + + taskCount++; + } + } + + Buffer buffer = new Buffer(tasks); + int proc = expCLI.getThreads(); + + if (proc > tasks.length) { + proc = tasks.length; + } + for (int i = 0; i < proc; i++) { + ExpTaskThread thread = new ExpTaskThread(buffer); + thread.start(); + this.taskList.add(0, thread); + this.taskTableModel.fireTableDataChanged(); + this.taskTable.setRowSelectionInterval(0, 0); + + } + + System.err.println(Globals.getWorkbenchInfoString()); + while (true) { + int count = 0; + int progressAnimIndex = 0; + StringBuilder progressLine = new StringBuilder(); + progressLine.append('\r'); + + for (ExpTaskThread thread : this.taskList) { + //System.out.println(thread.getCurrentActivityFracComplete()*100); + + if (thread.isCompleted == true) { + count++; + //System.out.println(count); + } + progressLine.append(StringUtils.secondsToDHMSString(thread.getCPUSecondsElapsed())); + progressLine.append(" ["); + progressLine.append(thread.getCurrentStatusString()); + progressLine.append("] "); + double fracComplete = thread.getCurrentActivityFracComplete(); + if (fracComplete >= 0.0) { + progressLine.append(StringUtils.doubleToString( + fracComplete * 100.0, 2, 2)); + progressLine.append("% "); + + } + //progressLine.append(thread.getCurrentActivityString()); + + } + System.out.print(progressLine); + System.out.print('\r'); + System.out.flush(); + try { + Thread.sleep(1000); + + } catch (InterruptedException ignored) { + // wake up + } + if (count == this.taskList.size()) { + TaskManagerTabPanel.this.summary.readData(resultsPath); + // TaskManagerTabPanel.this.plot.readData(resultsPath); + // TaskManagerTabPanel.this.analizeTab.readData(resultsPath); + System.out.println(); + System.out.println("To perform summaries type summary or exit to finish"); + Scanner sc = new Scanner(System.in); + String option = sc.nextLine(); + while (!option.equals("exit")) { + switch (option) { + case "summary": + System.out.println("Measures:"); + for (int i = 0; i < TaskManagerTabPanel.this.summary.measures.get(0).split(",").length; i++) { + System.out.println("[" + i + "] " + TaskManagerTabPanel.this.summary.measures.get(0).split(",")[i]); + } + System.out.println("Select Measeures: type -h for help"); + while (true) { + String arg[] = sc.nextLine().split(" "); + boolean out = expCLI.summary1CMD(arg); + if (out == true) { + if (expCLI.measures != null) { + String[] measures = new String[expCLI.measures.length]; + if (measures.length == expCLI.types.length) { + for (int i = 0; i < measures.length; i++) { + measures[i] = TaskManagerTabPanel.this.summary.measures.get(0).split(",")[expCLI.measures[i]]; + } + TaskManagerTabPanel.this.summary.summaryCMD(measures, expCLI.types); + + break; + } else { + System.out.println("There must be the same number of measures and types, please enter the commands again"); + } + } + } + + } + break; + } + System.out.println("To perform summaries type summary or exit to finish"); + option = sc.nextLine(); + } +// String arg = sc.nextLine(); +// System.out.println(arg); + break; + } + } + } + } + + /** + * + * @return a task thread + */ + public void taskSelectionChanged() { + ExpTaskThread[] selectedTasks = getSelectedTasks(); + if (selectedTasks.length == 1) { + if (this.previewPanel != null) { + this.previewPanel.setTaskThreadToPreview(selectedTasks[0]); + } + } else { + this.previewPanel.setTaskThreadToPreview(null); + } + } + + public ExpTaskThread[] getSelectedTasks() { + int[] selectedRows = this.taskTable.getSelectedRows(); + ExpTaskThread[] selectedTasks = new ExpTaskThread[selectedRows.length]; + for (int i = 0; i < selectedRows.length; i++) { + selectedTasks[i] = this.taskList.get(selectedRows[i]); + } + return selectedTasks; + } + + /** + * Pause tasks + */ + public void pauseSelectedTasks() { + ExpTaskThread[] selectedTasks = getSelectedTasks(); + for (ExpTaskThread thread : selectedTasks) { + thread.pauseTask(); + } + } + + /** + * Reseme task + */ + public void resumeSelectedTasks() { + ExpTaskThread[] selectedTasks = getSelectedTasks(); + for (ExpTaskThread thread : selectedTasks) { + thread.resumeTask(); + } + } + + /** + * Cancel task + */ + public void cancelSelectedTasks() { + ExpTaskThread[] selectedTasks = getSelectedTasks(); + for (ExpTaskThread thread : selectedTasks) { + thread.cancelTask(); + } + } + + /** + * Deletes selected tasks + */ + public void deleteSelectedTasks() { + ExpTaskThread[] selectedTasks = getSelectedTasks(); + for (ExpTaskThread thread : selectedTasks) { + thread.cancelTask(); + this.taskList.remove(thread); + } + this.taskTableModel.fireTableDataChanged(); + } + + private void SaveConfig(String path) { + Properties prop = new Properties(); + String algShortNames = "", algCommand = ""; + String streamShortNames = "", streamCommand = ""; + String expCLI = ""; + if (jTableAlgorithms.getRowCount() != 0) { + algCommand += jTableAlgorithms.getModel().getValueAt(0, 0); + algShortNames += jTableAlgorithms.getModel().getValueAt(0, 1); + } + if (jTableStreams.getRowCount() != 0) { + streamCommand += jTableStreams.getModel().getValueAt(0, 0); + streamShortNames += jTableStreams.getModel().getValueAt(0, 1); + } + for (int i = 1; i < jTableAlgorithms.getRowCount(); i++) { + algCommand += "," + jTableAlgorithms.getModel().getValueAt(i, 0); + algShortNames += "," + jTableAlgorithms.getModel().getValueAt(i, 1); + } + for (int j = 1; j < jTableStreams.getRowCount(); j++) { + streamCommand += "," + jTableStreams.getModel().getValueAt(j, 0); + streamShortNames += "," + jTableStreams.getModel().getValueAt(j, 1); + } + expCLI += "-ts \"" + jTextFieldTask.getText() + "\" "; + expCLI += "-ls \"" + algCommand + "\" "; + expCLI += "-lss \"" + algShortNames + "\" "; + expCLI += "-ds \"" + streamCommand + "\" "; + expCLI += "-dss \"" + streamShortNames + "\" "; + expCLI += "-th " + jTextFieldProcess.getText() + " "; + expCLI += "-rf \"" + FilenameUtils.separatorsToSystem(this.jTextFieldDir.getText()) + "\" "; + prop.setProperty("expCLI", expCLI); + + prop.setProperty("task", jTextFieldTask.getText()); + + prop.setProperty("processors", jTextFieldProcess.getText()); + + prop.setProperty("algorithmCommand", algCommand); + prop.setProperty("algorithmShortNames", algShortNames); + + prop.setProperty("streamCommand", streamCommand); + prop.setProperty("streamShortNames", streamShortNames); + prop.setProperty("ResultsDir", this.resultsPath); + path += ".properties"; + FileOutputStream propertiesFile = null; + File f = new File(path); + if (!f.exists()) { + f.delete(); + } + try { + propertiesFile = new FileOutputStream(path); + } catch (FileNotFoundException ex) { + JOptionPane.showMessageDialog(this, "Problems creating properties file", + "Error", JOptionPane.ERROR_MESSAGE); + } + try { + prop.store(propertiesFile, "file"); + JOptionPane.showMessageDialog(this, "Experiments saved at " + path, + "", JOptionPane.INFORMATION_MESSAGE); + } catch (IOException ex) { + JOptionPane.showMessageDialog(this, "Problems creating properties file", + "Error", JOptionPane.ERROR_MESSAGE); + } + + } + + /** + * Opens a previously saved configuration + * + * @param path + */ + public void openConfig(String path) { + + Properties properties = new Properties(); + try { + properties.load(new FileInputStream(path)); + } catch (IOException ex) { + JOptionPane.showMessageDialog(this, "Problems reading the properties file", + "Error", JOptionPane.ERROR_MESSAGE); + } + // read datasets + this.jTextFieldProcess.setText(properties.getProperty("processors")); + this.jTextFieldTask.setText(properties.getProperty("task")); + try { + this.currentTask = (MainTask) ClassOption.cliStringToObject( + this.jTextFieldTask.getText(), MainTask.class, null); + } catch (Exception ex) { + Logger.getLogger(TaskManagerTabPanel.class.getName()).log(Level.SEVERE, null, ex); + } + this.jTextFieldDir.setText(properties.getProperty("ResultsDir")); + this.resultsPath = this.jTextFieldDir.getText(); + String[] streamShortNames = properties.getProperty("streamShortNames").split(","); + String[] streamCommand = properties.getProperty("streamCommand").split(","); + String[] algShortNames = properties.getProperty("algorithmShortNames").split(","); + String[] algorithmCommand = properties.getProperty("algorithmCommand").split(","); + cleanTables(); + for (int i = 0; i < streamShortNames.length; i++) { + this.streamModel.addRow(new Object[]{streamCommand[i], streamShortNames[i]}); + } + for (int i = 0; i < algShortNames.length; i++) { + this.algoritmModel.addRow(new Object[]{algorithmCommand[i], algShortNames[i]}); + } + + } + + /** + * Clean the tables + */ + public void cleanTables() { + try { + DefaultTableModel algModel = (DefaultTableModel) jTableAlgorithms.getModel(); + DefaultTableModel strModel = (DefaultTableModel) jTableStreams.getModel(); + int rows = jTableAlgorithms.getRowCount(); + int srow = jTableStreams.getRowCount(); + int trow = this.taskList.size(); + for (int i = 0; i < rows; i++) { + algModel.removeRow(0); + } + for (int i = 0; i < srow; i++) { + strModel.removeRow(0); + } + for (int i = 0; i < trow; i++) { + this.taskList.remove(0); + } + this.taskTableModel.fireTableDataChanged(); + } catch (Exception e) { + JOptionPane.showMessageDialog(null, "Error al limpiar la tabla."); + } + } + + /** + * Main method + * + * @param args + */ + public static void main(String[] args) { + try { + UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); + javax.swing.SwingUtilities.invokeLater(new Runnable() { + + @Override + public void run() { + if (args.length != 0) { + //System.out.println("OK"); + TaskManagerTabPanel panel = new TaskManagerTabPanel(); + panel.runTaskCLI(args); + System.exit(0); + + } else { + createAndShowGUI(); + } + } + }); + } catch (Exception e) { + e.printStackTrace(); + } + } +} diff --git a/moa/src/main/java/moa/gui/experimentertab/TaskTextViewerPanel.java b/moa/src/main/java/moa/gui/experimentertab/TaskTextViewerPanel.java new file mode 100644 index 000000000..e87c2c03c --- /dev/null +++ b/moa/src/main/java/moa/gui/experimentertab/TaskTextViewerPanel.java @@ -0,0 +1,561 @@ +/* + * TaskTextViewerPanel.java + * Copyright (C) 2007 University of Waikato, Hamilton, New Zealand + * @author Richard Kirkby (rkirkby@cs.waikato.ac.nz) + * @author Jansen (moa@cs.rwth-aachen.de) + * + * 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 moa.gui.experimentertab; + +import java.awt.BorderLayout; +import java.awt.Dimension; +import java.awt.Font; +import java.awt.GridLayout; +import java.awt.Point; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.io.PrintWriter; +import java.util.ArrayList; +import java.util.Scanner; + +import javax.swing.JButton; +import javax.swing.JFileChooser; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.JTextArea; +import moa.evaluation.MeasureCollection; +import moa.gui.FileExtensionFilter; +import moa.gui.GUIUtils; +import moa.gui.conceptdrift.CDTaskManagerPanel; +import moa.gui.experimentertab.ExpPreviewPanel.TypePanel; +import moa.streams.clustering.ClusterEvent; +import moa.tasks.ConceptDriftMainTask; + +/** + * This panel displays text. Used to output the results of tasks. + * + * @author Richard Kirkby (rkirkby@cs.waikato.ac.nz) + * @version $Revision: 7 $ + */ +public class TaskTextViewerPanel extends JPanel implements ActionListener { + + private static final long serialVersionUID = 1L; + + public static String exportFileExtension = "txt"; + + protected JTextArea textArea; + + protected JScrollPane scrollPane; + + protected JButton exportButton; + + private javax.swing.JPanel topWrapper; + + private javax.swing.JSplitPane jSplitPane1; + + //Added for stream events + protected CDTaskManagerPanel taskManagerPanel; + + protected TypePanel typePanel; + + public void initVisualEvalPanel() { + acc1[0] = getNewMeasureCollection(); + acc2[0] = getNewMeasureCollection(); + if (clusteringVisualEvalPanel1 != null) { + panelEvalOutput.remove(clusteringVisualEvalPanel1); + } + clusteringVisualEvalPanel1 = new moa.gui.clustertab.ClusteringVisualEvalPanel(); + clusteringVisualEvalPanel1.setMeasures(acc1, acc2, this); + this.graphCanvas.setGraph(acc1[0], acc2[0], 0, 1000); + this.graphCanvas.forceAddEvents(); + clusteringVisualEvalPanel1.setMinimumSize(new java.awt.Dimension(280, 118)); + clusteringVisualEvalPanel1.setPreferredSize(new java.awt.Dimension(290, 115)); + panelEvalOutput.add(clusteringVisualEvalPanel1, gridBagConstraints); + } + public TaskTextViewerPanel() { + this(TypePanel.CLASSIFICATION, null); + } + + public java.awt.GridBagConstraints gridBagConstraints; + + public TaskTextViewerPanel(ExpPreviewPanel.TypePanel typePanel, CDTaskManagerPanel taskManagerPanel) { + this.typePanel = typePanel; + this.taskManagerPanel = taskManagerPanel; + jSplitPane1 = new javax.swing.JSplitPane(); + topWrapper = new javax.swing.JPanel(); + + this.textArea = new JTextArea(); + this.textArea.setEditable(false); + this.textArea.setFont(new Font("Monospaced", Font.PLAIN, 12)); + this.exportButton = new JButton("Export as .txt file..."); + this.exportButton.setEnabled(false); + JPanel buttonPanel = new JPanel(); + buttonPanel.setLayout(new GridLayout(1, 2)); + buttonPanel.add(this.exportButton); + topWrapper.setLayout(new BorderLayout()); + this.scrollPane = new JScrollPane(this.textArea); + topWrapper.add(this.scrollPane, BorderLayout.CENTER); + topWrapper.add(buttonPanel, BorderLayout.SOUTH); + this.exportButton.addActionListener(new ActionListener() { + + public void actionPerformed(ActionEvent e) { + JFileChooser fileChooser = new JFileChooser(); + fileChooser.setAcceptAllFileFilterUsed(true); + fileChooser.addChoosableFileFilter(new FileExtensionFilter( + exportFileExtension)); + if (fileChooser.showSaveDialog(TaskTextViewerPanel.this) == JFileChooser.APPROVE_OPTION) { + File chosenFile = fileChooser.getSelectedFile(); + String fileName = chosenFile.getPath(); + if (!chosenFile.exists() + && !fileName.endsWith(exportFileExtension)) { + fileName = fileName + "." + exportFileExtension; + } + try { + PrintWriter out = new PrintWriter(new BufferedWriter( + new FileWriter(fileName))); + out.write(TaskTextViewerPanel.this.textArea.getText()); + out.close(); + } catch (IOException ioe) { + GUIUtils.showExceptionDialog( + TaskTextViewerPanel.this.exportButton, + "Problem saving file " + fileName, ioe); + } + } + } + }); + //topWrapper.add(this.scrollPane); + //topWrapper.add(buttonPanel); + + panelEvalOutput = new javax.swing.JPanel(); + //clusteringVisualEvalPanel1 = new moa.gui.clustertab.ClusteringVisualEvalPanel(); + graphPanel = new javax.swing.JPanel(); + graphPanelControlTop = new javax.swing.JPanel(); + buttonZoomInY = new javax.swing.JButton(); + buttonZoomOutY = new javax.swing.JButton(); + labelEvents = new javax.swing.JLabel(); + graphScrollPanel = new javax.swing.JScrollPane(); + graphCanvas = new moa.gui.visualization.GraphCanvas(); + // New EventClusters + //clusterEvents = new ArrayList<ClusterEvent>(); + //clusterEvents.add(new ClusterEvent(this,100,"Change", "Drift")); + //graphCanvas.setClusterEventsList(clusterEvents); + + graphPanelControlBottom = new javax.swing.JPanel(); + buttonZoomInX = new javax.swing.JButton(); + buttonZoomOutX = new javax.swing.JButton(); + + setLayout(new java.awt.GridBagLayout()); + + jSplitPane1.setDividerLocation(200); + jSplitPane1.setOrientation(javax.swing.JSplitPane.VERTICAL_SPLIT); + + //topWrapper.setPreferredSize(new java.awt.Dimension(688, 500)); + //topWrapper.setLayout(new java.awt.GridBagLayout()); + + jSplitPane1.setLeftComponent(topWrapper); + + panelEvalOutput.setBorder(javax.swing.BorderFactory.createTitledBorder("Evaluation")); + panelEvalOutput.setLayout(new java.awt.GridBagLayout()); + + //clusteringVisualEvalPanel1.setMinimumSize(new java.awt.Dimension(280, 118)); + //clusteringVisualEvalPanel1.setPreferredSize(new java.awt.Dimension(290, 115)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 0; + gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH; + gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST; + gridBagConstraints.weighty = 1.0; + //panelEvalOutput.add(clusteringVisualEvalPanel1, gridBagConstraints); + initVisualEvalPanel(); + + + graphPanel.setBorder(javax.swing.BorderFactory.createTitledBorder("Plot")); + graphPanel.setPreferredSize(new java.awt.Dimension(530, 115)); + graphPanel.setLayout(new java.awt.GridBagLayout()); + + graphPanelControlTop.setLayout(new java.awt.GridBagLayout()); + + buttonZoomInY.setText("Zoom in Y"); + buttonZoomInY.addActionListener(new java.awt.event.ActionListener() { + + public void actionPerformed(java.awt.event.ActionEvent evt) { + buttonZoomInYActionPerformed(evt); + } + }); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.insets = new java.awt.Insets(0, 2, 0, 2); + graphPanelControlTop.add(buttonZoomInY, gridBagConstraints); + + buttonZoomOutY.setText("Zoom out Y"); + buttonZoomOutY.addActionListener(new java.awt.event.ActionListener() { + + public void actionPerformed(java.awt.event.ActionEvent evt) { + buttonZoomOutYActionPerformed(evt); + } + }); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.insets = new java.awt.Insets(0, 2, 0, 2); + graphPanelControlTop.add(buttonZoomOutY, gridBagConstraints); + + labelEvents.setHorizontalAlignment(javax.swing.SwingConstants.CENTER); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.weightx = 1.0; + gridBagConstraints.insets = new java.awt.Insets(0, 2, 0, 2); + graphPanelControlTop.add(labelEvents, gridBagConstraints); + + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 0; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST; + gridBagConstraints.weightx = 1.0; + graphPanel.add(graphPanelControlTop, gridBagConstraints); + + graphCanvas.setPreferredSize(new java.awt.Dimension(500, 111)); + + javax.swing.GroupLayout graphCanvasLayout = new javax.swing.GroupLayout(graphCanvas); + graphCanvas.setLayout(graphCanvasLayout); + graphCanvasLayout.setHorizontalGroup( + graphCanvasLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING).addGap(0, 515, Short.MAX_VALUE)); + graphCanvasLayout.setVerticalGroup( + graphCanvasLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING).addGap(0, 128, Short.MAX_VALUE)); + + graphScrollPanel.setViewportView(graphCanvas); + + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 1; + gridBagConstraints.gridwidth = 2; + gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH; + gridBagConstraints.weightx = 1.0; + gridBagConstraints.weighty = 1.0; + gridBagConstraints.insets = new java.awt.Insets(2, 2, 2, 2); + graphPanel.add(graphScrollPanel, gridBagConstraints); + + buttonZoomInX.setText("Zoom in X"); + buttonZoomInX.addActionListener(new java.awt.event.ActionListener() { + + public void actionPerformed(java.awt.event.ActionEvent evt) { + buttonZoomInXActionPerformed(evt); + } + }); + graphPanelControlBottom.add(buttonZoomInX); + + buttonZoomOutX.setText("Zoom out X"); + buttonZoomOutX.addActionListener(new java.awt.event.ActionListener() { + + public void actionPerformed(java.awt.event.ActionEvent evt) { + buttonZoomOutXActionPerformed(evt); + } + }); + graphPanelControlBottom.add(buttonZoomOutX); + + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 1; + gridBagConstraints.gridy = 0; + gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST; + graphPanel.add(graphPanelControlBottom, gridBagConstraints); + + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH; + gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST; + gridBagConstraints.weightx = 2.0; + gridBagConstraints.weighty = 1.0; + panelEvalOutput.add(graphPanel, gridBagConstraints); + + jSplitPane1.setRightComponent(panelEvalOutput); + + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH; + gridBagConstraints.weightx = 1.0; + gridBagConstraints.weighty = 1.0; + add(jSplitPane1, gridBagConstraints); + + // acc1[0] = getNewMeasureCollection(); + + //acc2[0] = getNewMeasureCollection(); + //clusteringVisualEvalPanel1.setMeasures(acc1, acc2, this); + //this.graphCanvas.setGraph(acc1[0], acc2[0], 0, 1000); + + } + + public void setText(String newText) { + Point p = this.scrollPane.getViewport().getViewPosition(); + this.textArea.setText(newText); + this.scrollPane.getViewport().setViewPosition(p); + this.exportButton.setEnabled(newText != null); + setGraph(newText); + } + + protected MeasureCollection[] acc1 = new MeasureCollection[1]; + + protected MeasureCollection[] acc2 = new MeasureCollection[1]; + + protected String secondLine = ""; + + protected double round(double d) { + return (Math.rint(d * 100) / 100); + } + + protected MeasureCollection getNewMeasureCollection() { + /*if (this.taskManagerPanel != null) { + return new ChangeDetectionMeasures(); + } else { + return new Accuracy(); + }*/ + return this.typePanel.getMeasureCollection(); + } + + public void setGraph(String preview) { + //Change the graph when there is change in the text + double processFrequency = 1000; + if (preview != null && !preview.equals("")) { + MeasureCollection oldAccuracy = acc1[0]; + acc1[0] = getNewMeasureCollection(); + Scanner scanner = new Scanner(preview); + String firstLine = scanner.nextLine(); + boolean isSecondLine = true; + + boolean isPrequential = firstLine.startsWith("learning evaluation instances,evaluation time"); + boolean isHoldOut = firstLine.startsWith("evaluation instances,to"); + int accuracyColumn = 6; + int kappaColumn = 4; + int RamColumn = 2; + int timeColumn = 1; + int memoryColumn = 9; + int kappaTempColumn = 5; + if (this.taskManagerPanel instanceof CDTaskManagerPanel) { + accuracyColumn = 6; + kappaColumn = 4; + RamColumn = 2; + timeColumn = 1; + memoryColumn = 9; + } else if (isPrequential || isHoldOut) { + accuracyColumn = 4; + kappaColumn = 5; + RamColumn = 2; + timeColumn = 1; + memoryColumn = 7; + kappaTempColumn = 5; + String[] tokensFirstLine = firstLine.split(","); + int i = 0; + for (String s : tokensFirstLine) { + if (s.equals("classifications correct (percent)") || s.equals("[avg] classifications correct (percent)")) { + accuracyColumn = i; + } else if (s.equals("Kappa Statistic (percent)") || s.equals("[avg] Kappa Statistic (percent)")) { + kappaColumn = i; + } else if (s.equals("Kappa Temporal Statistic (percent)") || s.equals("[avg] Kappa Temporal Statistic (percent)")) { + kappaTempColumn = i; + } else if (s.equals("model cost (RAM-Hours)")) { + RamColumn = i; + } else if (s.equals("evaluation time (cpu seconds)") + || s.equals("total train time")) { + timeColumn = i; + } else if (s.equals("model serialized size (bytes)")) { + memoryColumn = i; + } + i++; + } + } + if (isPrequential || isHoldOut || this.taskManagerPanel instanceof CDTaskManagerPanel) { + while (scanner.hasNextLine()) { + String line = scanner.nextLine(); + String[] tokens = line.split(","); + this.acc1[0].addValue(0, round(parseDouble(tokens[accuracyColumn]))); + this.acc1[0].addValue(1, round(parseDouble(tokens[kappaColumn]))); + this.acc1[0].addValue(2, round(parseDouble(tokens[kappaTempColumn]))); + if (!isHoldOut) { + this.acc1[0].addValue(3, Math.abs(parseDouble(tokens[RamColumn]))); + } + this.acc1[0].addValue(4, round(parseDouble(tokens[timeColumn]))); + this.acc1[0].addValue(5, round(parseDouble(tokens[memoryColumn]) / (1024 * 1024))); + + if (isSecondLine == true) { + processFrequency = Math.abs(parseDouble(tokens[0])); + isSecondLine = false; + if (acc1[0].getValue(0, 0) != oldAccuracy.getValue(0, 0)) { //(!line.equals(secondLine)) { + //If we are in a new task, compare with the previous + secondLine = line; + if (processFrequency == this.graphCanvas.getProcessFrequency()) { + acc2[0] = oldAccuracy; + } + } + } + } + } else { + this.acc2[0] = getNewMeasureCollection(); + } + + } else { + this.acc1[0] = getNewMeasureCollection(); + this.acc2[0] = getNewMeasureCollection(); + } + + + if (this.taskManagerPanel instanceof CDTaskManagerPanel) { + ConceptDriftMainTask cdTask = this.taskManagerPanel.getSelectedCurrenTask(); + ArrayList<ClusterEvent> clusterEvents = cdTask.getEventsList(); + this.graphCanvas.setClusterEventsList(clusterEvents); + } + this.graphCanvas.setGraph(acc1[0], acc2[0], this.graphCanvas.getMeasureSelected(), (int) processFrequency); + this.graphCanvas.updateCanvas(true); + this.graphCanvas.forceAddEvents(); + this.clusteringVisualEvalPanel1.update(); + + } + + private double parseDouble(String s) { + double ret = 0; + if (s.equals("?") == false) { + ret = Double.parseDouble(s); + } + return ret; + } + + private void scrollPane0MouseWheelMoved(java.awt.event.MouseWheelEvent evt) {//GEN-FIRST:event_scrollPane0MouseWheelMoved + streamPanel0.setZoom(evt.getX(), evt.getY(), (-1) * evt.getWheelRotation(), scrollPane0); + }//GEN-LAST:event_scrollPane0MouseWheelMoved + + private void buttonZoomInXActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonZoomInXActionPerformed + graphCanvas.scaleXResolution(false); + }//GEN-LAST:event_buttonZoomInXActionPerformed + + private void buttonZoomOutYActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonZoomOutYActionPerformed + graphCanvas.setSize(new Dimension(graphCanvas.getWidth(), (int) (graphCanvas.getHeight() * 0.8))); + graphCanvas.setPreferredSize(new Dimension(graphCanvas.getWidth(), (int) (graphCanvas.getHeight() * 0.8))); + this.graphCanvas.updateCanvas(true); + }//GEN-LAST:event_buttonZoomOutYActionPerformed + + private void buttonZoomOutXActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonZoomOutXActionPerformed + graphCanvas.scaleXResolution(true); + }//GEN-LAST:event_buttonZoomOutXActionPerformed + + private void buttonZoomInYActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonZoomInYActionPerformed + graphCanvas.setSize(new Dimension(graphCanvas.getWidth(), (int) (graphCanvas.getHeight() * 1.2))); + graphCanvas.setPreferredSize(new Dimension(graphCanvas.getWidth(), (int) (graphCanvas.getHeight() * 1.2))); + this.graphCanvas.updateCanvas(true); + }//GEN-LAST:event_buttonZoomInYActionPerformed + + private void buttonRunActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonRunActionPerformed + // TODO add your handling code here: + }//GEN-LAST:event_buttonRunActionPerformed + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JButton buttonRun; + + private javax.swing.JButton buttonScreenshot; + + private javax.swing.JButton buttonStop; + + private javax.swing.JButton buttonZoomInX; + + private javax.swing.JButton buttonZoomInY; + + private javax.swing.JButton buttonZoomOutX; + + private javax.swing.JButton buttonZoomOutY; + + private javax.swing.JCheckBox checkboxDrawClustering; + + private javax.swing.JCheckBox checkboxDrawGT; + + private javax.swing.JCheckBox checkboxDrawMicro; + + private javax.swing.JCheckBox checkboxDrawPoints; + + private moa.gui.clustertab.ClusteringVisualEvalPanel clusteringVisualEvalPanel1; + + private javax.swing.JComboBox comboX; + + private javax.swing.JComboBox comboY; + + private moa.gui.visualization.GraphCanvas graphCanvas; + + private javax.swing.JPanel graphPanel; + + private javax.swing.JPanel graphPanelControlBottom; + + private javax.swing.JPanel graphPanelControlTop; + + private javax.swing.JScrollPane graphScrollPanel; + + private javax.swing.JLabel jLabel1; + + private javax.swing.JLabel labelEvents; + + private javax.swing.JLabel labelNumPause; + + private javax.swing.JLabel labelX; + + private javax.swing.JLabel labelY; + + private javax.swing.JLabel label_processed_points; + + private javax.swing.JLabel label_processed_points_value; + + private javax.swing.JTextField numPauseAfterPoints; + + private javax.swing.JPanel panelControl; + + private javax.swing.JPanel panelEvalOutput; + + private javax.swing.JPanel panelVisualWrapper; + + private javax.swing.JScrollPane scrollPane0; + + private javax.swing.JScrollPane scrollPane1; + + private javax.swing.JSlider speedSlider; + + private javax.swing.JSplitPane splitVisual; + + private moa.gui.visualization.StreamPanel streamPanel0; + + private moa.gui.visualization.StreamPanel streamPanel1; + + @Override + public void actionPerformed(ActionEvent e) { + //reacte on graph selection and find out which measure was selected + int selected = Integer.parseInt(e.getActionCommand()); + int counter = selected; + int m_select = 0; + int m_select_offset = 0; + boolean found = false; + for (int i = 0; i < acc1.length; i++) { + for (int j = 0; j < acc1[i].getNumMeasures(); j++) { + if (acc1[i].isEnabled(j)) { + counter--; + if (counter < 0) { + m_select = i; + m_select_offset = j; + found = true; + break; + } + } + } + if (found) { + break; + } + } + this.graphCanvas.setGraph(acc1[m_select], acc2[m_select], m_select_offset, this.graphCanvas.getProcessFrequency()); + this.graphCanvas.forceAddEvents(); + } +} diff --git a/moa/src/main/java/moa/gui/experimentertab/statisticaltests/CDF_Normal.java b/moa/src/main/java/moa/gui/experimentertab/statisticaltests/CDF_Normal.java new file mode 100644 index 000000000..eb2a61250 --- /dev/null +++ b/moa/src/main/java/moa/gui/experimentertab/statisticaltests/CDF_Normal.java @@ -0,0 +1,215 @@ +package moa.gui.experimentertab.statisticaltests; + +/** +* +*This class contains routines to calculate the +*normal cumulative distribution function (CDF) and +*its inverse. +* +*@version .5 --- June 7, 1996 +*@version .6 --- January 10, 2001 (normcdf added) +* +*/ + +public class CDF_Normal extends Object { + +/** +* +*This method calculates the normal cdf inverse function. +*<p> +*Let PHI(x) be the normal cdf. Suppose that Q calculates +*1.0 - PHI(x), and that QINV calculates QINV(p) for p in (0.0,.5]. +*Then for p .le. .5, x = PHIINV(p) = -QINV(p). +*For p .gt. .5, x = PHIINV(p) = QINV(1.0 - p). +*The formula for approximating QINV is taken from Abramowitz and Stegun, +*Handbook of Mathematical Functions, Dover, 9th printing, +*formula 26.2.3, page 933. The error in x is claimed to +*be less than 4.5e-4 in absolute value. +* +*@param p p must lie between 0 and 1. xnormi returns +* the normal cdf inverse evaluated at p. +* +*@author Steve Verrill +*@version .5 --- June 7, 1996 + * @return +* +*/ + +// FIX: Eventually I should build in a check that p lies in (0,1) + + public static double xnormi(double p) { + + double arg,t,t2,t3,xnum,xden,qinvp,x,pc; + + final double c[] = {2.515517, + .802853, + .010328}; + + final double d[] = {1.432788, + .189269, + .001308}; + + if (p <= .5) { + + arg = -2.0*Math.log(p); + t = Math.sqrt(arg); + t2 = t*t; + t3 = t2*t; + + xnum = c[0] + c[1]*t + c[2]*t2; + xden = 1.0 + d[0]*t + d[1]*t2 + d[2]*t3; + qinvp = t - xnum/xden; + x = -qinvp; + + return x; + + } + + else { + + pc = 1.0 - p; + arg = -2.0*Math.log(pc); + t = Math.sqrt(arg); + t2 = t*t; + t3 = t2*t; + + xnum = c[0] + c[1]*t + c[2]*t2; + xden = 1.0 + d[0]*t + d[1]*t2 + d[2]*t3; + x = t - xnum/xden; + + return x; + + } + + } + + +/** +* +*This method calculates the normal cumulative distribution function. +*<p> +*It is based upon algorithm 5666 for the error function, from:<p> +*<pre> +* Hart, J.F. et al, 'Computer Approximations', Wiley 1968 +*</pre> +*<p> +*The FORTRAN programmer was Alan Miller. The documentation +*in the FORTRAN code claims that the function is "accurate +*to 1.e-15."<p> +*Steve Verrill +*translated the FORTRAN code (the March 30, 1986 version) +*into Java. This translation was performed on January 10, 2001. +* +*@param z The method returns the value of the normal +* cumulative distribution function at z. +* +*@version .5 --- January 10, 2001 + * @return +* +*/ + + +/* + +Here is a copy of the documentation in the FORTRAN code: + + SUBROUTINE NORMP(Z, P, Q, PDF) +C +C Normal distribution probabilities accurate to 1.e-15. +C Z = no. of standard deviations from the mean. +C P, Q = probabilities to the left & right of Z. P + Q = 1. +C PDF = the probability density. +C +C Based upon algorithm 5666 for the error function, from: +C Hart, J.F. et al, 'Computer Approximations', Wiley 1968 +C +C Programmer: Alan Miller +C +C Latest revision - 30 March 1986 +C + +*/ + + public static double normp(double z) { + + double zabs; + double p; + double expntl,pdf; + + final double p0 = 220.2068679123761; + final double p1 = 221.2135961699311; + final double p2 = 112.0792914978709; + final double p3 = 33.91286607838300; + final double p4 = 6.373962203531650; + final double p5 = .7003830644436881; + final double p6 = .3526249659989109E-01; + + final double q0 = 440.4137358247522; + final double q1 = 793.8265125199484; + final double q2 = 637.3336333788311; + final double q3 = 296.5642487796737; + final double q4 = 86.78073220294608; + final double q5 = 16.06417757920695; + final double q6 = 1.755667163182642; + final double q7 = .8838834764831844E-1; + + final double cutoff = 7.071; + final double root2pi = 2.506628274631001; + + zabs = Math.abs(z); + +// |z| > 37 + + if (z > 37.0) { + + p = 1.0; + + return p; + + } + + if (z < -37.0) { + + p = 0.0; + + return p; + + } + +// |z| <= 37. + + expntl = Math.exp(-.5*zabs*zabs); + + pdf = expntl/root2pi; + +// |z| < cutoff = 10/sqrt(2). + + if (zabs < cutoff) { + + p = expntl*((((((p6*zabs + p5)*zabs + p4)*zabs + p3)*zabs + + p2)*zabs + p1)*zabs + p0)/(((((((q7*zabs + q6)*zabs + + q5)*zabs + q4)*zabs + q3)*zabs + q2)*zabs + q1)*zabs + + q0); + + } else { + + p = pdf/(zabs + 1.0/(zabs + 2.0/(zabs + 3.0/(zabs + 4.0/ + (zabs + 0.65))))); + + } + + if (z < 0.0) { + + return p; + + } else { + + p = 1.0 - p; + + return p; + + } + + } + +} diff --git a/moa/src/main/java/moa/gui/experimentertab/statisticaltests/Fichero.java b/moa/src/main/java/moa/gui/experimentertab/statisticaltests/Fichero.java new file mode 100644 index 000000000..c832186c7 --- /dev/null +++ b/moa/src/main/java/moa/gui/experimentertab/statisticaltests/Fichero.java @@ -0,0 +1,92 @@ +package moa.gui.experimentertab.statisticaltests; + + +/* + * Created on 16-Jun-2004 + * + * Clase implementada funciones para el manejo de ficheros de datos + * + */ +/** + * @author Jes�s Alcal� Fern�ndez + * + * + */ +import java.io.*; + +/** + * + * @author Jes�s Alcal� Fern�ndez + */ +public class Fichero { + + /** + * + * @param nombreFichero + * @return + */ + public static String leeFichero(String nombreFichero) { + String cadena = ""; + + try { + FileInputStream fis = new FileInputStream(nombreFichero); + + byte[] leido = new byte[4096]; + int bytesLeidos = 0; + + while (bytesLeidos != -1) { + bytesLeidos = fis.read(leido); + + if (bytesLeidos != -1) { + cadena += new String(leido, 0, bytesLeidos); + } + } + + fis.close(); + } catch (IOException e) { + e.printStackTrace(); + System.exit(-1); + } + + return cadena; + } + + /** + * + * @param nombreFichero + * @param cadena + */ + public static void escribeFichero(String nombreFichero, String cadena) { + try { + FileOutputStream f = new FileOutputStream(nombreFichero); + DataOutputStream fis = new DataOutputStream((OutputStream) f); + + fis.writeBytes(cadena); + + fis.close(); + } catch (IOException e) { + e.printStackTrace(); + System.exit(-1); + } + } + + /** + * + * @param nombreFichero + * @param cadena + */ + public static void AnadirtoFichero(String nombreFichero, String cadena) { + try { + RandomAccessFile fis = new RandomAccessFile(nombreFichero, "rw"); + fis.seek(fis.length()); + + fis.writeBytes(cadena); + + fis.close(); + } catch (IOException e) { + e.printStackTrace(); + System.exit(-1); + } + } + +} diff --git a/moa/src/main/java/moa/gui/experimentertab/statisticaltests/PValuePerTwoAlgorithm.java b/moa/src/main/java/moa/gui/experimentertab/statisticaltests/PValuePerTwoAlgorithm.java new file mode 100644 index 000000000..4ed28cb98 --- /dev/null +++ b/moa/src/main/java/moa/gui/experimentertab/statisticaltests/PValuePerTwoAlgorithm.java @@ -0,0 +1,73 @@ +/* + * PValuePerTwoAlgorithm.java + * Copyright (C) 2007 University of Waikato, Hamilton, New Zealand + * @author Alberto Verdecia Cabrera (averdeciac@gmail.com) + * + * 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 moa.gui.experimentertab.statisticaltests; + +import java.util.ArrayList; + +/** + * + * @author Alberto Verdecia Cabrera (averdeciac@gmail.com) + */ +public class PValuePerTwoAlgorithm { + + public String algName1; + + public String algName2; + + public double PValue; + + /** + * Costructor. + * @param algName1 + * @param algName2 + * @param PValue + */ + public PValuePerTwoAlgorithm(String algName1, String algName2, double PValue) { + this.algName1 = algName1; + this.algName2 = algName2; + this.PValue = PValue; + } + + /** + * + * @param PValue + * @return + */ + public boolean isSignicativeBetterThan(double PValue){ + return this.PValue >= PValue; + } + + /** + * + * @param pvalues + * @param name1 + * @param name2 + * @return + */ + public static int getIndex(ArrayList<PValuePerTwoAlgorithm> pvalues, String name1, String name2){ + for(int i = 0; i < pvalues.size(); i++){ + if(pvalues.get(i).algName1.equals(name1)==true && pvalues.get(i).algName2.equals(name2)==true + || pvalues.get(i).algName1.equals(name2)==true && pvalues.get(i).algName2.equals(name1)==true) + return i; + + } + return -1; + } +} diff --git a/moa/src/main/java/moa/gui/experimentertab/statisticaltests/Pareja.java b/moa/src/main/java/moa/gui/experimentertab/statisticaltests/Pareja.java new file mode 100644 index 000000000..fea80a37f --- /dev/null +++ b/moa/src/main/java/moa/gui/experimentertab/statisticaltests/Pareja.java @@ -0,0 +1,41 @@ +package moa.gui.experimentertab.statisticaltests; + +/** + * <p> + * T�tulo: </p> + * <p> + * Descripci�n: </p> + * <p> + * Copyright: Copyright (c) 2005</p> + * <p> + * Empresa: </p> + * + * @author sin atribuir + * @version 1.0 + */ +public class Pareja implements Comparable { + + public double indice; + public double valor; + + public Pareja() { + + } + + public Pareja(double i, double v) { + indice = i; + valor = v; + } + + public int compareTo(Object o1) { //ordena por valor absoluto + + if (Math.abs(this.valor) > Math.abs(((Pareja) o1).valor)) { + return -1; + } else if (Math.abs(this.valor) < Math.abs(((Pareja) o1).valor)) { + return 1; + } else { + return 0; + } + } + +} diff --git a/moa/src/main/java/moa/gui/experimentertab/statisticaltests/RankPerAlgorithm.java b/moa/src/main/java/moa/gui/experimentertab/statisticaltests/RankPerAlgorithm.java new file mode 100644 index 000000000..6300d63e5 --- /dev/null +++ b/moa/src/main/java/moa/gui/experimentertab/statisticaltests/RankPerAlgorithm.java @@ -0,0 +1,54 @@ +/* + * RankPerAlgorithm.java + * Copyright (C) 2007 University of Waikato, Hamilton, New Zealand + * @author Alberto Verdecia Cabrera (averdeciac@gmail.com) + * + * 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 moa.gui.experimentertab.statisticaltests; + +/** + * This class contains each algorithm with its ranking. + * + * @author Alberto Verdecia Cabrera (averdeciac@gmail.com) + */ +public class RankPerAlgorithm implements Comparable<RankPerAlgorithm> { + + public String algName; + public double rank; + + /** + * Constructor. + * + * @param algName + * @param rank + */ + public RankPerAlgorithm(String algName, double rank) { + this.algName = algName; + this.rank = rank; + } + + @Override + public int compareTo(RankPerAlgorithm r) { + if (rank < r.rank) { + return -1; + } + if (rank > r.rank) { + return 1; + } + return 0; + } + +} diff --git a/moa/src/main/java/moa/gui/experimentertab/statisticaltests/Relation.java b/moa/src/main/java/moa/gui/experimentertab/statisticaltests/Relation.java new file mode 100644 index 000000000..6867af01e --- /dev/null +++ b/moa/src/main/java/moa/gui/experimentertab/statisticaltests/Relation.java @@ -0,0 +1,35 @@ +package moa.gui.experimentertab.statisticaltests; + +/** + * <p> + * T�tulo: + * <p> + * Descripci�n: </p> + * <p> + * Copyright: Copyright (c) 2005</p> + * <p> + * Empresa: </p> + * + * @author sin atribuir + * @version 1.0 + */ +public class Relation { + + public int i; + public int j; + + public Relation() { + + } + + public Relation(int x, int y) { + i = x; + j = y; + } + + @Override + public String toString() { + return "(" + i + "," + j + ")"; + } + +} diff --git a/moa/src/main/java/moa/gui/experimentertab/statisticaltests/StatisticalTest.java b/moa/src/main/java/moa/gui/experimentertab/statisticaltests/StatisticalTest.java new file mode 100644 index 000000000..f36c01b1b --- /dev/null +++ b/moa/src/main/java/moa/gui/experimentertab/statisticaltests/StatisticalTest.java @@ -0,0 +1,673 @@ +/* + * StatisticalTest.java + * Copyright (C) 2007 University of Waikato, Hamilton, New Zealand + * @author Alberto Verdecia Cabrera (averdeciac@gmail.com) + * + * 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/>. + * The statistical tests programmed in this class were taken from + * KEEL(Knowledge Extraction based on Evolutionary Learning) software. + * KEEL is an open source (GPLv3) Java software tool that can be used for + * a large number of different knowledge data discovery tasks. + * J. Alcalá-Fdez, L. Sánchez, S. García, M.J. del Jesus, S. Ventura, + * J.M. Garrell, J. Otero, C. Romero, J. Bacardit, V.M. Rivas, J.C. Fernández, + * F. Herrera. KEEL: A Software Tool to Assess Evolutionary Algorithms to + * Data Mining Problems. Soft Computing 13:3 (2009) 307-318, + * doi: 10.1007/s00500-008-0323-y. + * J. Alcalá-Fdez, A. Fernandez, J. Luengo, J. Derrac, S. García, L. Sánchez, + * F. Herrera. KEEL Data-Mining Software Tool: Data Set Repository, + * Integration of Algorithms and Experimental Analysis Framework. Journal of + * Multiple-Valued Logic and Soft Computing 17:2-3 (2011) 255-287. + */ +package moa.gui.experimentertab.statisticaltests; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; +import java.util.StringTokenizer; +import moa.gui.experimentertab.Algorithm; +import moa.gui.experimentertab.Stream; + +/** + * + * @author Alberto Verdecia Cabrera (averdeciac@gmail.com) + */ +public class StatisticalTest { + + ArrayList algoritmos; + ArrayList datasets; + ArrayList datos; + //String linea, token; + int i, j, k, m; + int posicion; + double mean[][]; + Pareja orden[][]; + Pareja rank[][]; + boolean encontrado; + int ig; + double sum; + boolean visto[]; + ArrayList porVisitar; + double Rj[]; + double friedman; + double sumatoria = 0; + double termino1, termino2, termino3; + double iman; + boolean vistos[]; + int pos, tmp; + double min; + double maxVal; + double rankingRef; + double Pi[]; + double ALPHAiHolm[]; + double ALPHAiShaffer[]; + String ordenAlgoritmos[]; + double ordenRankings[]; + int order[]; + double adjustedP[][]; + double Ci[]; + double SE; + boolean parar, otro; + ArrayList indices = new ArrayList(); + ArrayList exhaustiveI = new ArrayList(); + boolean[][] cuadro; + double minPi, tmpPi, maxAPi, tmpAPi; + Relation[] parejitas; + int lineaN = 0; + int columnaN = 0; + ArrayList T; + int Tarray[]; + ArrayList<RankPerAlgorithm> rankAlg; + double pFriedman, pIman; + public List<Stream> streams = new ArrayList<>(); + + /** + * Constructor. + * + * @param streams + */ + public StatisticalTest(List<Stream> streams) { + this.streams = streams; + algoritmos = new ArrayList(); + datasets = new ArrayList(); + datos = new ArrayList(); + rankAlg = new ArrayList<>(); + + } + + /** + * Read a csv file from an path. + * + * @param path + */ + public void readCSV(String path) { + String cadena, linea, token; + StringTokenizer lineas, tokens; + cadena = Fichero.leeFichero(path); + lineas = new StringTokenizer(cadena, "\n\r"); + while (lineas.hasMoreTokens()) { + linea = lineas.nextToken(); + tokens = new StringTokenizer(linea, ",\t"); + columnaN = 0; + while (tokens.hasMoreTokens()) { + if (lineaN == 0) { + if (columnaN == 0) { + token = tokens.nextToken(); + } else { + token = tokens.nextToken(); + algoritmos.add(token); + datos.add(new ArrayList()); + } + } else { + if (columnaN == 0) { + token = tokens.nextToken(); + datasets.add(token); + } else { + token = tokens.nextToken(); + ((ArrayList) datos.get(columnaN - 1)).add(new Double(token)); + } + } + columnaN++; + } + lineaN++; + } + } + + /** + * Read data from experiments sumaries. + */ + public void readData() { + + int cont = 0; + int algorithmSize = this.streams.get(0).algorithm.size(); + int streamSize = this.streams.size(); + int measureSize = this.streams.get(0).algorithm.get(0).measures.size(); + + for (int i = 0; i < algorithmSize; i++) { + algoritmos.add(this.streams.get(0).algorithm.get(i).name); + datos.add(new ArrayList()); + } + for (int i = 0; i < streamSize; i++) { + List<Algorithm> alg = this.streams.get(i).algorithm; + datasets.add(this.streams.get(i).name); + for (int j = 0; j < algorithmSize; j++) { + ((ArrayList) datos.get(j)).add(alg.get(j).measures.get(cont).getValue()); + } + + } + + } + + /** + * Compute the average ranking of the algorithms. + */ + public void avgPerformance() { + mean = new double[datasets.size()][algoritmos.size()]; + + /*Compute the average performance per algorithm for each data set*/ + for (i = 0; i < datasets.size(); i++) { + for (j = 0; j < algoritmos.size(); j++) { + mean[i][j] = ((Double) ((ArrayList) datos.get(j)).get(i)); + } + } + + /*We use the pareja structure to compute and order rankings*/ + orden = new Pareja[datasets.size()][algoritmos.size()]; + for (i = 0; i < datasets.size(); i++) { + for (j = 0; j < algoritmos.size(); j++) { + orden[i][j] = new Pareja(j, mean[i][j]); + } + Arrays.sort(orden[i]); + } + + /*building of the rankings table per algorithms and data sets*/ + rank = new Pareja[datasets.size()][algoritmos.size()]; + posicion = 0; + for (i = 0; i < datasets.size(); i++) { + for (j = 0; j < algoritmos.size(); j++) { + encontrado = false; + for (k = 0; k < algoritmos.size() && !encontrado; k++) { + if (orden[i][k].indice == j) { + encontrado = true; + posicion = k + 1; + } + } + rank[i][j] = new Pareja(posicion, orden[i][posicion - 1].valor); + } + } + + /*In the case of having the same performance, the rankings are equal*/ + for (i = 0; i < datasets.size(); i++) { + visto = new boolean[algoritmos.size()]; + porVisitar = new ArrayList(); + + Arrays.fill(visto, false); + for (j = 0; j < algoritmos.size(); j++) { + porVisitar.clear(); + sum = rank[i][j].indice; + visto[j] = true; + ig = 1; + for (k = j + 1; k < algoritmos.size(); k++) { + if (rank[i][j].valor == rank[i][k].valor && !visto[k]) { + sum += rank[i][k].indice; + ig++; + porVisitar.add(new Integer(k)); + visto[k] = true; + } + } + sum /= (double) ig; + rank[i][j].indice = sum; + for (k = 0; k < porVisitar.size(); k++) { + rank[i][((Integer) porVisitar.get(k))].indice = sum; + } + } + } + avgRankingPerAlgorithm(); + } + + private void avgRankingPerAlgorithm() { + + Rj = new double[algoritmos.size()]; + for (i = 0; i < algoritmos.size(); i++) { + Rj[i] = 0; + for (j = 0; j < datasets.size(); j++) { + Rj[i] += rank[j][i].indice / ((double) datasets.size()); + } + } + /*Print the average ranking per algorithm*/ + for (i = 0; i < algoritmos.size(); i++) { + rankAlg.add(new RankPerAlgorithm((String) algoritmos.get(i), Rj[i])); + } + //Order de Algorithms with rank + Collections.sort(rankAlg, new ComparatorImpl()); + + /*Compute the Friedman statistic*/ + termino1 = (12 * (double) datasets.size()) / ((double) algoritmos.size() + * ((double) algoritmos.size() + 1)); + termino2 = (double) algoritmos.size() * ((double) algoritmos.size() + 1) + * ((double) algoritmos.size() + 1) / (4.0); + for (i = 0; i < algoritmos.size(); i++) { + sumatoria += Rj[i] * Rj[i]; + } + friedman = (sumatoria - termino2) * termino1; + + pFriedman = ChiSq(friedman, (algoritmos.size() - 1)); + + /*Compute the Iman-Davenport statistic*/ + iman = ((datasets.size() - 1) * friedman) / (datasets.size() * (algoritmos.size() - 1) - friedman); + pIman = FishF(iman, (algoritmos.size() - 1), (algoritmos.size() - 1) * (datasets.size() - 1)); + //System.out.print("P-value computed by Iman and Daveport Test: " + pIman + ".\\newline\n\n"); + + termino3 = Math.sqrt((double) algoritmos.size() * ((double) algoritmos.size() + 1) + / (6.0 * (double) datasets.size())); + //Inicialize values + inicialize(); + + } + + /** + * Return the p-value computed by Friedman test. + * + * @return pFriedman + */ + public double getFriedmanPValue() { + return pFriedman; + } + + /** + * Return the p-value Iman and Daveport test. + * + * @return pIman + */ + public double getImanPValue() { + return pIman; + } + + /** + * Return the ranking of the algorithms. + * + * @return rankAlg + */ + public ArrayList<RankPerAlgorithm> getRankAlg() { + return rankAlg; + } + + private void inicialize() { + /*Compute the unadjusted p_i value for each comparison alpha=0.10*/ + Pi = new double[(int) combinatoria(2, algoritmos.size())]; + ordenAlgoritmos = new String[(int) combinatoria(2, algoritmos.size())]; + ordenRankings = new double[(int) combinatoria(2, algoritmos.size())]; + order = new int[(int) combinatoria(2, algoritmos.size())]; + parejitas = new Relation[(int) combinatoria(2, algoritmos.size())]; + T = new ArrayList(); + T = trueHShaffer(algoritmos.size()); + Tarray = new int[T.size()]; + for (i = 0; i < T.size(); i++) { + Tarray[i] = ((Integer) T.get(i)); + } + Arrays.sort(Tarray); + SE = termino3; + vistos = new boolean[(int) combinatoria(2, algoritmos.size())]; + for (i = 0, k = 0; i < algoritmos.size(); i++) { + for (j = i + 1; j < algoritmos.size(); j++, k++) { + ordenRankings[k] = Math.abs(Rj[i] - Rj[j]); + ordenAlgoritmos[k] = (String) algoritmos.get(i) + " vs. " + (String) algoritmos.get(j); + parejitas[k] = new Relation(i, j); + } + } + + Arrays.fill(vistos, false); + for (i = 0; i < ordenRankings.length; i++) { + for (j = 0; vistos[j] == true; j++); + pos = j; + maxVal = ordenRankings[j]; + for (j = j + 1; j < ordenRankings.length; j++) { + if (vistos[j] == false && ordenRankings[j] > maxVal) { + pos = j; + maxVal = ordenRankings[j]; + } + } + vistos[pos] = true; + order[i] = pos; + } + + /*Computing the logically related hypotheses tests (Shaffer and Bergmann-Hommel)*/ + pos = 0; + tmp = Tarray.length - 1; + for (i = 0; i < order.length; i++) { + Pi[i] = 2 * CDF_Normal.normp((-1) * Math.abs((ordenRankings[order[i]]) / SE)); + + } + + } + + /** + * Return the p-values computed by the Holm test. + * + * @return algPValues + */ + public ArrayList<PValuePerTwoAlgorithm> holmTest() { + ArrayList<PValuePerTwoAlgorithm> algPValues = new ArrayList<>(); + double[] holmPValues; + holmPValues = new double[Pi.length]; + + for (i = 0; i < holmPValues.length; i++) { + holmPValues[i] = Pi[i] * (double) (holmPValues.length - i); + } + for (i = 1; i < holmPValues.length; i++) { + if (holmPValues[i] < holmPValues[i - 1]) { + holmPValues[i] = holmPValues[i - 1]; + } + } + for (i = 0; i < Pi.length; i++) { + algPValues.add(new PValuePerTwoAlgorithm(algoritmos.get(parejitas[order[i]].i).toString(), + algoritmos.get(parejitas[order[i]].j).toString(), holmPValues[i])); + } + + return algPValues; + } + + /** + * Return the p-values computed by the Shaffer test. + * + * @return algPValues + */ + public ArrayList<PValuePerTwoAlgorithm> shafferTest() { + ArrayList<PValuePerTwoAlgorithm> algPValues = new ArrayList<>(); + double[] shafferPValues; + shafferPValues = new double[Pi.length]; + pos = 0; + tmp = Tarray.length - 1; + for (i = 0; i < shafferPValues.length; i++) { + shafferPValues[i] = Pi[i] * ((double) shafferPValues.length - (double) Math.max(pos, i)); + if (i == pos) { + tmp--; + pos = (int) combinatoria(2, algoritmos.size()) - Tarray[tmp]; + } + } + for (i = 1; i < shafferPValues.length; i++) { + if (shafferPValues[i] < shafferPValues[i - 1]) { + shafferPValues[i] = shafferPValues[i - 1]; + } + if (shafferPValues[i] < shafferPValues[i - 1]) { + shafferPValues[i] = shafferPValues[i - 1]; + } + } + + for (i = 0; i < Pi.length; i++) { + algPValues.add(new PValuePerTwoAlgorithm(algoritmos.get(parejitas[order[i]].i).toString(), + algoritmos.get(parejitas[order[i]].j).toString(), shafferPValues[i])); + } + + return algPValues; + } + + /** + * Return the p-values computed by the Nemenyi test. + * + * @return algPValues + */ + public ArrayList<PValuePerTwoAlgorithm> nemenyiTest() { + ArrayList<PValuePerTwoAlgorithm> algPValues = new ArrayList<>(); + double[] nemenyiPValues; + nemenyiPValues = new double[Pi.length]; + pos = 0; + tmp = Tarray.length - 1; + for (i = 0; i < nemenyiPValues.length; i++) { + nemenyiPValues[i] = Pi[i] * (double) (nemenyiPValues.length); + } + + for (i = 0; i < Pi.length; i++) { + algPValues.add(new PValuePerTwoAlgorithm(algoritmos.get(parejitas[order[i]].i).toString(), + algoritmos.get(parejitas[order[i]].j).toString(), nemenyiPValues[i])); + } + return algPValues; + } + + private static double combinatoria(int m, int n) { + + double result = 1; + int i; + + if (n >= m) { + for (i = 1; i <= m; i++) { + result *= (double) (n - m + i) / (double) i; + } + } else { + result = 0; + } + return result; + } + + private static ArrayList obtainExhaustive(ArrayList indices) { + + ArrayList result = new ArrayList(); + int i, j, k; + String binario; + boolean[] number = new boolean[indices.size()]; + ArrayList ind1, ind2; + ArrayList set = new ArrayList(); + ArrayList res1, res2; + ArrayList temp; + ArrayList temp2; + ArrayList temp3; + + ind1 = new ArrayList(); + ind2 = new ArrayList(); + temp = new ArrayList(); + temp2 = new ArrayList(); + temp3 = new ArrayList(); + + for (i = 0; i < indices.size(); i++) { + for (j = i + 1; j < indices.size(); j++) { + set.add(new Relation(((Integer) indices.get(i)), ((Integer) indices.get(j)))); + } + } + if (set.size() > 0) { + result.add(set); + } + + for (i = 1; i < (int) (Math.pow(2, indices.size() - 1)); i++) { + Arrays.fill(number, false); + ind1.clear(); + ind2.clear(); + temp.clear(); + temp2.clear(); + temp3.clear(); + binario = Integer.toString(i, 2); + for (k = 0; k < number.length - binario.length(); k++) { + number[k] = false; + } + for (j = 0; j < binario.length(); j++, k++) { + if (binario.charAt(j) == '1') { + number[k] = true; + } + } + for (j = 0; j < number.length; j++) { + if (number[j] == true) { + ind1.add(((Integer) indices.get(j))); + } else { + ind2.add(((Integer) indices.get(j))); + } + } + res1 = obtainExhaustive(ind1); + res2 = obtainExhaustive(ind2); + for (j = 0; j < res1.size(); j++) { + result.add(new ArrayList((ArrayList) res1.get(j))); + } + for (j = 0; j < res2.size(); j++) { + result.add(new ArrayList((ArrayList) res2.get(j))); + } + for (j = 0; j < res1.size(); j++) { + temp = (ArrayList) ((ArrayList) res1.get(j)).clone(); + for (k = 0; k < res2.size(); k++) { + temp2 = (ArrayList) temp.clone(); + temp3 = (ArrayList) ((ArrayList) res2.get(k)).clone(); + if (((Relation) temp2.get(0)).i < ((Relation) temp3.get(0)).i) { + temp2.addAll((ArrayList) temp3); + result.add(new ArrayList(temp2)); + } else { + temp3.addAll((ArrayList) temp2); + result.add(new ArrayList(temp3)); + + } + } + } + } + for (i = 0; i < result.size(); i++) { + if (((ArrayList) result.get(i)).toString().equalsIgnoreCase("[]")) { + result.remove(i); + i--; + } + } + for (i = 0; i < result.size(); i++) { + for (j = i + 1; j < result.size(); j++) { + if (((ArrayList) result.get(i)).toString().equalsIgnoreCase(((ArrayList) result.get(j)).toString())) { + result.remove(j); + j--; + } + } + } + return result; + } + + private static ArrayList trueHShaffer(int k) { + + ArrayList number; + int j; + ArrayList tmp, tmp2; + int p; + + number = new ArrayList(); + tmp = new ArrayList(); + if (k <= 1) { + number.add(0); + } else { + for (j = 1; j <= k; j++) { + tmp = trueHShaffer(k - j); + tmp2 = new ArrayList(); + for (p = 0; p < tmp.size(); p++) { + tmp2.add(((Integer) (tmp.get(p))) + (int) combinatoria(2, j)); + } + number = unionVectores(number, tmp2); + } + } + + return number; + } + + private static ArrayList unionVectores(ArrayList a, ArrayList b) { + + int i; + + for (i = 0; i < b.size(); i++) { + if (a.contains(new Integer((Integer) (b.get(i)))) == false) { + a.add(b.get(i)); + } + } + + return a; + } + + private static double ChiSq(double x, int n) { + if (n == 1 & x > 1000) { + return 0; + } + if (x > 1000 | n > 1000) { + double q = ChiSq((x - n) * (x - n) / (2 * n), 1) / 2; + if (x > n) { + return q; + } + { + return 1 - q; + } + } + double p = Math.exp(-0.5 * x); + if ((n % 2) == 1) { + p = p * Math.sqrt(2 * x / Math.PI); + } + double k = n; + while (k >= 2) { + p = p * x / k; + k = k - 2; + } + double t = p; + double a = n; + while (t > 0.0000000001 * p) { + a = a + 2; + t = t * x / a; + p = p + t; + } + return 1 - p; + } + + private static double FishF(double f, int n1, int n2) { + double x = n2 / (n1 * f + n2); + if ((n1 % 2) == 0) { + return StatCom(1 - x, n2, n1 + n2 - 4, n2 - 2) * Math.pow(x, n2 / 2.0); + } + if ((n2 % 2) == 0) { + return 1 + - StatCom(x, n1, n1 + n2 - 4, n1 - 2) + * Math.pow(1 - x, n1 / 2.0); + } + double th = Math.atan(Math.sqrt(n1 * f / (1.0 * n2))); + double a = th / (Math.PI / 2.0); + double sth = Math.sin(th); + double cth = Math.cos(th); + if (n2 > 1) { + a = a + + sth * cth * StatCom(cth * cth, 2, n2 - 3, -1) / (Math.PI / 2.0); + } + if (n1 == 1) { + return 1 - a; + } + double c = 4 * StatCom(sth * sth, n2 + 1, n1 + n2 - 4, n2 - 2) * sth + * Math.pow(cth, n2) / Math.PI; + if (n2 == 1) { + return 1 - a + c / 2.0; + } + int k = 2; + while (k <= (n2 - 1) / 2.0) { + c = c * k / (k - .5); + k = k + 1; + } + return 1 - a + c; + } + + private static double StatCom(double q, int i, int j, int b) { + double zz = 1; + double z = zz; + int k = i; + while (k <= j) { + zz = zz * q * k / (k - b); + z = z + zz; + k = k + 2; + } + return z; + } + + private static class ComparatorImpl implements Comparator<RankPerAlgorithm> { + + public ComparatorImpl() { + } + + @Override + public int compare(RankPerAlgorithm r1, RankPerAlgorithm r2) { + return r1.compareTo(r2); + } + } + +} diff --git a/moa/src/main/java/moa/gui/experimentertab/tasks/ConceptDriftMainTask.java b/moa/src/main/java/moa/gui/experimentertab/tasks/ConceptDriftMainTask.java new file mode 100644 index 000000000..dd686dd61 --- /dev/null +++ b/moa/src/main/java/moa/gui/experimentertab/tasks/ConceptDriftMainTask.java @@ -0,0 +1,26 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package moa.gui.experimentertab.tasks; + +import java.util.ArrayList; +import moa.streams.clustering.ClusterEvent; + +/** + * + * @author albert + */ +public abstract class ConceptDriftMainTask extends myMainTask { + + protected ArrayList<ClusterEvent> events; + + protected void setEventsList(ArrayList<ClusterEvent> events) { + this.events = events; + } + + public ArrayList<ClusterEvent> getEventsList() { + return this.events; + } + +} diff --git a/moa/src/main/java/moa/gui/experimentertab/tasks/EvaluateConceptDrift.java b/moa/src/main/java/moa/gui/experimentertab/tasks/EvaluateConceptDrift.java new file mode 100644 index 000000000..433ae3f72 --- /dev/null +++ b/moa/src/main/java/moa/gui/experimentertab/tasks/EvaluateConceptDrift.java @@ -0,0 +1,77 @@ +/* + * EvaluatePrequential.java + * Copyright (C) 2007 University of Waikato, Hamilton, New Zealand + * @author Richard Kirkby (rkirkby@cs.waikato.ac.nz) + * @author Albert Bifet (abifet at cs dot waikato dot ac dot nz) + * + * 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 moa.gui.experimentertab.tasks; + +import moa.core.ObjectRepository; +import moa.evaluation.ClassificationPerformanceEvaluator; +import moa.evaluation.LearningCurve; +import moa.options.ClassOption; +import com.github.javacliparser.IntOption; +import moa.evaluation.LearningPerformanceEvaluator; +import moa.tasks.TaskMonitor; + +/** + * Task for evaluating a classifier on a stream by testing then training with each example in sequence. + * + * @author Richard Kirkby (rkirkby@cs.waikato.ac.nz) + * @author Albert Bifet (abifet at cs dot waikato dot ac dot nz) + * @version $Revision: 7 $ + */ +public class EvaluateConceptDrift extends ConceptDriftMainTask{ + + + @Override + public String getPurposeString() { + return "Evaluates a classifier on a stream by testing then training with each example in sequence."; + } + + private static final long serialVersionUID = 1L; + + public ClassOption evaluatorOption = new ClassOption("evaluator", 'e', + "Classification performance evaluation method.", + LearningPerformanceEvaluator.class, + "BasicConceptDriftPerformanceEvaluator"); + + public IntOption instanceLimitOption = new IntOption("instanceLimit", 'i', + "Maximum number of instances to test/train on (-1 = no limit).", + 1000, -1, Integer.MAX_VALUE); + + public IntOption timeLimitOption = new IntOption("timeLimit", 't', + "Maximum number of seconds to test/train for (-1 = no limit).", -1, + -1, Integer.MAX_VALUE); + + public IntOption sampleFrequencyOption = new IntOption("sampleFrequency", + 'f', + "How many instances between samples of the learning performance.", + 10, 0, Integer.MAX_VALUE); + + + @Override + public Class<?> getTaskResultType() { + return LearningCurve.class; + } + + + @Override + protected Object doMainTask(TaskMonitor monitor, ObjectRepository repository) { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } +} \ No newline at end of file diff --git a/moa/src/main/java/moa/gui/experimentertab/tasks/EvaluateInterleavedChunks.java b/moa/src/main/java/moa/gui/experimentertab/tasks/EvaluateInterleavedChunks.java new file mode 100644 index 000000000..26ab9af8f --- /dev/null +++ b/moa/src/main/java/moa/gui/experimentertab/tasks/EvaluateInterleavedChunks.java @@ -0,0 +1,113 @@ +/* + * EvaluateInterleavedChunks.java + * Copyright (C) 2010 Poznan University of Technology, Poznan, Poland + * @author Dariusz Brzezinski (dariusz.brzezinski@cs.put.poznan.pl) + * + * 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 moa.gui.experimentertab.tasks; + +import moa.core.ObjectRepository; +import moa.tasks.*; + +import moa.evaluation.ClassificationPerformanceEvaluator; +import moa.evaluation.LearningCurve; +import moa.options.ClassOption; +import com.github.javacliparser.IntOption; +import moa.evaluation.LearningPerformanceEvaluator; + + +public class EvaluateInterleavedChunks extends myMainTask { + + @Override + public String getPurposeString() { + return "Evaluates a classifier on a stream by testing then training with chunks of data in sequence."; + } + + private static final long serialVersionUID = 1L; + + /** + * Allows to select the classifier performance evaluation method. + */ + public ClassOption evaluatorOption = new ClassOption("evaluator", 'e', + "Learning performance evaluation method.", + LearningPerformanceEvaluator.class, + "BasicClassificationPerformanceEvaluator"); + + /** + * Allows to define the maximum number of instances to test/train on (-1 = no limit). + */ + public IntOption instanceLimitOption = new IntOption("instanceLimit", 'i', + "Maximum number of instances to test/train on (-1 = no limit).", + 100000000, -1, Integer.MAX_VALUE); + + /** + * Allow to define the training/testing chunk size. + */ + public IntOption chunkSizeOption = new IntOption("chunkSize", 'c', + "Number of instances in a data chunk.", + 1000, 1, Integer.MAX_VALUE); + + /** + * Allows to define the maximum number of seconds to test/train for (-1 = no limit). + */ + public IntOption timeLimitOption = new IntOption("timeLimit", 't', + "Maximum number of seconds to test/train for (-1 = no limit).", -1, + -1, Integer.MAX_VALUE); + + /** + * Defines how often classifier parameters will be calculated. + */ + public IntOption sampleFrequencyOption = new IntOption("sampleFrequency", + 'f', + "How many instances between samples of the learning performance.", + 100000, 0, Integer.MAX_VALUE); + + /** + * Allows to define the memory limit for the created model. + */ + public IntOption maxMemoryOption = new IntOption("maxMemory", 'b', + "Maximum size of model (in bytes). -1 = no limit.", -1, -1, + Integer.MAX_VALUE); + + /** + * Allows to define the frequency of memory checks. + */ + public IntOption memCheckFrequencyOption = new IntOption( + "memCheckFrequency", 'q', + "How many instances between memory bound checks.", 100000, 0, + Integer.MAX_VALUE); + + /** + * Allows to define the output file name and location. + */ +// public FileOption dumpFileOption = new FileOption("dumpFile", 'd', +// "File to append intermediate csv reslts to.", null, "csv", true); + + /** + * Defines the task's result type. + */ + public Class<?> getTaskResultType() { + return LearningCurve.class; + } + + @Override + protected Object doMainTask(TaskMonitor monitor, ObjectRepository repository) { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + + + +} diff --git a/moa/src/main/java/moa/gui/experimentertab/tasks/EvaluateInterleavedTestThenTrain.java b/moa/src/main/java/moa/gui/experimentertab/tasks/EvaluateInterleavedTestThenTrain.java new file mode 100644 index 000000000..7abff4e11 --- /dev/null +++ b/moa/src/main/java/moa/gui/experimentertab/tasks/EvaluateInterleavedTestThenTrain.java @@ -0,0 +1,86 @@ +/* + * EvaluateInterleavedTestThenTrain.java + * Copyright (C) 2007 University of Waikato, Hamilton, New Zealand + * @author Richard Kirkby (rkirkby@cs.waikato.ac.nz) + * + * 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 moa.gui.experimentertab.tasks; + +import moa.core.ObjectRepository; +import moa.tasks.*; + +import moa.evaluation.LearningCurve; +import moa.options.ClassOption; +import com.github.javacliparser.IntOption; +import moa.evaluation.LearningPerformanceEvaluator; + +/** + * Task for evaluating a classifier on a stream by testing then training with + * each example in sequence. + * + * @author Richard Kirkby (rkirkby@cs.waikato.ac.nz) + * @version $Revision: 7 $ + */ +public class EvaluateInterleavedTestThenTrain extends myMainTask { + + @Override + public String getPurposeString() { + return "Evaluates a classifier on a stream by testing then training with each example in sequence."; + } + + private static final long serialVersionUID = 1L; + + public IntOption randomSeedOption = new IntOption( + "instanceRandomSeed", 'r', + "Seed for random generation of instances.", 1); + + public ClassOption evaluatorOption = new ClassOption("evaluator", 'e', + "Classification performance evaluation method.", + LearningPerformanceEvaluator.class, + "BasicClassificationPerformanceEvaluator"); + + public IntOption instanceLimitOption = new IntOption("instanceLimit", 'i', + "Maximum number of instances to test/train on (-1 = no limit).", + 100000000, -1, Integer.MAX_VALUE); + + public IntOption timeLimitOption = new IntOption("timeLimit", 't', + "Maximum number of seconds to test/train for (-1 = no limit).", -1, + -1, Integer.MAX_VALUE); + + public IntOption sampleFrequencyOption = new IntOption("sampleFrequency", + 'f', + "How many instances between samples of the learning performance.", + 100000, 0, Integer.MAX_VALUE); + + public IntOption memCheckFrequencyOption = new IntOption( + "memCheckFrequency", 'q', + "How many instances between memory bound checks.", 100000, 0, + Integer.MAX_VALUE); + +// public FileOption dumpFileOption = new FileOption("dumpFile", 'd', +// "File to append intermediate csv reslts to.", null,"", true); + + @Override + public Class<?> getTaskResultType() { + return LearningCurve.class; + } + + + @Override + protected Object doMainTask(TaskMonitor monitor, ObjectRepository repository) { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } +} diff --git a/moa/src/main/java/moa/gui/experimentertab/tasks/EvaluatePeriodicHeldOutTest.java b/moa/src/main/java/moa/gui/experimentertab/tasks/EvaluatePeriodicHeldOutTest.java new file mode 100644 index 000000000..e78af5759 --- /dev/null +++ b/moa/src/main/java/moa/gui/experimentertab/tasks/EvaluatePeriodicHeldOutTest.java @@ -0,0 +1,85 @@ +/* + * EvaluatePeriodicHeldOutTest.java + * Copyright (C) 2007 University of Waikato, Hamilton, New Zealand + * @author Richard Kirkby (rkirkby@cs.waikato.ac.nz) + * @author Ammar Shaker (shaker@mathematik.uni-marburg.de) + * + * 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 moa.gui.experimentertab.tasks; + +import moa.core.ObjectRepository; +import moa.evaluation.ClassificationPerformanceEvaluator; +import moa.evaluation.LearningCurve; +import moa.tasks.*; +import moa.options.ClassOption; +import com.github.javacliparser.FlagOption; +import com.github.javacliparser.IntOption; +import moa.evaluation.LearningPerformanceEvaluator; + +/** + * Task for evaluating a classifier on a stream by periodically testing on a + * heldout set. + * + * @author Richard Kirkby (rkirkby@cs.waikato.ac.nz) + * @version $Revision: 7 $ + */ +public class EvaluatePeriodicHeldOutTest extends myMainTask { + + @Override + public String getPurposeString() { + return "Evaluates a classifier on a stream by periodically testing on a heldout set."; + } + + private static final long serialVersionUID = 1L; + + public ClassOption evaluatorOption = new ClassOption("evaluator", 'e', + "Classification performance evaluation method.", + LearningPerformanceEvaluator.class, + "BasicClassificationPerformanceEvaluator"); + + public IntOption testSizeOption = new IntOption("testSize", 'n', + "Number of testing examples.", 1000000, 0, Integer.MAX_VALUE); + + public IntOption trainSizeOption = new IntOption("trainSize", 'i', + "Number of training examples, <1 = unlimited.", 0, 0, + Integer.MAX_VALUE); + + public IntOption trainTimeOption = new IntOption("trainTime", 't', + "Number of training seconds.", 10 * 60 * 60, 0, Integer.MAX_VALUE); + + public IntOption sampleFrequencyOption = new IntOption( + "sampleFrequency", + 'f', + "Number of training examples between samples of learning performance.", + 100000, 0, Integer.MAX_VALUE); + +// public FileOption dumpFileOption = new FileOption("dumpFile", 'd', +// "File to append intermediate csv results to.", null, "csv", true); + + public FlagOption cacheTestOption = new FlagOption("cacheTest", 'c', + "Cache test instances in memory."); + + @Override + public Class<?> getTaskResultType() { + return LearningCurve.class; + } + + @Override + protected Object doMainTask(TaskMonitor monitor, ObjectRepository repository) { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + +} diff --git a/moa/src/main/java/moa/gui/experimentertab/tasks/EvaluatePrequential.java b/moa/src/main/java/moa/gui/experimentertab/tasks/EvaluatePrequential.java new file mode 100644 index 000000000..4591bd557 --- /dev/null +++ b/moa/src/main/java/moa/gui/experimentertab/tasks/EvaluatePrequential.java @@ -0,0 +1,73 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package moa.gui.experimentertab.tasks; + + +import com.github.javacliparser.FileOption; +import moa.core.ObjectRepository; +import moa.evaluation.ClassificationPerformanceEvaluator; +import moa.options.ClassOption; +import com.github.javacliparser.FloatOption; +import com.github.javacliparser.IntOption; +import moa.evaluation.LearningPerformanceEvaluator; + + +import moa.tasks.TaskMonitor; + +/** + * + * @author Alberto + */ +public class EvaluatePrequential extends myMainTask{ + @Override + public String getPurposeString() { + return "Evaluates a classifier on a stream by testing then training with each example in sequence."; + } + + private static final long serialVersionUID = 1L; + + public ClassOption evaluatorOption = new ClassOption("evaluator", 'e', + "Classification performance evaluation method.", + LearningPerformanceEvaluator.class, + "WindowClassificationPerformanceEvaluator"); + + public IntOption instanceLimitOption = new IntOption("instanceLimit", 'i', + "Maximum number of instances to test/train on (-1 = no limit).", + 100000000, -1, Integer.MAX_VALUE); + + public IntOption timeLimitOption = new IntOption("timeLimit", 't', + "Maximum number of seconds to test/train for (-1 = no limit).", -1, + -1, Integer.MAX_VALUE); + + public IntOption sampleFrequencyOption = new IntOption("sampleFrequency", + 'f', + "How many instances between samples of the learning performance.", + 100000, 0, Integer.MAX_VALUE); + + public IntOption memCheckFrequencyOption = new IntOption( + "memCheckFrequency", 'q', + "How many instances between memory bound checks.", 100000, 0, + Integer.MAX_VALUE); + + //New for prequential method DEPRECATED + public IntOption widthOption = new IntOption("width", + 'w', "Size of Window", 1000); + + public FloatOption alphaOption = new FloatOption("alpha", + 'a', "Fading factor or exponential smoothing factor", .01); + + @Override + protected Object doMainTask(TaskMonitor monitor, ObjectRepository repository) { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + + @Override + public Class<?> getTaskResultType() { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + + +} diff --git a/moa/src/main/java/moa/gui/experimentertab/tasks/EvaluatePrequentialCV.java b/moa/src/main/java/moa/gui/experimentertab/tasks/EvaluatePrequentialCV.java new file mode 100644 index 000000000..b929c4f7e --- /dev/null +++ b/moa/src/main/java/moa/gui/experimentertab/tasks/EvaluatePrequentialCV.java @@ -0,0 +1,114 @@ +/* + * EvaluatePrequential.java + * Copyright (C) 2007 University of Waikato, Hamilton, New Zealand + * @author Richard Kirkby (rkirkby@cs.waikato.ac.nz) + * @author Albert Bifet (abifet at cs dot waikato dot ac dot nz) + * + * 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 moa.gui.experimentertab.tasks; + +import moa.tasks.*; +import com.github.javacliparser.FileOption; +import com.github.javacliparser.FloatOption; +import com.github.javacliparser.IntOption; +import com.github.javacliparser.MultiChoiceOption; +import com.yahoo.labs.samoa.instances.Instance; +import moa.classifiers.Classifier; +import moa.core.*; +import moa.evaluation.*; +import moa.learners.Learner; +import moa.options.ClassOption; +import moa.streams.ExampleStream; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.PrintStream; +import java.util.Arrays; +import java.util.LinkedList; +import java.util.List; +import java.util.Random; + +/** + * Task for prequential cross-validation evaluation of a classifier on a stream by testing then training with each + * example in sequence and doing cross-validation at the same time. + * + * <p>Albert Bifet, Gianmarco De Francisci Morales, Jesse Read, Geoff Holmes, Bernhard Pfahringer: Efficient Online + * Evaluation of Big Data Stream Classifiers. KDD 2015: 59-68</p> + * + * @author Richard Kirkby (rkirkby@cs.waikato.ac.nz) + * @author Albert Bifet (abifet at cs dot waikato dot ac dot nz) + * @version $Revision: 7 $ + */ +public class EvaluatePrequentialCV extends myMainTask { + + @Override + public String getPurposeString() { + return "Evaluates a classifier on a stream by doing prequential evaluation (testing then training with each" + + " example in sequence) and doing cross-validation."; + } + + private static final long serialVersionUID = 1L; + + public ClassOption evaluatorOption = new ClassOption("evaluator", 'e', + "Classification performance evaluation method.", + LearningPerformanceEvaluator.class, + "WindowClassificationPerformanceEvaluator"); + + public IntOption instanceLimitOption = new IntOption("instanceLimit", 'i', + "Maximum number of instances to test/train on (-1 = no limit).", + 100000000, -1, Integer.MAX_VALUE); + + public IntOption timeLimitOption = new IntOption("timeLimit", 't', + "Maximum number of seconds to test/train for (-1 = no limit).", -1, + -1, Integer.MAX_VALUE); + + public IntOption sampleFrequencyOption = new IntOption("sampleFrequency", + 'f', + "How many instances between samples of the learning performance.", + 100000, 0, Integer.MAX_VALUE); + + public IntOption memCheckFrequencyOption = new IntOption( + "memCheckFrequency", 'q', + "How many instances between memory bound checks.", 100000, 0, + Integer.MAX_VALUE); + + public IntOption ensembleSizeOption = new IntOption("ensembleSize", 'w', + "The number of distributed models.", 10, 1, Integer.MAX_VALUE); + + public MultiChoiceOption validationMethodologyOption = new MultiChoiceOption( + "validationMethodology", 'a', "Validation methodology to use.", new String[]{ + "Cross-Validation", "Bootstrap-Validation", "Split-Validation"}, + new String[]{"k-fold distributed Cross Validation", + "k-fold distributed Bootstrap Validation", + "k-fold distributed Split Validation" + }, 0); + + public IntOption randomSeedOption = new IntOption("randomSeed", 'r', + "Seed for random behaviour of the task.", 1); + + + @Override + public Class<?> getTaskResultType() { + throw new UnsupportedOperationException("Not supported yet."); + } + + + @Override + protected Object doMainTask(TaskMonitor monitor, ObjectRepository repository) { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + +} diff --git a/moa/src/main/java/moa/gui/experimentertab/tasks/myMainTask.java b/moa/src/main/java/moa/gui/experimentertab/tasks/myMainTask.java new file mode 100644 index 000000000..7a4e8eae9 --- /dev/null +++ b/moa/src/main/java/moa/gui/experimentertab/tasks/myMainTask.java @@ -0,0 +1,70 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package moa.gui.experimentertab.tasks; + + +import moa.core.ObjectRepository; +import moa.tasks.AbstractTask; +import moa.tasks.TaskMonitor; + +/** + * + * @author Alberto + */ +public abstract class myMainTask extends AbstractTask { + + private static final long serialVersionUID = 1L; + + /** The number of instances between monitor updates. */ + protected static final int INSTANCES_BETWEEN_MONITOR_UPDATES = 10; + + /** File option to save the final result of the task to. */ +// public FileOption outputFileOption = new FileOption("taskResultFile", 'O', +// "File to save the final result of the task to.", null, "moa", true); + + @Override + protected Object doTaskImpl(TaskMonitor monitor, ObjectRepository repository) { + Object result = doMainTask(monitor, repository); +// if (monitor.taskShouldAbort()) { +// return null; +// } +// File outputFile = this.outputFileOption.getFile(); +// if (outputFile != null) { +// if (result instanceof Serializable) { +// monitor.setCurrentActivity("Saving result of task " +// + getTaskName() + " to file " + outputFile + "...", +// -1.0); +// try { +// SerializeUtils.writeToFile(outputFile, +// (Serializable) result); +// } catch (IOException ioe) { +// throw new RuntimeException("Failed writing result of task " +// + getTaskName() + " to file " + outputFile, ioe); +// } +// } else { +// throw new RuntimeException("Result of task " + getTaskName() +// + " is not serializable, so cannot be written to file " +// + outputFile); +// } +// } + return result; + } + + /** + * This method performs this task. + * <code>AbstractTask</code> implements <code>doTask</code>, + * that uses <code>doTaskImpl</code>. + * <code>myMainTask</code> implements <code>doTaskImpl</code> using + * <code>doMainTask</code> so its extensions only need to implement + * <code>doMainTask</code>. + * + * @param monitor the TaskMonitor to use + * @param repository the ObjectRepository to use + * @return an object with the result of this task + */ + protected abstract Object doMainTask(TaskMonitor monitor, + ObjectRepository repository); +}