summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrej Shadura <andrewsh@debian.org>2019-03-09 22:30:30 +0000
committerAndrej Shadura <andrewsh@debian.org>2019-03-09 22:30:30 +0000
commit21d13de881e43d4ab86369af4c5fc744b342b3f9 (patch)
tree6588cebc4e1dbad3ac5b5d52bc21255925c2c93e
parent6160961591bfbfeab2ea5f7c249f58c78e893347 (diff)
Import Upstream version 0.4.0
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/DummyAlgorithm.java13
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/clustering/ClusteringAlgorithm.java4
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/clustering/OPTICSTypeAlgorithm.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/clustering/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/clustering/trivial/ByLabelClustering.java11
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/clustering/trivial/ByLabelHierarchicalClustering.java11
-rw-r--r--src/de/lmu/ifi/dbs/elki/algorithm/outlier/trivial/ByLabelOutlier.java11
-rw-r--r--src/de/lmu/ifi/dbs/elki/application/GeneratorXMLSpec.java638
-rw-r--r--src/de/lmu/ifi/dbs/elki/application/internal/DocumentParameters.java93
-rw-r--r--src/de/lmu/ifi/dbs/elki/data/ClassLabel.java25
-rw-r--r--src/de/lmu/ifi/dbs/elki/data/ExternalID.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/data/HierarchicalClassLabel.java36
-rw-r--r--src/de/lmu/ifi/dbs/elki/data/LabelList.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/data/SimpleClassLabel.java34
-rw-r--r--src/de/lmu/ifi/dbs/elki/data/model/ClusterModel.java1
-rw-r--r--src/de/lmu/ifi/dbs/elki/data/model/Model.java3
-rw-r--r--src/de/lmu/ifi/dbs/elki/data/synthetic/bymodel/GeneratorMain.java125
-rw-r--r--src/de/lmu/ifi/dbs/elki/datasource/DatabaseConnection.java1
-rw-r--r--src/de/lmu/ifi/dbs/elki/datasource/ExternalIDJoinDatabaseConnection.java8
-rw-r--r--src/de/lmu/ifi/dbs/elki/datasource/FileBasedDatabaseConnection.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/datasource/GeneratorXMLDatabaseConnection.java636
-rw-r--r--src/de/lmu/ifi/dbs/elki/datasource/LabelJoinDatabaseConnection.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/datasource/filter/AttributeWiseErfNormalization.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/datasource/filter/AttributeWiseMinMaxNormalization.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/datasource/filter/AttributeWiseVarianceNormalization.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/datasource/filter/ClassLabelFilter.java22
-rw-r--r--src/de/lmu/ifi/dbs/elki/datasource/filter/DoubleVectorProjectionFilter.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/datasource/filter/DoubleVectorRandomProjectionFilter.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/datasource/filter/ExternalIDFilter.java3
-rw-r--r--src/de/lmu/ifi/dbs/elki/datasource/filter/FilterByLabelFilter.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/datasource/filter/FixedDBIDsFilter.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/datasource/filter/InverseDocumentFrequencyNormalization.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/datasource/filter/Normalization.java1
-rw-r--r--src/de/lmu/ifi/dbs/elki/datasource/filter/SortByLabelFilter.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/datasource/filter/SplitNumberVectorFilter.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/datasource/parser/ArffParser.java686
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/distancefunction/AbstractDatabaseDistanceFunction.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/distancefunction/AbstractIndexBasedDistanceFunction.java3
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/distancefunction/AbstractVectorDoubleDistanceFunction.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/distancefunction/MinKDistance.java5
-rw-r--r--src/de/lmu/ifi/dbs/elki/distance/distancefunction/SharedNearestNeighborJaccardDistanceFunction.java4
-rw-r--r--src/de/lmu/ifi/dbs/elki/gui/configurator/ClassListParameterConfigurator.java8
-rw-r--r--src/de/lmu/ifi/dbs/elki/gui/configurator/ClassParameterConfigurator.java8
-rw-r--r--src/de/lmu/ifi/dbs/elki/gui/configurator/ConfiguratorPanel.java4
-rw-r--r--src/de/lmu/ifi/dbs/elki/gui/configurator/EnumParameterConfigurator.java104
-rw-r--r--src/de/lmu/ifi/dbs/elki/gui/configurator/FileParameterConfigurator.java7
-rw-r--r--src/de/lmu/ifi/dbs/elki/gui/configurator/FlagParameterConfigurator.java7
-rw-r--r--src/de/lmu/ifi/dbs/elki/gui/configurator/TextParameterConfigurator.java7
-rw-r--r--src/de/lmu/ifi/dbs/elki/gui/multistep/MultiStepGUI.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/gui/multistep/panels/SavedSettingsTabPanel.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/gui/util/ParameterTable.java18
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/IndexFactory.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/preprocessed/AbstractPreprocessorIndex.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/preprocessed/LocalProjectionIndex.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/preprocessed/preference/DiSHPreferenceVectorIndex.java17
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/DistanceEntry.java4
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/IndexTree.java1
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/IndexTreePath.java1
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/TreeIndexFactory.java3
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/TreeIndexPathComponent.java3
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkapp/MkAppEntry.java6
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkcop/ConvexHull.java1
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkcop/MkCoPEntry.java25
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkcop/MkCoPTree.java1
-rw-r--r--src/de/lmu/ifi/dbs/elki/math/MathUtil.java5
-rw-r--r--src/de/lmu/ifi/dbs/elki/persistent/ByteArrayUtil.java12
-rw-r--r--src/de/lmu/ifi/dbs/elki/properties/ELKI.properties18
-rw-r--r--src/de/lmu/ifi/dbs/elki/result/DiscardResultHandler.java3
-rw-r--r--src/de/lmu/ifi/dbs/elki/result/ResultHierarchy.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/result/optics/ClusterOrderResult.java4
-rw-r--r--src/de/lmu/ifi/dbs/elki/result/outlier/OutlierResult.java1
-rw-r--r--src/de/lmu/ifi/dbs/elki/result/textwriter/TextWriter.java11
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/Util.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/KNNList.java14
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/iterator/UnmodifiableListIterator.java4
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/AbstractNumberConstraint.java7
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/EqualStringConstraint.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/IntervalConstraint.java249
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/ListSizeConstraint.java3
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/ParameterFlagGlobalConstraint.java4
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/StringLengthConstraint.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameterization/EmptyParameterization.java3
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameterization/ListParameterization.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameterization/SerializedParameterization.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameterization/UnParameterization.java5
-rw-r--r--src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/EnumParameter.java167
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/VisualizationTask.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/VisualizerContext.java4
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/batikutil/JSVGUpdateSynchronizer.java4
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/gui/ResultWindow.java15
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/gui/SelectionTableWindow.java11
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/gui/SimpleSVGViewer.java4
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/gui/detail/DetailView.java4
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/gui/overview/OverviewPlot.java52
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/opticsplot/OPTICSColorStatic.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/projector/HistogramFactory.java3
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/projector/HistogramProjector.java25
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/projector/OPTICSProjectorFactory.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/projector/ProjectorFactory.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/projector/ScatterPlotFactory.java5
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/projector/ScatterPlotProjector.java3
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/savedialog/SaveOptionsPanel.java6
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/visualizers/AbstractVisualization.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/visualizers/optics/AbstractOPTICSVisualization.java12
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/visualizers/optics/OPTICSClusterVisualization.java5
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/visualizers/optics/OPTICSPlotCutVisualization.java11
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/visualizers/optics/OPTICSPlotSelectionVisualization.java10
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/visualizers/optics/OPTICSPlotVisualizer.java5
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/visualizers/optics/OPTICSSteepAreaVisualization.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/visualizers/thumbs/ThumbnailVisualization.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/visualizers/vis2d/AbstractTooltipVisualization.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/visualizers/vis2d/AxisVisualization.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/visualizers/vis2d/ClusterOrderVisualization.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/visualizers/vis2d/ClusteringVisualization.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/visualizers/vis2d/MoveObjectsToolVisualization.java8
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/visualizers/vis2d/SelectionConvexHullVisualization.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/visualizers/vis2d/SelectionCubeVisualization.java6
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/visualizers/vis2d/SelectionDotVisualization.java8
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/visualizers/vis2d/SelectionToolCubeVisualization.java14
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/visualizers/vis2d/SelectionToolDotVisualization.java14
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/visualizers/vis2d/ToolBox2DVisualization.java8
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/visualizers/vis2d/TreeMBRVisualization.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/visualizers/vis2d/TreeSphereVisualization.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/ClusterEvaluationVisFactory.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/CurveVisFactory.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/HistogramVisFactory.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/KeyVisFactory.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/PixmapVisualizer.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/SettingsVisFactory.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/SimilarityMatrixVisualizer.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/workflow/EvaluationStep.java3
131 files changed, 2140 insertions, 1309 deletions
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/DummyAlgorithm.java b/src/de/lmu/ifi/dbs/elki/algorithm/DummyAlgorithm.java
index d864f18c..e403c623 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/DummyAlgorithm.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/DummyAlgorithm.java
@@ -41,10 +41,15 @@ import de.lmu.ifi.dbs.elki.utilities.documentation.Title;
/**
* Dummy Algorithm, which just iterates over all points once, doing a 10NN query
* each. Useful in testing e.g. index structures and as template for custom
- * algorithms.
+ * algorithms. If you are looking for an algorithm that does <em>nothing</em>,
+ * you must use {@link de.lmu.ifi.dbs.elki.algorithm.NullAlgorithm
+ * NullAlgorithm} instead. While this algorithm doesn't produce a result, it
+ * still performs rather expensive operations.
*
* @author Erich Schubert
* @param <O> Vector type
+ *
+ * @apiviz.uses KNNQuery
*/
@Title("Dummy Algorithm")
@Description("The algorithm executes a euclidena 10NN query on all data points, and can be used in unit testing")
@@ -70,13 +75,15 @@ public class DummyAlgorithm<O extends NumberVector<?, ?>> extends AbstractAlgori
* @return Null result
*/
public Result run(Database database, Relation<O> relation) {
+ // Get a distance and knn query for the Euclidean distance
+ // Hardcoded, only use this if you only allow the eucliden distance
DistanceQuery<O, DoubleDistance> distQuery = database.getDistanceQuery(relation, EuclideanDistanceFunction.STATIC);
KNNQuery<O, DoubleDistance> knnQuery = database.getKNNQuery(distQuery, 10);
for(DBID id : relation.iterDBIDs()) {
- // Get the actual object from the database (but discard)
+ // Get the actual object from the database (but discard the result)
relation.get(id);
- // run a 10NN query for each point (but discard)
+ // run a 10NN query for each point (but discard the result)
knnQuery.getKNNForDBID(id, 10);
}
return null;
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/ClusteringAlgorithm.java b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/ClusteringAlgorithm.java
index 2f05e44b..e28dbff3 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/ClusteringAlgorithm.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/ClusteringAlgorithm.java
@@ -40,8 +40,8 @@ import de.lmu.ifi.dbs.elki.database.Database;
*
* @author Arthur Zimek
*
- * @apiviz.uses Clustering
- * @apiviz.uses Model
+ * @apiviz.has Clustering
+ * @apiviz.has Model
*
* @param <C> Clustering type
*/
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/OPTICSTypeAlgorithm.java b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/OPTICSTypeAlgorithm.java
index e8b113d7..c233963d 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/OPTICSTypeAlgorithm.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/OPTICSTypeAlgorithm.java
@@ -33,7 +33,7 @@ import de.lmu.ifi.dbs.elki.result.optics.ClusterOrderResult;
*
* @author Erich Schubert
*
- * @apiviz.uses ClusterOrderResult
+ * @apiviz.has ClusterOrderResult
*
* @param <D> Distance type
*/
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/package-info.java b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/package-info.java
index 9314b725..660a7a4f 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/package-info.java
@@ -7,6 +7,8 @@
* More relaxed clustering algorithms are allowed to provide a result that is a fuzzy clustering, does not
* partition the database complete or is in any other sense a relaxed clustering result.
*
+ * @apiviz.exclude de.lmu.ifi.dbs.elki.algorithm.clustering.OPTICSXi.SteepAreaResult
+ *
* @see de.lmu.ifi.dbs.elki.algorithm
*/
/*
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/trivial/ByLabelClustering.java b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/trivial/ByLabelClustering.java
index 87c2c482..02350db3 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/trivial/ByLabelClustering.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/trivial/ByLabelClustering.java
@@ -34,6 +34,7 @@ import de.lmu.ifi.dbs.elki.data.Cluster;
import de.lmu.ifi.dbs.elki.data.Clustering;
import de.lmu.ifi.dbs.elki.data.model.ClusterModel;
import de.lmu.ifi.dbs.elki.data.model.Model;
+import de.lmu.ifi.dbs.elki.data.type.NoSupportedDataTypeException;
import de.lmu.ifi.dbs.elki.data.type.TypeInformation;
import de.lmu.ifi.dbs.elki.data.type.TypeUtil;
import de.lmu.ifi.dbs.elki.database.Database;
@@ -122,12 +123,14 @@ public class ByLabelClustering extends AbstractAlgorithm<Clustering<Model>> impl
@Override
public Clustering<Model> run(Database database) {
// Prefer a true class label
- Relation<ClassLabel> relation = database.getRelation(TypeUtil.CLASSLABEL);
- if(relation != null) {
+ try {
+ Relation<ClassLabel> relation = database.getRelation(TypeUtil.CLASSLABEL);
return run(relation);
}
- // Otherwise, try any labellike.
- return run(database.getRelation(getInputTypeRestriction()[0]));
+ catch(NoSupportedDataTypeException e) {
+ // Otherwise, try any labellike.
+ return run(database.getRelation(getInputTypeRestriction()[0]));
+ }
}
/**
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/trivial/ByLabelHierarchicalClustering.java b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/trivial/ByLabelHierarchicalClustering.java
index 3bda8174..5b8041d7 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/clustering/trivial/ByLabelHierarchicalClustering.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/clustering/trivial/ByLabelHierarchicalClustering.java
@@ -34,6 +34,7 @@ import de.lmu.ifi.dbs.elki.data.Cluster;
import de.lmu.ifi.dbs.elki.data.Clustering;
import de.lmu.ifi.dbs.elki.data.model.ClusterModel;
import de.lmu.ifi.dbs.elki.data.model.Model;
+import de.lmu.ifi.dbs.elki.data.type.NoSupportedDataTypeException;
import de.lmu.ifi.dbs.elki.data.type.TypeInformation;
import de.lmu.ifi.dbs.elki.data.type.TypeUtil;
import de.lmu.ifi.dbs.elki.database.Database;
@@ -80,12 +81,14 @@ public class ByLabelHierarchicalClustering extends AbstractAlgorithm<Clustering<
@Override
public Clustering<Model> run(Database database) {
// Prefer a true class label
- Relation<ClassLabel> relation = database.getRelation(TypeUtil.CLASSLABEL);
- if(relation != null) {
+ try {
+ Relation<ClassLabel> relation = database.getRelation(TypeUtil.CLASSLABEL);
return run(relation);
}
- // Otherwise, try any labellike.
- return run(database.getRelation(getInputTypeRestriction()[0]));
+ catch(NoSupportedDataTypeException e) {
+ // Otherwise, try any labellike.
+ return run(database.getRelation(getInputTypeRestriction()[0]));
+ }
}
/**
diff --git a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/trivial/ByLabelOutlier.java b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/trivial/ByLabelOutlier.java
index 3c9b318f..62f083fb 100644
--- a/src/de/lmu/ifi/dbs/elki/algorithm/outlier/trivial/ByLabelOutlier.java
+++ b/src/de/lmu/ifi/dbs/elki/algorithm/outlier/trivial/ByLabelOutlier.java
@@ -28,6 +28,7 @@ import java.util.regex.Pattern;
import de.lmu.ifi.dbs.elki.algorithm.AbstractAlgorithm;
import de.lmu.ifi.dbs.elki.algorithm.outlier.OutlierAlgorithm;
import de.lmu.ifi.dbs.elki.data.ClassLabel;
+import de.lmu.ifi.dbs.elki.data.type.NoSupportedDataTypeException;
import de.lmu.ifi.dbs.elki.data.type.TypeInformation;
import de.lmu.ifi.dbs.elki.data.type.TypeUtil;
import de.lmu.ifi.dbs.elki.database.Database;
@@ -93,12 +94,14 @@ public class ByLabelOutlier extends AbstractAlgorithm<OutlierResult> implements
@Override
public OutlierResult run(Database database) {
// Prefer a true class label
- Relation<ClassLabel> relation = database.getRelation(TypeUtil.CLASSLABEL);
- if(relation != null) {
+ try {
+ Relation<ClassLabel> relation = database.getRelation(TypeUtil.CLASSLABEL);
return run(relation);
}
- // Otherwise, try any labellike.
- return run(database.getRelation(getInputTypeRestriction()[0]));
+ catch(NoSupportedDataTypeException e) {
+ // Otherwise, try any labellike.
+ return run(database.getRelation(getInputTypeRestriction()[0]));
+ }
}
/**
diff --git a/src/de/lmu/ifi/dbs/elki/application/GeneratorXMLSpec.java b/src/de/lmu/ifi/dbs/elki/application/GeneratorXMLSpec.java
index c09c74eb..373960a5 100644
--- a/src/de/lmu/ifi/dbs/elki/application/GeneratorXMLSpec.java
+++ b/src/de/lmu/ifi/dbs/elki/application/GeneratorXMLSpec.java
@@ -24,559 +24,63 @@ package de.lmu.ifi.dbs.elki.application;
*/
import java.io.File;
-import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
-import java.io.InputStream;
import java.io.OutputStreamWriter;
-import java.net.URL;
-import java.util.LinkedList;
-import java.util.Random;
-import java.util.regex.Pattern;
+import java.util.List;
-import javax.xml.XMLConstants;
-import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.parsers.ParserConfigurationException;
-import javax.xml.validation.Schema;
-import javax.xml.validation.SchemaFactory;
-
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.w3c.dom.Node;
-import org.xml.sax.SAXException;
-
-import de.lmu.ifi.dbs.elki.data.synthetic.bymodel.GeneratorMain;
+import de.lmu.ifi.dbs.elki.data.synthetic.bymodel.GeneratorInterface;
+import de.lmu.ifi.dbs.elki.data.synthetic.bymodel.GeneratorInterfaceDynamic;
import de.lmu.ifi.dbs.elki.data.synthetic.bymodel.GeneratorSingleCluster;
-import de.lmu.ifi.dbs.elki.data.synthetic.bymodel.GeneratorStatic;
import de.lmu.ifi.dbs.elki.data.synthetic.bymodel.distribution.Distribution;
-import de.lmu.ifi.dbs.elki.data.synthetic.bymodel.distribution.GammaDistribution;
-import de.lmu.ifi.dbs.elki.data.synthetic.bymodel.distribution.NormalDistribution;
-import de.lmu.ifi.dbs.elki.data.synthetic.bymodel.distribution.UniformDistribution;
+import de.lmu.ifi.dbs.elki.datasource.GeneratorXMLDatabaseConnection;
+import de.lmu.ifi.dbs.elki.datasource.bundle.MultipleObjectsBundle;
import de.lmu.ifi.dbs.elki.logging.Logging;
import de.lmu.ifi.dbs.elki.math.linearalgebra.Vector;
+import de.lmu.ifi.dbs.elki.utilities.FormatUtil;
import de.lmu.ifi.dbs.elki.utilities.exceptions.UnableToComplyException;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.OptionID;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.DoubleParameter;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.FileParameter;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.IntParameter;
-import de.lmu.ifi.dbs.elki.utilities.xml.XMLNodeIterator;
/**
* Generate a data set based on a specified model (using an XML specification)
*
* @author Erich Schubert
*
- * @apiviz.composedOf GeneratorMain
- * @apiviz.has GeneratorSingleCluster oneway - - creates
- * @apiviz.has GeneratorStatic oneway - - creates
+ * @apiviz.composedOf GeneratorXMLDatabaseConnection
*/
public class GeneratorXMLSpec extends AbstractApplication {
- // TODO: move XML parsing into data package.
-
/**
* The logger for this class.
*/
private static final Logging logger = Logging.getLogger(GeneratorXMLSpec.class);
/**
- * A pattern defining whitespace.
- */
- public static final Pattern WHITESPACE_PATTERN = Pattern.compile("\\s+");
-
- /**
- * Parameter to give the configuration file
- */
- public static final OptionID CONFIGFILE_ID = OptionID.getOrCreateOptionID("bymodel.spec", "The generator specification file.");
-
- /**
- * Parameter to give the configuration file
- */
- public static final OptionID RANDOMSEED_ID = OptionID.getOrCreateOptionID("bymodel.randomseed", "The random generator seed.");
-
- /**
- * Parameter to give the configuration file
- */
- public static final OptionID SIZE_SCALE_ID = OptionID.getOrCreateOptionID("bymodel.sizescale", "Factor for scaling the specified cluster sizes.");
-
- /**
- * File name of the generators XML Schema file.
+ * Line separator for output
*/
- private static final String GENERATOR_SCHEMA_FILE = GeneratorXMLSpec.class.getPackage().getName().replace('.', '/') + '/' + "GeneratorByModel.xsd";
+ public final static String LINE_SEPARATOR = System.getProperty("line.separator");
/**
- * The configuration file.
- */
- File specfile;
-
- /**
- * Parameter for scaling the cluster sizes.
- */
- double sizescale = 1.0;
-
- /**
- * The actual generator class
- */
- public GeneratorMain gen = new GeneratorMain();
-
- /**
- * Random generator used for initializing cluster generators.
- */
- private Random clusterRandom = null;
-
- /**
- * Set testAgainstModel flag
+ * Output file.
*/
- private boolean testAgainstModel = true;
+ private File outputFile;
/**
- * Output file.
+ * The original data source.
*/
- private File outputFile;
+ private GeneratorXMLDatabaseConnection generator;
/**
* Constructor.
*
* @param verbose Verbose flag
* @param output Output file
- * @param specfile Specification file
- * @param sizescale Size scaling
- * @param clusterRandom Random number generator
+ * @param generator GeneratorXMLDatabaseConnection
*/
- public GeneratorXMLSpec(boolean verbose, File output, File specfile, double sizescale, Random clusterRandom) {
+ public GeneratorXMLSpec(boolean verbose, File output, GeneratorXMLDatabaseConnection generator) {
super(verbose);
this.outputFile = output;
- this.specfile = specfile;
- this.sizescale = sizescale;
- this.clusterRandom = clusterRandom;
- if(this.clusterRandom == null) {
- this.clusterRandom = new Random();
- }
- }
-
- /**
- * Load the XML configuration file.
- *
- * @throws UnableToComplyException
- */
- private void loadXMLSpecification(File specfile) throws UnableToComplyException {
- try {
- InputStream in = new FileInputStream(specfile);
- DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
- dbf.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
- URL url = ClassLoader.getSystemResource(GENERATOR_SCHEMA_FILE);
- if(url != null) {
- try {
- Schema schema = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI).newSchema(url);
- dbf.setSchema(schema);
- dbf.setIgnoringElementContentWhitespace(true);
- }
- catch(Exception e) {
- logger.warning("Could not set up XML Schema validation for speciciation file.");
- }
- }
- else {
- logger.warning("Could not set up XML Schema validation for speciciation file.");
- }
- Document doc = dbf.newDocumentBuilder().parse(in);
- Node root = doc.getDocumentElement();
- if(root.getNodeName() == "dataset") {
- processElementDataset(root);
- }
- else {
- throw new UnableToComplyException("Experiment specification has incorrect document element: " + root.getNodeName());
- }
- }
- catch(FileNotFoundException e) {
- throw new UnableToComplyException("Can't open specification file.", e);
- }
- catch(SAXException e) {
- throw new UnableToComplyException("Error parsing specification file.", e);
- }
- catch(IOException e) {
- throw new UnableToComplyException("IO Exception loading specification file.", e);
- }
- catch(ParserConfigurationException e) {
- throw new UnableToComplyException("Parser Configuration Error", e);
- }
- }
-
- /**
- * Process a 'dataset' Element in the XML stream.
- *
- * @param cur Current document nod
- * @throws UnableToComplyException
- */
- private void processElementDataset(Node cur) throws UnableToComplyException {
- // *** get parameters
- String seedstr = ((Element) cur).getAttribute("random-seed");
- if(seedstr != null && seedstr != "") {
- clusterRandom = new Random((int) (Integer.valueOf(seedstr) * sizescale));
- }
- String testmod = ((Element) cur).getAttribute("test-model");
- if(testmod != null && testmod != "") {
- testAgainstModel = (Integer.valueOf(testmod) != 0);
- }
- // TODO: check for unknown attributes.
- for(Node child : new XMLNodeIterator(cur.getFirstChild())) {
- if(child.getNodeName() == "cluster") {
- processElementCluster(child);
- }
- else if(child.getNodeName() == "static") {
- processElementStatic(child);
- }
- else if(child.getNodeType() == Node.ELEMENT_NODE) {
- logger.warning("Unknown element in XML specification file: " + child.getNodeName());
- }
- }
- }
-
- /**
- * Process a 'cluster' Element in the XML stream.
- *
- * @param cur Current document nod
- * @throws UnableToComplyException
- */
- private void processElementCluster(Node cur) throws UnableToComplyException {
- int size = -1;
- double overweight = 1.0;
-
- String sizestr = ((Element) cur).getAttribute("size");
- if(sizestr != null && sizestr != "") {
- size = (int) (Integer.valueOf(sizestr) * sizescale);
- }
-
- String name = ((Element) cur).getAttribute("name");
-
- String dcostr = ((Element) cur).getAttribute("density-correction");
- if(dcostr != null && dcostr != "") {
- overweight = Double.valueOf(dcostr);
- }
-
- if(size < 0) {
- throw new UnableToComplyException("No valid cluster size given in specification file.");
- }
- if(name == null || name == "") {
- throw new UnableToComplyException("No cluster name given in specification file.");
- }
-
- // *** add new cluster object
- Random newRand = new Random(clusterRandom.nextLong());
- GeneratorSingleCluster cluster = new GeneratorSingleCluster(name, size, overweight, newRand);
-
- // TODO: check for unknown attributes.
- for(Node child : new XMLNodeIterator(cur.getFirstChild())) {
- if(child.getNodeName() == "uniform") {
- processElementUniform(cluster, child);
- }
- else if(child.getNodeName() == "normal") {
- processElementNormal(cluster, child);
- }
- else if(child.getNodeName() == "gamma") {
- processElementGamma(cluster, child);
- }
- else if(child.getNodeName() == "rotate") {
- processElementRotate(cluster, child);
- }
- else if(child.getNodeName() == "translate") {
- processElementTranslate(cluster, child);
- }
- else if(child.getNodeName() == "clip") {
- processElementClipping(cluster, child);
- }
- else if(child.getNodeType() == Node.ELEMENT_NODE) {
- logger.warning("Unknown element in XML specification file: " + child.getNodeName());
- }
- }
-
- gen.addCluster(cluster);
- }
-
- /**
- * Process a 'uniform' Element in the XML stream.
- *
- * @param cluster
- * @param cur Current document nod
- * @throws UnableToComplyException
- */
- private void processElementUniform(GeneratorSingleCluster cluster, Node cur) throws UnableToComplyException {
- double min = 0.0;
- double max = 1.0;
-
- String minstr = ((Element) cur).getAttribute("min");
- if(minstr != null && minstr != "") {
- min = Double.valueOf(minstr);
- }
- String maxstr = ((Element) cur).getAttribute("max");
- if(maxstr != null && maxstr != "") {
- max = Double.valueOf(maxstr);
- }
-
- // *** new uniform generator
- Random random = cluster.getNewRandomGenerator();
- Distribution generator = new UniformDistribution(min, max, random);
- cluster.addGenerator(generator);
-
- // TODO: check for unknown attributes.
- for(Node child : new XMLNodeIterator(cur.getFirstChild())) {
- if(child.getNodeType() == Node.ELEMENT_NODE) {
- logger.warning("Unknown element in XML specification file: " + child.getNodeName());
- }
- }
- }
-
- /**
- * Process a 'normal' Element in the XML stream.
- *
- * @param cluster
- * @param cur Current document nod
- * @throws UnableToComplyException
- */
- private void processElementNormal(GeneratorSingleCluster cluster, Node cur) throws UnableToComplyException {
- double mean = 0.0;
- double stddev = 1.0;
- String meanstr = ((Element) cur).getAttribute("mean");
- if(meanstr != null && meanstr != "") {
- mean = Double.valueOf(meanstr);
- }
- String stddevstr = ((Element) cur).getAttribute("stddev");
- if(stddevstr != null && stddevstr != "") {
- stddev = Double.valueOf(stddevstr);
- }
-
- // *** New normal distribution generator
- Random random = cluster.getNewRandomGenerator();
- Distribution generator = new NormalDistribution(mean, stddev, random);
- cluster.addGenerator(generator);
-
- // TODO: check for unknown attributes.
- for(Node child : new XMLNodeIterator(cur.getFirstChild())) {
- if(child.getNodeType() == Node.ELEMENT_NODE) {
- logger.warning("Unknown element in XML specification file: " + child.getNodeName());
- }
- }
- }
-
- /**
- * Process a 'gamma' Element in the XML stream.
- *
- * @param cluster
- * @param cur Current document nod
- * @throws UnableToComplyException
- */
- private void processElementGamma(GeneratorSingleCluster cluster, Node cur) throws UnableToComplyException {
- double k = 1.0;
- double theta = 1.0;
- String kstr = ((Element) cur).getAttribute("k");
- if(kstr != null && kstr != "") {
- k = Double.valueOf(kstr);
- }
- String thetastr = ((Element) cur).getAttribute("theta");
- if(thetastr != null && thetastr != "") {
- theta = Double.valueOf(thetastr);
- }
-
- // *** New normal distribution generator
- Random random = cluster.getNewRandomGenerator();
- Distribution generator = new GammaDistribution(k, theta, random);
- cluster.addGenerator(generator);
-
- // TODO: check for unknown attributes.
- for(Node child : new XMLNodeIterator(cur.getFirstChild())) {
- if(child.getNodeType() == Node.ELEMENT_NODE) {
- logger.warning("Unknown element in XML specification file: " + child.getNodeName());
- }
- }
- }
-
- /**
- * Process a 'rotate' Element in the XML stream.
- *
- * @param cluster
- * @param cur Current document nod
- * @throws UnableToComplyException
- */
- private void processElementRotate(GeneratorSingleCluster cluster, Node cur) throws UnableToComplyException {
- int axis1 = 0;
- int axis2 = 0;
- double angle = 0.0;
-
- String a1str = ((Element) cur).getAttribute("axis1");
- if(a1str != null && a1str != "") {
- axis1 = Integer.valueOf(a1str);
- }
- String a2str = ((Element) cur).getAttribute("axis2");
- if(a2str != null && a2str != "") {
- axis2 = Integer.valueOf(a2str);
- }
- String anstr = ((Element) cur).getAttribute("angle");
- if(anstr != null && anstr != "") {
- angle = Double.valueOf(anstr);
- }
- if(axis1 <= 0 || axis1 > cluster.getDim()) {
- throw new UnableToComplyException("Invalid axis1 number given in specification file.");
- }
- if(axis1 <= 0 || axis1 > cluster.getDim()) {
- throw new UnableToComplyException("Invalid axis2 number given in specification file.");
- }
- if(axis1 == axis2) {
- throw new UnableToComplyException("Invalid axis numbers given in specification file.");
- }
-
- // Add rotation to cluster.
- cluster.addRotation(axis1 - 1, axis2 - 1, Math.toRadians(angle));
-
- // TODO: check for unknown attributes.
- for(Node child : new XMLNodeIterator(cur.getFirstChild())) {
- if(child.getNodeType() == Node.ELEMENT_NODE) {
- logger.warning("Unknown element in XML specification file: " + child.getNodeName());
- }
- }
- }
-
- /**
- * Process a 'translate' Element in the XML stream.
- *
- * @param cluster
- * @param cur Current document nod
- * @throws UnableToComplyException
- */
- private void processElementTranslate(GeneratorSingleCluster cluster, Node cur) throws UnableToComplyException {
- Vector offset = null;
- String vstr = ((Element) cur).getAttribute("vector");
- if(vstr != null && vstr != "") {
- offset = parseVector(vstr);
- }
- if(offset == null) {
- throw new UnableToComplyException("No translation vector given.");
- }
-
- // *** add new translation
- cluster.addTranslation(offset);
-
- // TODO: check for unknown attributes.
- for(Node child : new XMLNodeIterator(cur.getFirstChild())) {
- if(child.getNodeType() == Node.ELEMENT_NODE) {
- logger.warning("Unknown element in XML specification file: " + child.getNodeName());
- }
- }
- }
-
- /**
- * Process a 'clipping' Element in the XML stream.
- *
- * @param cluster
- * @param cur Current document nod
- * @throws UnableToComplyException
- */
- private void processElementClipping(GeneratorSingleCluster cluster, Node cur) throws UnableToComplyException {
- Vector cmin = null;
- Vector cmax = null;
-
- String minstr = ((Element) cur).getAttribute("min");
- if(minstr != null && minstr != "") {
- cmin = parseVector(minstr);
- }
- String maxstr = ((Element) cur).getAttribute("max");
- if(maxstr != null && maxstr != "") {
- cmax = parseVector(maxstr);
- }
- if(cmin == null || cmax == null) {
- throw new UnableToComplyException("No or incomplete clipping vectors given.");
- }
-
- // *** set clipping
- cluster.setClipping(cmin, cmax);
-
- // TODO: check for unknown attributes.
- for(Node child : new XMLNodeIterator(cur.getFirstChild())) {
- if(child.getNodeType() == Node.ELEMENT_NODE) {
- logger.warning("Unknown element in XML specification file: " + child.getNodeName());
- }
- }
- }
-
- /**
- * Process a 'static' cluster Element in the XML stream.
- *
- * @param cur Current document nod
- * @throws UnableToComplyException
- */
- private void processElementStatic(Node cur) throws UnableToComplyException {
- String name = ((Element) cur).getAttribute("name");
- if(name == null) {
- throw new UnableToComplyException("No cluster name given in specification file.");
- }
-
- LinkedList<Vector> points = new LinkedList<Vector>();
- // TODO: check for unknown attributes.
- for(Node child : new XMLNodeIterator(cur.getFirstChild())) {
- if(child.getNodeName() == "point") {
- processElementPoint(points, child);
- }
- else if(child.getNodeType() == Node.ELEMENT_NODE) {
- logger.warning("Unknown element in XML specification file: " + child.getNodeName());
- }
- }
- // *** add new cluster object
- GeneratorStatic cluster = new GeneratorStatic(name, points);
-
- gen.addCluster(cluster);
- if(logger.isVerbose()) {
- logger.verbose("Loaded cluster " + cluster.name + " from specification.");
- }
- }
-
- /**
- * Parse a 'point' element (point vector for a static cluster)
- *
- * @param points current list of points (to append to)
- * @param cur Current document nod
- * @throws UnableToComplyException
- */
- private void processElementPoint(LinkedList<Vector> points, Node cur) throws UnableToComplyException {
- Vector point = null;
- String vstr = ((Element) cur).getAttribute("vector");
- if(vstr != null && vstr != "") {
- point = parseVector(vstr);
- }
- if(point == null) {
- throw new UnableToComplyException("No translation vector given.");
- }
-
- // *** add new point
- points.add(point);
-
- // TODO: check for unknown attributes.
- for(Node child : new XMLNodeIterator(cur.getFirstChild())) {
- if(child.getNodeType() == Node.ELEMENT_NODE) {
- logger.warning("Unknown element in XML specification file: " + child.getNodeName());
- }
- }
- }
-
- /**
- * Parse a string into a vector.
- *
- * TODO: move this into utility package?
- *
- * @param s String to parse
- * @return Vector
- * @throws UnableToComplyException
- */
- private Vector parseVector(String s) throws UnableToComplyException {
- String[] entries = WHITESPACE_PATTERN.split(s);
- double[] d = new double[entries.length];
- for(int i = 0; i < entries.length; i++) {
- try {
- d[i] = Double.valueOf(entries[i]);
- }
- catch(NumberFormatException e) {
- throw new UnableToComplyException("Could not parse vector.");
- }
- }
- return new Vector(d);
+ this.generator = generator;
}
/**
@@ -584,15 +88,7 @@ public class GeneratorXMLSpec extends AbstractApplication {
*/
@Override
public void run() throws UnableToComplyException {
- if(logger.isVerbose()) {
- logger.verbose("Loading specification ...");
- }
- loadXMLSpecification(specfile);
- if(logger.isVerbose()) {
- logger.verbose("Generating clusters ...");
- }
- gen.setTestAgainstModel(testAgainstModel);
- gen.generate();
+ MultipleObjectsBundle data = generator.loadData();
if(logger.isVerbose()) {
logger.verbose("Writing output ...");
}
@@ -604,7 +100,7 @@ public class GeneratorXMLSpec extends AbstractApplication {
}
OutputStreamWriter outStream = new FileWriter(outputFile, true);
- gen.writeClusters(outStream);
+ writeClusters(outStream, data);
outStream.flush();
outStream.close();
@@ -621,6 +117,68 @@ public class GeneratorXMLSpec extends AbstractApplication {
}
/**
+ * Write the resulting clusters to an output stream.
+ *
+ * @param outStream output stream
+ * @param data Generated data
+ * @throws IOException thrown on write errors
+ */
+ public void writeClusters(OutputStreamWriter outStream, MultipleObjectsBundle data) throws IOException {
+ List<GeneratorInterface> clusters = generator.gen.getGenerators();
+ // compute global discard values
+ int totalsize = 0;
+ int totaldisc = 0;
+ assert (clusters.size() > 0);
+ for(GeneratorInterface curclus : clusters) {
+ totalsize = totalsize + curclus.getSize();
+ if(curclus instanceof GeneratorSingleCluster) {
+ totaldisc = totaldisc + ((GeneratorSingleCluster) curclus).getDiscarded();
+ }
+ }
+ double globdens = (double) (totalsize + totaldisc) / totalsize;
+ outStream.write("########################################################" + LINE_SEPARATOR);
+ outStream.write("## Number of clusters: " + clusters.size() + LINE_SEPARATOR);
+ for(GeneratorInterface curclus : clusters) {
+ outStream.write("########################################################" + LINE_SEPARATOR);
+ outStream.write("## Cluster: " + curclus.getName() + LINE_SEPARATOR);
+ outStream.write("########################################################" + LINE_SEPARATOR);
+ outStream.write("## Size: " + curclus.getSize() + LINE_SEPARATOR);
+ if(curclus instanceof GeneratorSingleCluster) {
+ GeneratorSingleCluster cursclus = (GeneratorSingleCluster) curclus;
+ Vector cmin = cursclus.getClipmin();
+ Vector cmax = cursclus.getClipmax();
+ if(cmin != null && cmax != null) {
+ outStream.write("## Clipping: " + cmin.toString() + " - " + cmax.toString() + LINE_SEPARATOR);
+ }
+ outStream.write("## Density correction factor: " + cursclus.getDensityCorrection() + LINE_SEPARATOR);
+ outStream.write("## Generators:" + LINE_SEPARATOR);
+ for(Distribution gen : cursclus.getAxes()) {
+ outStream.write("## " + gen.toString() + LINE_SEPARATOR);
+ }
+ if(cursclus.getTrans() != null && cursclus.getTrans().getTransformation() != null) {
+ outStream.write("## Affine transformation matrix:" + LINE_SEPARATOR);
+ outStream.write(FormatUtil.format(cursclus.getTrans().getTransformation(), "## ") + LINE_SEPARATOR);
+ }
+ }
+ if(curclus instanceof GeneratorInterfaceDynamic) {
+ GeneratorSingleCluster cursclus = (GeneratorSingleCluster) curclus;
+ outStream.write("## Discards: " + cursclus.getDiscarded() + " Retries left: " + cursclus.getRetries() + LINE_SEPARATOR);
+ double corf = /* cursclus.overweight */(double) (cursclus.getSize() + cursclus.getDiscarded()) / cursclus.getSize() / globdens;
+ outStream.write("## Density correction factor estimation: " + corf + LINE_SEPARATOR);
+
+ }
+ outStream.write("########################################################" + LINE_SEPARATOR);
+ for(Vector p : curclus.getPoints()) {
+ for(int i = 0; i < p.getRowDimensionality(); i++) {
+ outStream.write(p.get(i) + " ");
+ }
+ outStream.write(curclus.getName());
+ outStream.write(LINE_SEPARATOR);
+ }
+ }
+ }
+
+ /**
* Parameterization class.
*
* @author Erich Schubert
@@ -629,50 +187,26 @@ public class GeneratorXMLSpec extends AbstractApplication {
*/
public static class Parameterizer extends AbstractApplication.Parameterizer {
/**
- * The configuration file.
- */
- File specfile = null;
-
- /**
- * Parameter for scaling the cluster sizes.
- */
- double sizescale = 1.0;
-
- /**
- * Random generator used for initializing cluster generators.
+ * Output file.
*/
- private Random clusterRandom = null;
+ private File outputFile = null;
/**
- * Output file.
+ * Data generator
*/
- private File outputFile = null;
+ private GeneratorXMLDatabaseConnection generator = null;
@Override
protected void makeOptions(Parameterization config) {
super.makeOptions(config);
// Output file
outputFile = getParameterOutputFile(config, "the file to write the generated data set into, if the file already exists, the generated points will be appended to this file.");
- // Specification file
- final FileParameter cfgparam = new FileParameter(CONFIGFILE_ID, FileParameter.FileType.INPUT_FILE);
- if(config.grab(cfgparam)) {
- specfile = cfgparam.getValue();
- }
- // Cluster size scaling
- final DoubleParameter scalepar = new DoubleParameter(SIZE_SCALE_ID, 1.0);
- if(config.grab(scalepar)) {
- sizescale = scalepar.getValue();
- }
- // Random generator
- final IntParameter seedpar = new IntParameter(RANDOMSEED_ID, true);
- if(config.grab(seedpar)) {
- clusterRandom = new Random(seedpar.getValue());
- }
+ generator = config.tryInstantiate(GeneratorXMLDatabaseConnection.class);
}
@Override
protected GeneratorXMLSpec makeInstance() {
- return new GeneratorXMLSpec(verbose, outputFile, specfile, sizescale, clusterRandom);
+ return new GeneratorXMLSpec(verbose, outputFile, generator);
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/application/internal/DocumentParameters.java b/src/de/lmu/ifi/dbs/elki/application/internal/DocumentParameters.java
index b5bb516e..05af4b4d 100644
--- a/src/de/lmu/ifi/dbs/elki/application/internal/DocumentParameters.java
+++ b/src/de/lmu/ifi/dbs/elki/application/internal/DocumentParameters.java
@@ -196,39 +196,40 @@ public class DocumentParameters {
public void run() {
// Try a V3 style parameterizer first.
Parameterizer par = ClassGenericsUtil.getParameterizer(cls);
- if (par != null) {
+ if(par != null) {
par.configure(track);
- return;
}
- try {
- Object instance = ClassGenericsUtil.tryInstantiate(Object.class, cls, track);
- for(Pair<Object, Parameter<?, ?>> pair : track.getAllParameters()) {
- if(pair.first == null) {
- pair.first = instance;
+ else {
+ try {
+ ClassGenericsUtil.tryInstantiate(Object.class, cls, track);
+ }
+ catch(java.lang.NoSuchMethodException e) {
+ logger.warning("Could not instantiate class " + cls.getName() + " - no appropriate constructor or parameterizer found.");
+ }
+ catch(java.lang.reflect.InvocationTargetException e) {
+ if(e.getCause() instanceof RuntimeException) {
+ throw (RuntimeException) e.getCause();
+ }
+ if(e.getCause() instanceof Error) {
+ throw (Error) e.getCause();
}
- options.add(pair);
+ throw new RuntimeException(e.getCause());
}
- }
- catch(java.lang.NoSuchMethodException e) {
- logger.warning("Could not instantiate class "+cls.getName()+" - no appropriate constructor or parameterizer found.");
- }
- catch(java.lang.reflect.InvocationTargetException e) {
- if(e.getCause() instanceof RuntimeException) {
- throw (RuntimeException) e.getCause();
+ catch(RuntimeException e) {
+ throw e;
}
- if(e.getCause() instanceof Error) {
- throw (Error) e.getCause();
+ catch(Exception e) {
+ throw new RuntimeException(e);
+ }
+ catch(java.lang.Error e) {
+ throw new RuntimeException(e);
}
- throw new RuntimeException(e.getCause());
- }
- catch(RuntimeException e) {
- throw e;
- }
- catch(Exception e) {
- throw new RuntimeException(e);
}
- catch(java.lang.Error e) {
- throw new RuntimeException(e);
+ for(Pair<Object, Parameter<?, ?>> pair : track.getAllParameters()) {
+ if(pair.first == null) {
+ pair.first = cls;
+ }
+ options.add(pair);
}
}
}, null);
@@ -296,7 +297,7 @@ public class DocumentParameters {
boolean inlist = false;
if(byo != null) {
for(Pair<Parameter<?, ?>, Class<?>> pair : byo) {
- if(pair.second == c) {
+ if(pair.second.equals(c)) {
inlist = true;
break;
}
@@ -306,9 +307,6 @@ public class DocumentParameters {
byopt.add(o.getOptionID(), new Pair<Parameter<?, ?>, Class<?>>(o, c));
}
}
- if(!byopt.contains(o.getOptionID(), new Pair<Parameter<?, ?>, Class<?>>(o, c))) {
- byopt.add(o.getOptionID(), new Pair<Parameter<?, ?>, Class<?>>(o, c));
- }
}
es.shutdownNow();
logger.debug("byClass: " + byclass.size() + " byOpt: " + byopt.size());
@@ -435,7 +433,7 @@ public class DocumentParameters {
elemdd.appendChild(elemp);
// class restriction?
if(opt instanceof ClassParameter<?>) {
- appendClassRestriction(htmldoc, (ClassParameter<?>) opt, elemdd);
+ appendClassRestriction(htmldoc, ((ClassParameter<?>) opt).getRestrictionClass(), elemdd);
}
// default value? completions?
appendDefaultValueIfSet(htmldoc, opt, elemdd);
@@ -509,7 +507,7 @@ public class DocumentParameters {
Collections.sort(opts, new SortByOption());
for(OptionID oid : opts) {
- Parameter<?, ?> firstopt = byopt.get(oid).get(0).getFirst();
+ final Parameter<?, ?> firstopt = byopt.get(oid).get(0).getFirst();
// DT = definition term
Element optdt = htmldoc.createElement(HTMLUtil.HTML_DT_TAG);
// Anchor for references
@@ -533,8 +531,17 @@ public class DocumentParameters {
optdd.appendChild(elemp);
}
// class restriction?
+ Class<?> superclass = null;
if(firstopt instanceof ClassParameter<?>) {
- appendClassRestriction(htmldoc, (ClassParameter<?>) firstopt, optdd);
+ // Find superclass heuristically
+ superclass = ((ClassParameter<?>) firstopt).getRestrictionClass();
+ for (Pair<Parameter<?, ?>, Class<?>> clinst : byopt.get(oid)) {
+ ClassParameter<?> cls = (ClassParameter<?>) clinst.getFirst();
+ if (!cls.getRestrictionClass().equals(superclass) && cls.getRestrictionClass().isAssignableFrom(superclass)) {
+ superclass = cls.getRestrictionClass();
+ }
+ }
+ appendClassRestriction(htmldoc, superclass, optdd);
}
// default value?
appendDefaultValueIfSet(htmldoc, firstopt, optdd);
@@ -566,8 +573,8 @@ public class DocumentParameters {
ClassParameter<?> cls = (ClassParameter<?>) clinst.getFirst();
if(cls.getRestrictionClass() != null) {
// TODO: if it is null, it could still be different!
- if(!cls.getRestrictionClass().equals(((ClassParameter<?>) firstopt).getRestrictionClass())) {
- appendClassRestriction(htmldoc, cls, classli);
+ if(!cls.getRestrictionClass().equals(superclass)) {
+ appendClassRestriction(htmldoc, cls.getRestrictionClass(), classli);
}
}
else {
@@ -599,22 +606,22 @@ public class DocumentParameters {
p.appendChild(defa);
}
- private static void appendClassRestriction(Document htmldoc, ClassParameter<?> opt, Element elemdd) {
- if(opt.getRestrictionClass() == null) {
- logger.warning("No restriction class for Parameter " + opt.getName());
+ private static void appendClassRestriction(Document htmldoc, Class<?> restriction, Element elemdd) {
+ if(restriction == null) {
+ logger.warning("No restriction class!");
return;
}
Element p = htmldoc.createElement(HTMLUtil.HTML_P_TAG);
p.appendChild(htmldoc.createTextNode(HEADER_CLASS_RESTRICTION));
- if(opt.getRestrictionClass().isInterface()) {
+ if(restriction.isInterface()) {
p.appendChild(htmldoc.createTextNode(HEADER_CLASS_RESTRICTION_IMPLEMENTING));
}
else {
p.appendChild(htmldoc.createTextNode(HEADER_CLASS_RESTRICTION_EXTENDING));
}
Element defa = htmldoc.createElement(HTMLUtil.HTML_A_TAG);
- defa.setAttribute(HTMLUtil.HTML_HREF_ATTRIBUTE, linkForClassName(opt.getRestrictionClass().getName()));
- defa.setTextContent(opt.getRestrictionClass().getName());
+ defa.setAttribute(HTMLUtil.HTML_HREF_ATTRIBUTE, linkForClassName(restriction.getName()));
+ defa.setTextContent(restriction.getName());
p.appendChild(defa);
elemdd.appendChild(p);
}
@@ -645,8 +652,8 @@ public class DocumentParameters {
elemdd.appendChild(ul);
}
// Report when not in properties file.
- if (Properties.ELKI_PROPERTIES.getProperty(opt.getRestrictionClass().getName()).length == 0) {
- logger.warning(opt.getRestrictionClass().getName()+" not in properties. No autocompletion available in release GUI.");
+ if(Properties.ELKI_PROPERTIES.getProperty(opt.getRestrictionClass().getName()).length == 0) {
+ logger.warning(opt.getRestrictionClass().getName() + " not in properties. No autocompletion available in release GUI.");
}
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/data/ClassLabel.java b/src/de/lmu/ifi/dbs/elki/data/ClassLabel.java
index 7cef5e1e..3ec5874c 100644
--- a/src/de/lmu/ifi/dbs/elki/data/ClassLabel.java
+++ b/src/de/lmu/ifi/dbs/elki/data/ClassLabel.java
@@ -31,23 +31,16 @@ import de.lmu.ifi.dbs.elki.utilities.InspectionUtilFrequentlyScanned;
*
* @author Arthur Zimek
*/
-public abstract class ClassLabel implements Comparable<ClassLabel>, InspectionUtilFrequentlyScanned {
+public abstract class ClassLabel implements Comparable<ClassLabel> {
/**
* ClassLabels need an empty constructor for dynamic access. Subsequently, the
* init method must be called.
*/
protected ClassLabel() {
- // requires subsequent call of init
+ // Initialized from factory
}
/**
- * Initialization of a ClassLabel for the given label.
- *
- * @param label the label to create a ClassLabel
- */
- public abstract void init(String label);
-
- /**
* Any ClassLabel should ensure a natural ordering that is consistent with
* equals. Thus, if <code>this.compareTo(o)==0</code>, then
* <code>this.equals(o)</code> should be <code>true</code>.
@@ -83,4 +76,16 @@ public abstract class ClassLabel implements Comparable<ClassLabel>, InspectionUt
public int hashCode() {
return toString().hashCode();
}
-}
+
+ /**
+ * Class label factory
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.has ClassLabel - - «creates»
+ * @apiviz.stereotype factory
+ */
+ public static abstract class Factory<L extends ClassLabel> implements InspectionUtilFrequentlyScanned {
+ public abstract L makeFromString(String lbl);
+ }
+} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/data/ExternalID.java b/src/de/lmu/ifi/dbs/elki/data/ExternalID.java
index 4ba44062..228b97d0 100644
--- a/src/de/lmu/ifi/dbs/elki/data/ExternalID.java
+++ b/src/de/lmu/ifi/dbs/elki/data/ExternalID.java
@@ -28,6 +28,8 @@ package de.lmu.ifi.dbs.elki.data;
* External ID objects.
*
* @author Erich Schubert
+ *
+ * @apiviz.composedOf String
*/
public final class ExternalID {
/**
diff --git a/src/de/lmu/ifi/dbs/elki/data/HierarchicalClassLabel.java b/src/de/lmu/ifi/dbs/elki/data/HierarchicalClassLabel.java
index 694324c7..499a40be 100644
--- a/src/de/lmu/ifi/dbs/elki/data/HierarchicalClassLabel.java
+++ b/src/de/lmu/ifi/dbs/elki/data/HierarchicalClassLabel.java
@@ -30,6 +30,8 @@ import java.util.regex.Pattern;
* of classes.
*
* @author Arthur Zimek
+ *
+ * @apiviz.composedOf Comparable
*/
public class HierarchicalClassLabel extends ClassLabel {
/**
@@ -56,17 +58,9 @@ public class HierarchicalClassLabel extends ClassLabel {
/**
* Holds the names on the different levels.
*/
- // TODO: fix generics warnings.
private Comparable<?>[] levelwiseNames;
/**
- * @see ClassLabel#ClassLabel()
- */
- public HierarchicalClassLabel() {
- super();
- }
-
- /**
* Constructs a hierarchical class label from the given name, using the given
* Pattern to match separators of different levels in the given name, and
* setting the given separator-String to separate different levels in String
@@ -78,7 +72,8 @@ public class HierarchicalClassLabel extends ClassLabel {
* @param separator a separator String to separate different levels in the
* String-representation of this HierarchicalClassLabel
*/
- public void init(String name, Pattern regex, String separator) {
+ public HierarchicalClassLabel(String name, Pattern regex, String separator) {
+ super();
this.separatorPattern = regex;
this.separatorString = separator;
String[] levelwiseStrings = separatorPattern.split(name);
@@ -101,11 +96,9 @@ public class HierarchicalClassLabel extends ClassLabel {
* separated by '.'.
*
* @param label a String describing a hierarchical class label
- * @see #init(String, java.util.regex.Pattern, String)
*/
- @Override
- public void init(String label) {
- init(label, DEFAULT_SEPARATOR, DEFAULT_SEPARATOR_STRING);
+ public HierarchicalClassLabel(String label) {
+ this(label, DEFAULT_SEPARATOR, DEFAULT_SEPARATOR_STRING);
}
/**
@@ -190,4 +183,19 @@ public class HierarchicalClassLabel extends ClassLabel {
}
return name.toString();
}
-}
+
+ /**
+ * Factory class
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.has HierarchicalClassLabel - - «creates»
+ * @apiviz.stereotype factory
+ */
+ public static class Factory extends ClassLabel.Factory<HierarchicalClassLabel> {
+ @Override
+ public HierarchicalClassLabel makeFromString(String lbl) {
+ return new HierarchicalClassLabel(lbl);
+ }
+ }
+} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/data/LabelList.java b/src/de/lmu/ifi/dbs/elki/data/LabelList.java
index d710bf37..9dc73c0f 100644
--- a/src/de/lmu/ifi/dbs/elki/data/LabelList.java
+++ b/src/de/lmu/ifi/dbs/elki/data/LabelList.java
@@ -31,6 +31,8 @@ import de.lmu.ifi.dbs.elki.utilities.FormatUtil;
* A list of string labels
*
* @author Erich Schubert
+ *
+ * @apiviz.composedOf String
*/
public class LabelList extends ArrayList<String> {
/**
diff --git a/src/de/lmu/ifi/dbs/elki/data/SimpleClassLabel.java b/src/de/lmu/ifi/dbs/elki/data/SimpleClassLabel.java
index da51aeaa..b71dd9bb 100644
--- a/src/de/lmu/ifi/dbs/elki/data/SimpleClassLabel.java
+++ b/src/de/lmu/ifi/dbs/elki/data/SimpleClassLabel.java
@@ -28,27 +28,22 @@ package de.lmu.ifi.dbs.elki.data;
* A simple class label casting a String as it is as label.
*
* @author Arthur Zimek
+ *
+ * @apiviz.composedOf String
*/
public class SimpleClassLabel extends ClassLabel {
/**
* Holds the String designating the label.
*/
private String label;
-
+
/**
- * @see ClassLabel#ClassLabel()
+ * Constructor.
+ *
+ * @param label Label
*/
- public SimpleClassLabel() {
+ public SimpleClassLabel(String label) {
super();
- }
-
- /**
- * Provides a simple class label covering the given String.
- *
- * @param label the String to be cast as label
- */
- @Override
- public void init(String label) {
this.label = label;
}
@@ -107,4 +102,19 @@ public class SimpleClassLabel extends ClassLabel {
public String toString() {
return label;
}
+
+ /**
+ * Factory class
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.has SimpleClassLabel - - «creates»
+ * @apiviz.stereotype factory
+ */
+ public static class Factory extends ClassLabel.Factory<SimpleClassLabel> {
+ @Override
+ public SimpleClassLabel makeFromString(String lbl) {
+ return new SimpleClassLabel(lbl);
+ }
+ }
} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/data/model/ClusterModel.java b/src/de/lmu/ifi/dbs/elki/data/model/ClusterModel.java
index c8b3e0eb..f40b4b73 100644
--- a/src/de/lmu/ifi/dbs/elki/data/model/ClusterModel.java
+++ b/src/de/lmu/ifi/dbs/elki/data/model/ClusterModel.java
@@ -30,6 +30,7 @@ package de.lmu.ifi.dbs.elki.data.model;
*
* @author Erich Schubert
*
+ * @apiviz.landmark
*/
public final class ClusterModel extends BaseModel {
/**
diff --git a/src/de/lmu/ifi/dbs/elki/data/model/Model.java b/src/de/lmu/ifi/dbs/elki/data/model/Model.java
index 58e9542b..d07fc926 100644
--- a/src/de/lmu/ifi/dbs/elki/data/model/Model.java
+++ b/src/de/lmu/ifi/dbs/elki/data/model/Model.java
@@ -29,7 +29,8 @@ package de.lmu.ifi.dbs.elki.data.model;
*
* @author Erich Schubert
*
+ * @apiviz.landmark
*/
public interface Model {
// currently, there are no requirements on a model.
-}
+} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/data/synthetic/bymodel/GeneratorMain.java b/src/de/lmu/ifi/dbs/elki/data/synthetic/bymodel/GeneratorMain.java
index 6400a747..eef7b13d 100644
--- a/src/de/lmu/ifi/dbs/elki/data/synthetic/bymodel/GeneratorMain.java
+++ b/src/de/lmu/ifi/dbs/elki/data/synthetic/bymodel/GeneratorMain.java
@@ -23,14 +23,18 @@ package de.lmu.ifi.dbs.elki.data.synthetic.bymodel;
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-import java.io.IOException;
-import java.io.OutputStreamWriter;
+import java.util.ArrayList;
+import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
-import de.lmu.ifi.dbs.elki.data.synthetic.bymodel.distribution.Distribution;
+import de.lmu.ifi.dbs.elki.data.ClassLabel;
+import de.lmu.ifi.dbs.elki.data.DoubleVector;
+import de.lmu.ifi.dbs.elki.data.SimpleClassLabel;
+import de.lmu.ifi.dbs.elki.data.type.TypeUtil;
+import de.lmu.ifi.dbs.elki.data.type.VectorFieldTypeInformation;
+import de.lmu.ifi.dbs.elki.datasource.bundle.MultipleObjectsBundle;
import de.lmu.ifi.dbs.elki.math.linearalgebra.Vector;
-import de.lmu.ifi.dbs.elki.utilities.FormatUtil;
import de.lmu.ifi.dbs.elki.utilities.exceptions.UnableToComplyException;
/**
@@ -63,14 +67,9 @@ import de.lmu.ifi.dbs.elki.utilities.exceptions.UnableToComplyException;
*/
public class GeneratorMain {
/**
- * Line separator for output
- */
- public final static String LINE_SEPARATOR = System.getProperty("line.separator");
-
- /**
* List of clusters to generate
*/
- private LinkedList<GeneratorInterface> clusters = new LinkedList<GeneratorInterface>();
+ private LinkedList<GeneratorInterface> generators = new LinkedList<GeneratorInterface>();
/**
* Add a cluster to the cluster list.
@@ -78,7 +77,7 @@ public class GeneratorMain {
* @param c cluster to add
*/
public void addCluster(GeneratorInterface c) {
- clusters.add(c);
+ generators.add(c);
}
/**
@@ -94,18 +93,18 @@ public class GeneratorMain {
*/
public void generate() throws UnableToComplyException {
// we actually need some clusters.
- if(clusters.size() < 1) {
+ if(generators.size() < 1) {
throw new UnableToComplyException("No clusters specified.");
}
// Assert that cluster dimensions agree.
- int dim = clusters.get(0).getDim();
- for(GeneratorInterface c : clusters) {
+ final int dim = generators.get(0).getDim();
+ for(GeneratorInterface c : generators) {
if(c.getDim() != dim) {
throw new UnableToComplyException("Cluster dimensions do not agree.");
}
}
// generate clusters
- for(GeneratorInterface curclus : clusters) {
+ for(GeneratorInterface curclus : generators) {
while(curclus.getPoints().size() < curclus.getSize()) {
// generate the "missing" number of points
List<Vector> newp = curclus.generate(curclus.getSize() - curclus.getPoints().size());
@@ -115,7 +114,7 @@ public class GeneratorMain {
if(testAgainstModel) {
double max = 0.0;
double is = 0.0;
- for(GeneratorInterface other : clusters) {
+ for(GeneratorInterface other : generators) {
double d = other.getDensity(p) * other.getSize();
if(other == curclus) {
is = d;
@@ -143,66 +142,6 @@ public class GeneratorMain {
}
/**
- * Write the resulting clusters to an output stream.
- *
- * @param outStream output stream
- * @throws IOException thrown on write errors
- */
- public void writeClusters(OutputStreamWriter outStream) throws IOException {
- // compute global discard values
- int totalsize = 0;
- int totaldisc = 0;
- assert (clusters.size() > 0);
- for(GeneratorInterface curclus : clusters) {
- totalsize = totalsize + curclus.getSize();
- if(curclus instanceof GeneratorSingleCluster) {
- totaldisc = totaldisc + ((GeneratorSingleCluster) curclus).getDiscarded();
- }
- }
- double globdens = (double) (totalsize + totaldisc) / totalsize;
- outStream.write("########################################################" + LINE_SEPARATOR);
- outStream.write("## Number of clusters: " + clusters.size() + LINE_SEPARATOR);
- for(GeneratorInterface curclus : clusters) {
- outStream.write("########################################################" + LINE_SEPARATOR);
- outStream.write("## Cluster: " + curclus.getName() + LINE_SEPARATOR);
- outStream.write("########################################################" + LINE_SEPARATOR);
- outStream.write("## Size: " + curclus.getSize() + LINE_SEPARATOR);
- if(curclus instanceof GeneratorSingleCluster) {
- GeneratorSingleCluster cursclus = (GeneratorSingleCluster) curclus;
- Vector cmin = cursclus.getClipmin();
- Vector cmax = cursclus.getClipmax();
- if(cmin != null && cmax != null) {
- outStream.write("## Clipping: " + cmin.toString() + " - " + cmax.toString() + LINE_SEPARATOR);
- }
- outStream.write("## Density correction factor: " + cursclus.getDensityCorrection() + LINE_SEPARATOR);
- outStream.write("## Generators:" + LINE_SEPARATOR);
- for(Distribution gen : cursclus.getAxes()) {
- outStream.write("## " + gen.toString() + LINE_SEPARATOR);
- }
- if(cursclus.getTrans() != null && cursclus.getTrans().getTransformation() != null) {
- outStream.write("## Affine transformation matrix:" + LINE_SEPARATOR);
- outStream.write(FormatUtil.format(cursclus.getTrans().getTransformation(), "## ") + LINE_SEPARATOR);
- }
- }
- if(curclus instanceof GeneratorInterfaceDynamic) {
- GeneratorSingleCluster cursclus = (GeneratorSingleCluster) curclus;
- outStream.write("## Discards: " + cursclus.getDiscarded() + " Retries left: " + cursclus.getRetries() + LINE_SEPARATOR);
- double corf = /* cursclus.overweight */(double) (cursclus.getSize() + cursclus.getDiscarded()) / cursclus.getSize() / globdens;
- outStream.write("## Density correction factor estimation: " + corf + LINE_SEPARATOR);
-
- }
- outStream.write("########################################################" + LINE_SEPARATOR);
- for(Vector p : curclus.getPoints()) {
- for(int i = 0; i < p.getRowDimensionality(); i++) {
- outStream.write(p.get(i) + " ");
- }
- outStream.write(curclus.getName());
- outStream.write(LINE_SEPARATOR);
- }
- }
- }
-
- /**
* Return value of the {@link #testAgainstModel} flag
*
* @return value of testAgainstModel
@@ -219,4 +158,36 @@ public class GeneratorMain {
public void setTestAgainstModel(boolean testAgainstModel) {
this.testAgainstModel = testAgainstModel;
}
-}
+
+ /**
+ * Access the generators.
+ *
+ * @return generators
+ */
+ public List<GeneratorInterface> getGenerators() {
+ return Collections.unmodifiableList(generators);
+ }
+
+ /**
+ * Get the objects bundle
+ *
+ * @return Bundle
+ */
+ public MultipleObjectsBundle getBundle() {
+ final int dim = generators.get(0).getDim();
+ final DoubleVector factory = new DoubleVector(new double[dim]);
+ MultipleObjectsBundle bundle = new MultipleObjectsBundle();
+ VectorFieldTypeInformation<DoubleVector> type = new VectorFieldTypeInformation<DoubleVector>(DoubleVector.class, dim, factory);
+ bundle.appendColumn(type, new ArrayList<Object>());
+ bundle.appendColumn(TypeUtil.CLASSLABEL, new ArrayList<Object>());
+
+ for(GeneratorInterface generator : generators) {
+ ClassLabel l = new SimpleClassLabel(generator.getName());
+ for(Vector v : generator.getPoints()) {
+ DoubleVector dv = new DoubleVector(v);
+ bundle.appendSimple(dv, l);
+ }
+ }
+ return bundle;
+ }
+} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/datasource/DatabaseConnection.java b/src/de/lmu/ifi/dbs/elki/datasource/DatabaseConnection.java
index 2900ab17..72b54f27 100644
--- a/src/de/lmu/ifi/dbs/elki/datasource/DatabaseConnection.java
+++ b/src/de/lmu/ifi/dbs/elki/datasource/DatabaseConnection.java
@@ -36,6 +36,7 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.Parameterizable;
*
* @author Arthur Zimek
*
+ * @apiviz.landmark
* @apiviz.has MultipleObjectsBundle
*/
public interface DatabaseConnection extends Parameterizable {
diff --git a/src/de/lmu/ifi/dbs/elki/datasource/ExternalIDJoinDatabaseConnection.java b/src/de/lmu/ifi/dbs/elki/datasource/ExternalIDJoinDatabaseConnection.java
index 9bad2941..aa777ca1 100644
--- a/src/de/lmu/ifi/dbs/elki/datasource/ExternalIDJoinDatabaseConnection.java
+++ b/src/de/lmu/ifi/dbs/elki/datasource/ExternalIDJoinDatabaseConnection.java
@@ -44,6 +44,8 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ObjectListParamet
* Joins multiple data sources by their label
*
* @author Erich Schubert
+ *
+ * @apiviz.uses ExternalID
*/
public class ExternalIDJoinDatabaseConnection extends AbstractDatabaseConnection implements Parameterizable {
/**
@@ -96,12 +98,12 @@ public class ExternalIDJoinDatabaseConnection extends AbstractDatabaseConnection
for(int i = 0; i < first.dataLength(); i++) {
ExternalID data = (ExternalID) first.data(i, lblcol);
if(data == null) {
- logger.warning("Object without ID encountered.");
+ logger.debug("Object without ID encountered.");
continue;
}
Integer old = labelmap.put(data, i);
if(old != null) {
- logger.warning("Duplicate id encountered: " + data + " in rows " + old + " and " + i);
+ logger.debug("Duplicate id encountered: " + data + " in rows " + old + " and " + i);
}
}
}
@@ -153,7 +155,7 @@ public class ExternalIDJoinDatabaseConnection extends AbstractDatabaseConnection
}
Integer row = labelmap.get(data);
if(row == null) {
- logger.warning("ID not found for join: " + data + " in row " + i);
+ logger.debug("ID not found for join: " + data + " in row " + i);
continue;
}
for(int d = 0; d < cur.metaLength(); d++) {
diff --git a/src/de/lmu/ifi/dbs/elki/datasource/FileBasedDatabaseConnection.java b/src/de/lmu/ifi/dbs/elki/datasource/FileBasedDatabaseConnection.java
index 168a85e4..39c6d2a2 100644
--- a/src/de/lmu/ifi/dbs/elki/datasource/FileBasedDatabaseConnection.java
+++ b/src/de/lmu/ifi/dbs/elki/datasource/FileBasedDatabaseConnection.java
@@ -40,6 +40,8 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.FileParameter;
* Provides a file based database connection based on the parser to be set.
*
* @author Arthur Zimek
+ *
+ * @apiviz.landmark
*/
public class FileBasedDatabaseConnection extends InputStreamDatabaseConnection {
/**
diff --git a/src/de/lmu/ifi/dbs/elki/datasource/GeneratorXMLDatabaseConnection.java b/src/de/lmu/ifi/dbs/elki/datasource/GeneratorXMLDatabaseConnection.java
new file mode 100644
index 00000000..40e4d5af
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/datasource/GeneratorXMLDatabaseConnection.java
@@ -0,0 +1,636 @@
+package de.lmu.ifi.dbs.elki.datasource;
+/*
+ This file is part of ELKI:
+ Environment for Developing KDD-Applications Supported by Index-Structures
+
+ Copyright (C) 2011
+ Ludwig-Maximilians-Universität München
+ Lehr- und Forschungseinheit für Datenbanksysteme
+ ELKI Development Team
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.LinkedList;
+import java.util.Random;
+import java.util.regex.Pattern;
+
+import javax.xml.XMLConstants;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.validation.Schema;
+import javax.xml.validation.SchemaFactory;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.xml.sax.SAXException;
+
+import de.lmu.ifi.dbs.elki.application.GeneratorXMLSpec;
+import de.lmu.ifi.dbs.elki.data.synthetic.bymodel.GeneratorMain;
+import de.lmu.ifi.dbs.elki.data.synthetic.bymodel.GeneratorSingleCluster;
+import de.lmu.ifi.dbs.elki.data.synthetic.bymodel.GeneratorStatic;
+import de.lmu.ifi.dbs.elki.data.synthetic.bymodel.distribution.Distribution;
+import de.lmu.ifi.dbs.elki.data.synthetic.bymodel.distribution.GammaDistribution;
+import de.lmu.ifi.dbs.elki.data.synthetic.bymodel.distribution.NormalDistribution;
+import de.lmu.ifi.dbs.elki.data.synthetic.bymodel.distribution.UniformDistribution;
+import de.lmu.ifi.dbs.elki.datasource.bundle.MultipleObjectsBundle;
+import de.lmu.ifi.dbs.elki.logging.Logging;
+import de.lmu.ifi.dbs.elki.math.linearalgebra.Vector;
+import de.lmu.ifi.dbs.elki.utilities.exceptions.AbortException;
+import de.lmu.ifi.dbs.elki.utilities.exceptions.UnableToComplyException;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.OptionID;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.DoubleParameter;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.FileParameter;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.IntParameter;
+import de.lmu.ifi.dbs.elki.utilities.xml.XMLNodeIterator;
+
+public class GeneratorXMLDatabaseConnection implements DatabaseConnection {
+ /**
+ * Logger
+ */
+ private static Logging logger = Logging.getLogger(GeneratorXMLDatabaseConnection.class);
+
+ /**
+ * A pattern defining whitespace.
+ */
+ public static final Pattern WHITESPACE_PATTERN = Pattern.compile("\\s+");
+
+ /**
+ * Parameter to give the configuration file
+ */
+ public static final OptionID CONFIGFILE_ID = OptionID.getOrCreateOptionID("bymodel.spec", "The generator specification file.");
+
+ /**
+ * Parameter to give the configuration file
+ */
+ public static final OptionID RANDOMSEED_ID = OptionID.getOrCreateOptionID("bymodel.randomseed", "The random generator seed.");
+
+ /**
+ * Parameter to give the configuration file
+ */
+ public static final OptionID SIZE_SCALE_ID = OptionID.getOrCreateOptionID("bymodel.sizescale", "Factor for scaling the specified cluster sizes.");
+
+ /**
+ * File name of the generators XML Schema file.
+ */
+ private static final String GENERATOR_SCHEMA_FILE = GeneratorXMLSpec.class.getPackage().getName().replace('.', '/') + '/' + "GeneratorByModel.xsd";
+
+ /**
+ * The configuration file.
+ */
+ File specfile;
+
+ /**
+ * Parameter for scaling the cluster sizes.
+ */
+ double sizescale = 1.0;
+
+ /**
+ * The actual generator class
+ */
+ public GeneratorMain gen = new GeneratorMain();
+
+ /**
+ * Random generator used for initializing cluster generators.
+ */
+ private Random clusterRandom = null;
+
+ /**
+ * Set testAgainstModel flag
+ */
+ private boolean testAgainstModel = true;
+
+ /**
+ * Constructor.
+ *
+ * @param specfile Specification file
+ * @param sizescale Size scaling
+ * @param clusterRandom Random number generator
+ */
+ public GeneratorXMLDatabaseConnection(File specfile, double sizescale, Random clusterRandom) {
+ super();
+ this.specfile = specfile;
+ this.sizescale = sizescale;
+ this.clusterRandom = clusterRandom;
+ if(this.clusterRandom == null) {
+ this.clusterRandom = new Random();
+ }
+ }
+
+ @Override
+ public MultipleObjectsBundle loadData() {
+ if(logger.isVerbose()) {
+ logger.verbose("Loading specification ...");
+ }
+ try {
+ loadXMLSpecification();
+ }
+ catch(UnableToComplyException e) {
+ throw new AbortException("Cannot load XML specification", e);
+ }
+ if(logger.isVerbose()) {
+ logger.verbose("Generating clusters ...");
+ }
+ gen.setTestAgainstModel(testAgainstModel);
+ try {
+ gen.generate();
+ return gen.getBundle();
+ }
+ catch(UnableToComplyException e) {
+ throw new AbortException("Data generation failed. ", e);
+ }
+ }
+
+ /**
+ * Load the XML configuration file.
+ *
+ * @throws UnableToComplyException
+ */
+ private void loadXMLSpecification() throws UnableToComplyException {
+ try {
+ InputStream in = new FileInputStream(specfile);
+ DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
+ dbf.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
+ URL url = ClassLoader.getSystemResource(GENERATOR_SCHEMA_FILE);
+ if(url != null) {
+ try {
+ Schema schema = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI).newSchema(url);
+ dbf.setSchema(schema);
+ dbf.setIgnoringElementContentWhitespace(true);
+ }
+ catch(Exception e) {
+ logger.warning("Could not set up XML Schema validation for speciciation file.");
+ }
+ }
+ else {
+ logger.warning("Could not set up XML Schema validation for speciciation file.");
+ }
+ Document doc = dbf.newDocumentBuilder().parse(in);
+ Node root = doc.getDocumentElement();
+ if(root.getNodeName() == "dataset") {
+ processElementDataset(root);
+ }
+ else {
+ throw new UnableToComplyException("Experiment specification has incorrect document element: " + root.getNodeName());
+ }
+ }
+ catch(FileNotFoundException e) {
+ throw new UnableToComplyException("Can't open specification file.", e);
+ }
+ catch(SAXException e) {
+ throw new UnableToComplyException("Error parsing specification file.", e);
+ }
+ catch(IOException e) {
+ throw new UnableToComplyException("IO Exception loading specification file.", e);
+ }
+ catch(ParserConfigurationException e) {
+ throw new UnableToComplyException("Parser Configuration Error", e);
+ }
+ }
+
+ /**
+ * Process a 'dataset' Element in the XML stream.
+ *
+ * @param cur Current document nod
+ * @throws UnableToComplyException
+ */
+ private void processElementDataset(Node cur) throws UnableToComplyException {
+ // *** get parameters
+ String seedstr = ((Element) cur).getAttribute("random-seed");
+ if(seedstr != null && seedstr != "") {
+ clusterRandom = new Random((int) (Integer.valueOf(seedstr) * sizescale));
+ }
+ String testmod = ((Element) cur).getAttribute("test-model");
+ if(testmod != null && testmod != "") {
+ testAgainstModel = (Integer.valueOf(testmod) != 0);
+ }
+ // TODO: check for unknown attributes.
+ for(Node child : new XMLNodeIterator(cur.getFirstChild())) {
+ if(child.getNodeName() == "cluster") {
+ processElementCluster(child);
+ }
+ else if(child.getNodeName() == "static") {
+ processElementStatic(child);
+ }
+ else if(child.getNodeType() == Node.ELEMENT_NODE) {
+ logger.warning("Unknown element in XML specification file: " + child.getNodeName());
+ }
+ }
+ }
+
+ /**
+ * Process a 'cluster' Element in the XML stream.
+ *
+ * @param cur Current document nod
+ * @throws UnableToComplyException
+ */
+ private void processElementCluster(Node cur) throws UnableToComplyException {
+ int size = -1;
+ double overweight = 1.0;
+
+ String sizestr = ((Element) cur).getAttribute("size");
+ if(sizestr != null && sizestr != "") {
+ size = (int) (Integer.valueOf(sizestr) * sizescale);
+ }
+
+ String name = ((Element) cur).getAttribute("name");
+
+ String dcostr = ((Element) cur).getAttribute("density-correction");
+ if(dcostr != null && dcostr != "") {
+ overweight = Double.valueOf(dcostr);
+ }
+
+ if(size < 0) {
+ throw new UnableToComplyException("No valid cluster size given in specification file.");
+ }
+ if(name == null || name == "") {
+ throw new UnableToComplyException("No cluster name given in specification file.");
+ }
+
+ // *** add new cluster object
+ Random newRand = new Random(clusterRandom.nextLong());
+ GeneratorSingleCluster cluster = new GeneratorSingleCluster(name, size, overweight, newRand);
+
+ // TODO: check for unknown attributes.
+ for(Node child : new XMLNodeIterator(cur.getFirstChild())) {
+ if(child.getNodeName() == "uniform") {
+ processElementUniform(cluster, child);
+ }
+ else if(child.getNodeName() == "normal") {
+ processElementNormal(cluster, child);
+ }
+ else if(child.getNodeName() == "gamma") {
+ processElementGamma(cluster, child);
+ }
+ else if(child.getNodeName() == "rotate") {
+ processElementRotate(cluster, child);
+ }
+ else if(child.getNodeName() == "translate") {
+ processElementTranslate(cluster, child);
+ }
+ else if(child.getNodeName() == "clip") {
+ processElementClipping(cluster, child);
+ }
+ else if(child.getNodeType() == Node.ELEMENT_NODE) {
+ logger.warning("Unknown element in XML specification file: " + child.getNodeName());
+ }
+ }
+
+ gen.addCluster(cluster);
+ }
+
+ /**
+ * Process a 'uniform' Element in the XML stream.
+ *
+ * @param cluster
+ * @param cur Current document nod
+ * @throws UnableToComplyException
+ */
+ private void processElementUniform(GeneratorSingleCluster cluster, Node cur) throws UnableToComplyException {
+ double min = 0.0;
+ double max = 1.0;
+
+ String minstr = ((Element) cur).getAttribute("min");
+ if(minstr != null && minstr != "") {
+ min = Double.valueOf(minstr);
+ }
+ String maxstr = ((Element) cur).getAttribute("max");
+ if(maxstr != null && maxstr != "") {
+ max = Double.valueOf(maxstr);
+ }
+
+ // *** new uniform generator
+ Random random = cluster.getNewRandomGenerator();
+ Distribution generator = new UniformDistribution(min, max, random);
+ cluster.addGenerator(generator);
+
+ // TODO: check for unknown attributes.
+ for(Node child : new XMLNodeIterator(cur.getFirstChild())) {
+ if(child.getNodeType() == Node.ELEMENT_NODE) {
+ logger.warning("Unknown element in XML specification file: " + child.getNodeName());
+ }
+ }
+ }
+
+ /**
+ * Process a 'normal' Element in the XML stream.
+ *
+ * @param cluster
+ * @param cur Current document nod
+ * @throws UnableToComplyException
+ */
+ private void processElementNormal(GeneratorSingleCluster cluster, Node cur) throws UnableToComplyException {
+ double mean = 0.0;
+ double stddev = 1.0;
+ String meanstr = ((Element) cur).getAttribute("mean");
+ if(meanstr != null && meanstr != "") {
+ mean = Double.valueOf(meanstr);
+ }
+ String stddevstr = ((Element) cur).getAttribute("stddev");
+ if(stddevstr != null && stddevstr != "") {
+ stddev = Double.valueOf(stddevstr);
+ }
+
+ // *** New normal distribution generator
+ Random random = cluster.getNewRandomGenerator();
+ Distribution generator = new NormalDistribution(mean, stddev, random);
+ cluster.addGenerator(generator);
+
+ // TODO: check for unknown attributes.
+ for(Node child : new XMLNodeIterator(cur.getFirstChild())) {
+ if(child.getNodeType() == Node.ELEMENT_NODE) {
+ logger.warning("Unknown element in XML specification file: " + child.getNodeName());
+ }
+ }
+ }
+
+ /**
+ * Process a 'gamma' Element in the XML stream.
+ *
+ * @param cluster
+ * @param cur Current document nod
+ * @throws UnableToComplyException
+ */
+ private void processElementGamma(GeneratorSingleCluster cluster, Node cur) throws UnableToComplyException {
+ double k = 1.0;
+ double theta = 1.0;
+ String kstr = ((Element) cur).getAttribute("k");
+ if(kstr != null && kstr != "") {
+ k = Double.valueOf(kstr);
+ }
+ String thetastr = ((Element) cur).getAttribute("theta");
+ if(thetastr != null && thetastr != "") {
+ theta = Double.valueOf(thetastr);
+ }
+
+ // *** New normal distribution generator
+ Random random = cluster.getNewRandomGenerator();
+ Distribution generator = new GammaDistribution(k, theta, random);
+ cluster.addGenerator(generator);
+
+ // TODO: check for unknown attributes.
+ for(Node child : new XMLNodeIterator(cur.getFirstChild())) {
+ if(child.getNodeType() == Node.ELEMENT_NODE) {
+ logger.warning("Unknown element in XML specification file: " + child.getNodeName());
+ }
+ }
+ }
+
+ /**
+ * Process a 'rotate' Element in the XML stream.
+ *
+ * @param cluster
+ * @param cur Current document nod
+ * @throws UnableToComplyException
+ */
+ private void processElementRotate(GeneratorSingleCluster cluster, Node cur) throws UnableToComplyException {
+ int axis1 = 0;
+ int axis2 = 0;
+ double angle = 0.0;
+
+ String a1str = ((Element) cur).getAttribute("axis1");
+ if(a1str != null && a1str != "") {
+ axis1 = Integer.valueOf(a1str);
+ }
+ String a2str = ((Element) cur).getAttribute("axis2");
+ if(a2str != null && a2str != "") {
+ axis2 = Integer.valueOf(a2str);
+ }
+ String anstr = ((Element) cur).getAttribute("angle");
+ if(anstr != null && anstr != "") {
+ angle = Double.valueOf(anstr);
+ }
+ if(axis1 <= 0 || axis1 > cluster.getDim()) {
+ throw new UnableToComplyException("Invalid axis1 number given in specification file.");
+ }
+ if(axis1 <= 0 || axis1 > cluster.getDim()) {
+ throw new UnableToComplyException("Invalid axis2 number given in specification file.");
+ }
+ if(axis1 == axis2) {
+ throw new UnableToComplyException("Invalid axis numbers given in specification file.");
+ }
+
+ // Add rotation to cluster.
+ cluster.addRotation(axis1 - 1, axis2 - 1, Math.toRadians(angle));
+
+ // TODO: check for unknown attributes.
+ for(Node child : new XMLNodeIterator(cur.getFirstChild())) {
+ if(child.getNodeType() == Node.ELEMENT_NODE) {
+ logger.warning("Unknown element in XML specification file: " + child.getNodeName());
+ }
+ }
+ }
+
+ /**
+ * Process a 'translate' Element in the XML stream.
+ *
+ * @param cluster
+ * @param cur Current document nod
+ * @throws UnableToComplyException
+ */
+ private void processElementTranslate(GeneratorSingleCluster cluster, Node cur) throws UnableToComplyException {
+ Vector offset = null;
+ String vstr = ((Element) cur).getAttribute("vector");
+ if(vstr != null && vstr != "") {
+ offset = parseVector(vstr);
+ }
+ if(offset == null) {
+ throw new UnableToComplyException("No translation vector given.");
+ }
+
+ // *** add new translation
+ cluster.addTranslation(offset);
+
+ // TODO: check for unknown attributes.
+ for(Node child : new XMLNodeIterator(cur.getFirstChild())) {
+ if(child.getNodeType() == Node.ELEMENT_NODE) {
+ logger.warning("Unknown element in XML specification file: " + child.getNodeName());
+ }
+ }
+ }
+
+ /**
+ * Process a 'clipping' Element in the XML stream.
+ *
+ * @param cluster
+ * @param cur Current document nod
+ * @throws UnableToComplyException
+ */
+ private void processElementClipping(GeneratorSingleCluster cluster, Node cur) throws UnableToComplyException {
+ Vector cmin = null;
+ Vector cmax = null;
+
+ String minstr = ((Element) cur).getAttribute("min");
+ if(minstr != null && minstr != "") {
+ cmin = parseVector(minstr);
+ }
+ String maxstr = ((Element) cur).getAttribute("max");
+ if(maxstr != null && maxstr != "") {
+ cmax = parseVector(maxstr);
+ }
+ if(cmin == null || cmax == null) {
+ throw new UnableToComplyException("No or incomplete clipping vectors given.");
+ }
+
+ // *** set clipping
+ cluster.setClipping(cmin, cmax);
+
+ // TODO: check for unknown attributes.
+ for(Node child : new XMLNodeIterator(cur.getFirstChild())) {
+ if(child.getNodeType() == Node.ELEMENT_NODE) {
+ logger.warning("Unknown element in XML specification file: " + child.getNodeName());
+ }
+ }
+ }
+
+ /**
+ * Process a 'static' cluster Element in the XML stream.
+ *
+ * @param cur Current document nod
+ * @throws UnableToComplyException
+ */
+ private void processElementStatic(Node cur) throws UnableToComplyException {
+ String name = ((Element) cur).getAttribute("name");
+ if(name == null) {
+ throw new UnableToComplyException("No cluster name given in specification file.");
+ }
+
+ LinkedList<Vector> points = new LinkedList<Vector>();
+ // TODO: check for unknown attributes.
+ for(Node child : new XMLNodeIterator(cur.getFirstChild())) {
+ if(child.getNodeName() == "point") {
+ processElementPoint(points, child);
+ }
+ else if(child.getNodeType() == Node.ELEMENT_NODE) {
+ logger.warning("Unknown element in XML specification file: " + child.getNodeName());
+ }
+ }
+ // *** add new cluster object
+ GeneratorStatic cluster = new GeneratorStatic(name, points);
+
+ gen.addCluster(cluster);
+ if(logger.isVerbose()) {
+ logger.verbose("Loaded cluster " + cluster.name + " from specification.");
+ }
+ }
+
+ /**
+ * Parse a 'point' element (point vector for a static cluster)
+ *
+ * @param points current list of points (to append to)
+ * @param cur Current document nod
+ * @throws UnableToComplyException
+ */
+ private void processElementPoint(LinkedList<Vector> points, Node cur) throws UnableToComplyException {
+ Vector point = null;
+ String vstr = ((Element) cur).getAttribute("vector");
+ if(vstr != null && vstr != "") {
+ point = parseVector(vstr);
+ }
+ if(point == null) {
+ throw new UnableToComplyException("No translation vector given.");
+ }
+
+ // *** add new point
+ points.add(point);
+
+ // TODO: check for unknown attributes.
+ for(Node child : new XMLNodeIterator(cur.getFirstChild())) {
+ if(child.getNodeType() == Node.ELEMENT_NODE) {
+ logger.warning("Unknown element in XML specification file: " + child.getNodeName());
+ }
+ }
+ }
+
+ /**
+ * Parse a string into a vector.
+ *
+ * TODO: move this into utility package?
+ *
+ * @param s String to parse
+ * @return Vector
+ * @throws UnableToComplyException
+ */
+ private Vector parseVector(String s) throws UnableToComplyException {
+ String[] entries = WHITESPACE_PATTERN.split(s);
+ double[] d = new double[entries.length];
+ for(int i = 0; i < entries.length; i++) {
+ try {
+ d[i] = Double.valueOf(entries[i]);
+ }
+ catch(NumberFormatException e) {
+ throw new UnableToComplyException("Could not parse vector.");
+ }
+ }
+ return new Vector(d);
+ }
+
+ /**
+ * Parameterization class.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ public static class Parameterizer extends AbstractParameterizer {
+ /**
+ * The configuration file.
+ */
+ File specfile = null;
+
+ /**
+ * Parameter for scaling the cluster sizes.
+ */
+ double sizescale = 1.0;
+
+ /**
+ * Random generator used for initializing cluster generators.
+ */
+ private Random clusterRandom = null;
+
+ @Override
+ protected void makeOptions(Parameterization config) {
+ super.makeOptions(config);
+ // Specification file
+ final FileParameter cfgparam = new FileParameter(CONFIGFILE_ID, FileParameter.FileType.INPUT_FILE);
+ if(config.grab(cfgparam)) {
+ specfile = cfgparam.getValue();
+ }
+ // Cluster size scaling
+ final DoubleParameter scalepar = new DoubleParameter(SIZE_SCALE_ID, 1.0);
+ if(config.grab(scalepar)) {
+ sizescale = scalepar.getValue();
+ }
+ // Random generator
+ final IntParameter seedpar = new IntParameter(RANDOMSEED_ID, true);
+ if(config.grab(seedpar)) {
+ clusterRandom = new Random(seedpar.getValue());
+ }
+ }
+
+ @Override
+ protected GeneratorXMLDatabaseConnection makeInstance() {
+ return new GeneratorXMLDatabaseConnection(specfile, sizescale, clusterRandom);
+ }
+ }
+} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/datasource/LabelJoinDatabaseConnection.java b/src/de/lmu/ifi/dbs/elki/datasource/LabelJoinDatabaseConnection.java
index b91ccb80..b34566ae 100644
--- a/src/de/lmu/ifi/dbs/elki/datasource/LabelJoinDatabaseConnection.java
+++ b/src/de/lmu/ifi/dbs/elki/datasource/LabelJoinDatabaseConnection.java
@@ -44,6 +44,8 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ObjectListParamet
* Joins multiple data sources by their label
*
* @author Erich Schubert
+ *
+ * @apiviz.uses LabelList
*/
public class LabelJoinDatabaseConnection extends AbstractDatabaseConnection implements Parameterizable {
/**
diff --git a/src/de/lmu/ifi/dbs/elki/datasource/filter/AttributeWiseErfNormalization.java b/src/de/lmu/ifi/dbs/elki/datasource/filter/AttributeWiseErfNormalization.java
index e2f99d35..d365a9ae 100644
--- a/src/de/lmu/ifi/dbs/elki/datasource/filter/AttributeWiseErfNormalization.java
+++ b/src/de/lmu/ifi/dbs/elki/datasource/filter/AttributeWiseErfNormalization.java
@@ -35,6 +35,8 @@ import de.lmu.ifi.dbs.elki.math.MathUtil;
* @author Erich Schubert
*
* @param <O> Object type
+ *
+ * @apiviz.uses NumberVector
*/
public class AttributeWiseErfNormalization<O extends NumberVector<O, ?>> extends AbstractNormalization<O> {
/**
diff --git a/src/de/lmu/ifi/dbs/elki/datasource/filter/AttributeWiseMinMaxNormalization.java b/src/de/lmu/ifi/dbs/elki/datasource/filter/AttributeWiseMinMaxNormalization.java
index f2fe02c0..d9a636ec 100644
--- a/src/de/lmu/ifi/dbs/elki/datasource/filter/AttributeWiseMinMaxNormalization.java
+++ b/src/de/lmu/ifi/dbs/elki/datasource/filter/AttributeWiseMinMaxNormalization.java
@@ -47,6 +47,8 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.Parameter;
*
* @author Elke Achtert
* @param <V> vector type
+ *
+ * @apiviz.uses NumberVector
*/
// TODO: extract superclass AbstractAttributeWiseNormalization
public class AttributeWiseMinMaxNormalization<V extends NumberVector<V, ?>> extends AbstractNormalization<V> {
diff --git a/src/de/lmu/ifi/dbs/elki/datasource/filter/AttributeWiseVarianceNormalization.java b/src/de/lmu/ifi/dbs/elki/datasource/filter/AttributeWiseVarianceNormalization.java
index 837f3ec5..3ae2fdad 100644
--- a/src/de/lmu/ifi/dbs/elki/datasource/filter/AttributeWiseVarianceNormalization.java
+++ b/src/de/lmu/ifi/dbs/elki/datasource/filter/AttributeWiseVarianceNormalization.java
@@ -50,6 +50,8 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.Parameter;
*
* @author Erich Schubert
* @param <V> vector type
+ *
+ * @apiviz.uses NumberVector
*/
// TODO: extract superclass AbstractAttributeWiseNormalization
public class AttributeWiseVarianceNormalization<V extends NumberVector<V, ?>> extends AbstractNormalization<V> {
diff --git a/src/de/lmu/ifi/dbs/elki/datasource/filter/ClassLabelFilter.java b/src/de/lmu/ifi/dbs/elki/datasource/filter/ClassLabelFilter.java
index ce79d612..1c9a2274 100644
--- a/src/de/lmu/ifi/dbs/elki/datasource/filter/ClassLabelFilter.java
+++ b/src/de/lmu/ifi/dbs/elki/datasource/filter/ClassLabelFilter.java
@@ -45,6 +45,7 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ObjectParameter;
*
* @author Erich Schubert
*
+ * @apiviz.uses LabelList oneway - - «reads»
* @apiviz.has ClassLabel
*/
public class ClassLabelFilter implements ObjectFilter {
@@ -74,18 +75,18 @@ public class ClassLabelFilter implements ObjectFilter {
/**
* The class label class to use.
*/
- private final Class<? extends ClassLabel> classLabelClass;
+ private final ClassLabel.Factory<?> classLabelFactory;
/**
* Constructor.
*
* @param classLabelIndex The index to convert
- * @param classLabelClass The class label class to use
+ * @param classLabelFactory The class label factory to use
*/
- public ClassLabelFilter(int classLabelIndex, Class<? extends ClassLabel> classLabelClass) {
+ public ClassLabelFilter(int classLabelIndex, ClassLabel.Factory<?> classLabelFactory) {
super();
this.classLabelIndex = classLabelIndex;
- this.classLabelClass = classLabelClass;
+ this.classLabelFactory = classLabelFactory;
}
@Override
@@ -112,8 +113,7 @@ public class ClassLabelFilter implements ObjectFilter {
if(obj != null) {
LabelList ll = (LabelList) obj;
try {
- ClassLabel lbl = classLabelClass.newInstance();
- lbl.init(ll.remove(classLabelIndex));
+ ClassLabel lbl = classLabelFactory.makeFromString(ll.remove(classLabelIndex));
clscol.add(lbl);
}
catch(Exception e) {
@@ -153,28 +153,28 @@ public class ClassLabelFilter implements ObjectFilter {
protected Integer classLabelIndex;
/**
- * The class label class to use.
+ * The class label factory to use.
*/
- private Class<? extends ClassLabel> classLabelClass;
+ private ClassLabel.Factory<?> classLabelFactory;
@Override
protected void makeOptions(Parameterization config) {
super.makeOptions(config);
// parameter class label index
final IntParameter classLabelIndexParam = new IntParameter(CLASS_LABEL_INDEX_ID, new GreaterEqualConstraint(0));
- final ObjectParameter<ClassLabel> classlabelClassParam = new ObjectParameter<ClassLabel>(CLASS_LABEL_CLASS_ID, ClassLabel.class, SimpleClassLabel.class);
+ final ObjectParameter<ClassLabel.Factory<?>> classlabelClassParam = new ObjectParameter<ClassLabel.Factory<?>>(CLASS_LABEL_CLASS_ID, ClassLabel.Factory.class, SimpleClassLabel.Factory.class);
config.grab(classLabelIndexParam);
config.grab(classlabelClassParam);
if(classLabelIndexParam.isDefined() && classlabelClassParam.isDefined()) {
classLabelIndex = classLabelIndexParam.getValue();
- classLabelClass = classlabelClassParam.getValue();
+ classLabelFactory = classlabelClassParam.instantiateClass(config);
}
}
@Override
protected Object makeInstance() {
- return new ClassLabelFilter(classLabelIndex, classLabelClass);
+ return new ClassLabelFilter(classLabelIndex, classLabelFactory);
}
}
} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/datasource/filter/DoubleVectorProjectionFilter.java b/src/de/lmu/ifi/dbs/elki/datasource/filter/DoubleVectorProjectionFilter.java
index d7aaf843..21b00b0d 100644
--- a/src/de/lmu/ifi/dbs/elki/datasource/filter/DoubleVectorProjectionFilter.java
+++ b/src/de/lmu/ifi/dbs/elki/datasource/filter/DoubleVectorProjectionFilter.java
@@ -36,6 +36,8 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameteriz
* onto a selected subset of attributes.</p>
*
* @author Arthur Zimek
+ *
+ * @apiviz.uses DoubleVector
*/
public class DoubleVectorProjectionFilter extends AbstractFeatureSelectionFilter<DoubleVector> {
/**
diff --git a/src/de/lmu/ifi/dbs/elki/datasource/filter/DoubleVectorRandomProjectionFilter.java b/src/de/lmu/ifi/dbs/elki/datasource/filter/DoubleVectorRandomProjectionFilter.java
index 1fe7c1a9..802b00d6 100644
--- a/src/de/lmu/ifi/dbs/elki/datasource/filter/DoubleVectorRandomProjectionFilter.java
+++ b/src/de/lmu/ifi/dbs/elki/datasource/filter/DoubleVectorRandomProjectionFilter.java
@@ -36,6 +36,8 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameteriz
* </p>
*
* @author Arthur Zimek
+ *
+ * @apiviz.uses DoubleVector
*/
public class DoubleVectorRandomProjectionFilter extends AbstractRandomFeatureSelectionFilter<DoubleVector> {
/**
diff --git a/src/de/lmu/ifi/dbs/elki/datasource/filter/ExternalIDFilter.java b/src/de/lmu/ifi/dbs/elki/datasource/filter/ExternalIDFilter.java
index 16933d4d..c53c2e4d 100644
--- a/src/de/lmu/ifi/dbs/elki/datasource/filter/ExternalIDFilter.java
+++ b/src/de/lmu/ifi/dbs/elki/datasource/filter/ExternalIDFilter.java
@@ -41,6 +41,9 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.IntParameter;
* Class that turns a label column into an external ID column.
*
* @author Erich Schubert
+ *
+ * @apiviz.uses LabelList oneway - - «reads»
+ * @apiviz.has ExternalID oneway - - «produces»
*/
// TODO: use a non-string class for external ids?
public class ExternalIDFilter implements ObjectFilter {
diff --git a/src/de/lmu/ifi/dbs/elki/datasource/filter/FilterByLabelFilter.java b/src/de/lmu/ifi/dbs/elki/datasource/filter/FilterByLabelFilter.java
index 58c1d509..b950080d 100644
--- a/src/de/lmu/ifi/dbs/elki/datasource/filter/FilterByLabelFilter.java
+++ b/src/de/lmu/ifi/dbs/elki/datasource/filter/FilterByLabelFilter.java
@@ -40,6 +40,8 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.PatternParameter;
* A filter to sort the data set by some label.
*
* @author Erich Schubert
+ *
+ * @apiviz.uses LabelList oneway - - «reads»
*/
public class FilterByLabelFilter implements ObjectFilter {
/**
diff --git a/src/de/lmu/ifi/dbs/elki/datasource/filter/FixedDBIDsFilter.java b/src/de/lmu/ifi/dbs/elki/datasource/filter/FixedDBIDsFilter.java
index eda4b9ee..b49494e4 100644
--- a/src/de/lmu/ifi/dbs/elki/datasource/filter/FixedDBIDsFilter.java
+++ b/src/de/lmu/ifi/dbs/elki/datasource/filter/FixedDBIDsFilter.java
@@ -41,7 +41,7 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.IntParameter;
*
* @author Erich Schubert
*
- * @apiviz.uses DBID
+ * @apiviz.has DBID oneway - - «produces»
*/
public class FixedDBIDsFilter implements ObjectFilter {
/**
diff --git a/src/de/lmu/ifi/dbs/elki/datasource/filter/InverseDocumentFrequencyNormalization.java b/src/de/lmu/ifi/dbs/elki/datasource/filter/InverseDocumentFrequencyNormalization.java
index 3b6e69c0..d8ffd71c 100644
--- a/src/de/lmu/ifi/dbs/elki/datasource/filter/InverseDocumentFrequencyNormalization.java
+++ b/src/de/lmu/ifi/dbs/elki/datasource/filter/InverseDocumentFrequencyNormalization.java
@@ -37,6 +37,8 @@ import de.lmu.ifi.dbs.elki.data.type.TypeUtil;
* frequency.
*
* @author Erich Schubert
+ *
+ * @apiviz.uses SparseFloatVector
*/
public class InverseDocumentFrequencyNormalization extends AbstractNormalization<SparseFloatVector> {
/**
diff --git a/src/de/lmu/ifi/dbs/elki/datasource/filter/Normalization.java b/src/de/lmu/ifi/dbs/elki/datasource/filter/Normalization.java
index c21c7603..417c4456 100644
--- a/src/de/lmu/ifi/dbs/elki/datasource/filter/Normalization.java
+++ b/src/de/lmu/ifi/dbs/elki/datasource/filter/Normalization.java
@@ -36,6 +36,7 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.Parameterizable;
*
* @author Arthur Zimek
*
+ * @apiviz.landmark
* @apiviz.has NonNumericFeaturesException
*
* @param <O> object type
diff --git a/src/de/lmu/ifi/dbs/elki/datasource/filter/SortByLabelFilter.java b/src/de/lmu/ifi/dbs/elki/datasource/filter/SortByLabelFilter.java
index 0f633ad3..74bbe3ac 100644
--- a/src/de/lmu/ifi/dbs/elki/datasource/filter/SortByLabelFilter.java
+++ b/src/de/lmu/ifi/dbs/elki/datasource/filter/SortByLabelFilter.java
@@ -36,6 +36,8 @@ import de.lmu.ifi.dbs.elki.logging.Logging;
* A filter to sort the data set by some label.
*
* @author Erich Schubert
+ *
+ * @apiviz.uses de.lmu.ifi.dbs.elki.data.LabelList oneway - - «reads»
*/
public class SortByLabelFilter implements ObjectFilter {
/**
diff --git a/src/de/lmu/ifi/dbs/elki/datasource/filter/SplitNumberVectorFilter.java b/src/de/lmu/ifi/dbs/elki/datasource/filter/SplitNumberVectorFilter.java
index 0ad8b5cc..25ab7e89 100644
--- a/src/de/lmu/ifi/dbs/elki/datasource/filter/SplitNumberVectorFilter.java
+++ b/src/de/lmu/ifi/dbs/elki/datasource/filter/SplitNumberVectorFilter.java
@@ -42,6 +42,8 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.IntListParameter;
* Split an existing column into two types.
*
* @author Erich Schubert
+ *
+ * @apiviz.uses NumberVector
*/
public class SplitNumberVectorFilter<V extends NumberVector<V, ?>> implements ObjectFilter {
/**
diff --git a/src/de/lmu/ifi/dbs/elki/datasource/parser/ArffParser.java b/src/de/lmu/ifi/dbs/elki/datasource/parser/ArffParser.java
index 9710b493..847349f2 100644
--- a/src/de/lmu/ifi/dbs/elki/datasource/parser/ArffParser.java
+++ b/src/de/lmu/ifi/dbs/elki/datasource/parser/ArffParser.java
@@ -1,4 +1,5 @@
package de.lmu.ifi.dbs.elki.datasource.parser;
+
/*
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
@@ -28,6 +29,11 @@ import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.StreamTokenizer;
import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.TreeMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -36,6 +42,7 @@ import de.lmu.ifi.dbs.elki.data.DoubleVector;
import de.lmu.ifi.dbs.elki.data.ExternalID;
import de.lmu.ifi.dbs.elki.data.LabelList;
import de.lmu.ifi.dbs.elki.data.SimpleClassLabel;
+import de.lmu.ifi.dbs.elki.data.SparseFloatVector;
import de.lmu.ifi.dbs.elki.data.type.SimpleTypeInformation;
import de.lmu.ifi.dbs.elki.data.type.TypeInformation;
import de.lmu.ifi.dbs.elki.data.type.TypeUtil;
@@ -43,6 +50,10 @@ import de.lmu.ifi.dbs.elki.data.type.VectorFieldTypeInformation;
import de.lmu.ifi.dbs.elki.datasource.bundle.MultipleObjectsBundle;
import de.lmu.ifi.dbs.elki.logging.Logging;
import de.lmu.ifi.dbs.elki.utilities.exceptions.AbortException;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.OptionID;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.PatternParameter;
/**
* Parser to load WEKA .arff files into ELKI.
@@ -83,12 +94,12 @@ public class ArffParser implements Parser {
/**
* Pattern to auto-convert columns to external ids.
*/
- public static final Pattern ARFF_MAGIC_EID = Pattern.compile("(ID|External-?ID)", Pattern.CASE_INSENSITIVE);
+ public static final String DEFAULT_ARFF_MAGIC_EID = "(ID|External-?ID)";
/**
* Pattern to auto-convert columns to class labels.
*/
- public static final Pattern ARFF_MAGIC_CLASS = Pattern.compile("(Class|Class-?Label)", Pattern.CASE_INSENSITIVE);
+ public static final String DEFAULT_ARFF_MAGIC_CLASS = "(Class|Class-?Label)";
/**
* Pattern for numeric columns
@@ -100,250 +111,472 @@ public class ArffParser implements Parser {
*/
public static final Pattern EMPTY = Pattern.compile("^\\s*$");
+ /**
+ * Pattern to recognize external ids
+ */
+ Pattern magic_eid;
+
+ /**
+ * Pattern to recognize class label columns
+ */
+ Pattern magic_class;
+
+ /**
+ * Constructor.
+ *
+ * @param magic_eid Magic to recognize external IDs
+ * @param magic_class Magic to recognize class labels
+ */
+ public ArffParser(Pattern magic_eid, Pattern magic_class) {
+ super();
+ this.magic_eid = magic_eid;
+ this.magic_class = magic_class;
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param magic_eid Magic to recognize external IDs
+ * @param magic_class Magic to recognize class labels
+ */
+ public ArffParser(String magic_eid, String magic_class) {
+ this(Pattern.compile(magic_eid, Pattern.CASE_INSENSITIVE), Pattern.compile(magic_class, Pattern.CASE_INSENSITIVE));
+ }
+
@Override
public MultipleObjectsBundle parse(InputStream instream) {
try {
BufferedReader br = new BufferedReader(new InputStreamReader(instream));
- String line;
- // Locate header line
- while(true) {
- line = br.readLine();
- if(line == null) {
- throw new AbortException(ARFF_HEADER_RELATION + " not found in file.");
- }
- // Skip comments and empty lines
- if(ARFF_COMMENT.matcher(line).matches() || EMPTY.matcher(line).matches()) {
- continue;
- }
- // Break on relation statement
- if(ARFF_HEADER_RELATION.matcher(line).matches()) {
- break;
- }
- throw new AbortException("Expected relation declaration: " + line);
- }
ArrayList<String> names = new ArrayList<String>();
ArrayList<String> types = new ArrayList<String>();
- // Load attribute metadata
- while(true) {
- line = br.readLine();
- if(line == null) {
- throw new AbortException(ARFF_HEADER_DATA + " not found in file.");
- }
- // Skip comments and empty lines
- if(ARFF_COMMENT.matcher(line).matches() || EMPTY.matcher(line).matches()) {
- continue;
+
+ readHeader(br);
+ parseAttributeStatements(br, names, types);
+
+ // Convert into column mapping. Prepare arrays to fill
+ int[] targ = new int[names.size()];
+ TypeInformation[] elkitypes = new TypeInformation[names.size()];
+ int[] dimsize = new int[names.size()];
+ processColumnTypes(names, types, targ, elkitypes, dimsize);
+
+ // Prepare bundle:
+ // This is a bit complicated to produce vector fields.
+ MultipleObjectsBundle bundle = new MultipleObjectsBundle();
+ StreamTokenizer tokenizer = makeArffTokenizer(br);
+
+ int state = 0;
+
+ nextToken(tokenizer);
+ while(tokenizer.ttype != StreamTokenizer.TT_EOF) {
+ // Parse instance
+ if(tokenizer.ttype == StreamTokenizer.TT_EOL) {
+ // ignore empty lines
}
- // Break on data statement to continue
- if(ARFF_HEADER_DATA.matcher(line).matches()) {
- break;
+ else if(tokenizer.ttype != '{') {
+ if(state == 0) {
+ setupBundleHeaders(names, targ, elkitypes, dimsize, bundle, false);
+ state = 1; // dense
+ }
+ if(state != 1) {
+ throw new AbortException("Mixing dense and sparse vectors is currently not allowed.");
+ }
+ // Load a dense instance
+ bundle.appendSimple(loadDenseInstance(tokenizer, dimsize, elkitypes, bundle.metaLength()));
}
- // Expect an attribute specification
- Matcher matcher = ARFF_HEADER_ATTRIBUTE.matcher(line);
- if(matcher.matches()) {
- String name = matcher.group(1);
- if(name.charAt(0) == '\'' && name.charAt(name.length() - 1) == '\'') {
- name = name.substring(1, name.length() - 1);
+ else {
+ if(state == 0) {
+ setupBundleHeaders(names, targ, elkitypes, dimsize, bundle, true);
+ state = 2; // dense
}
- else if(name.charAt(0) == '"' && name.charAt(name.length() - 1) == '"') {
- name = name.substring(1, name.length() - 1);
+ if(state != 2) {
+ throw new AbortException("Mixing dense and sparse vectors is currently not allowed.");
}
- String type = matcher.group(2);
- names.add(name);
- types.add(type);
- // logger.warning("Attribute name: " + name + " type: " + type);
- continue;
+ bundle.appendSimple(loadSparseInstance(tokenizer, targ, dimsize, elkitypes, bundle.metaLength()));
+ }
+ if(tokenizer.ttype != StreamTokenizer.TT_EOF) {
+ nextToken(tokenizer);
}
- throw new AbortException("Unrecognized line: " + line);
}
- assert (names.size() == types.size());
-
- int[] targ = new int[names.size()];
- TypeInformation[] etyp = new TypeInformation[names.size()];
- int[] dims = new int[names.size()];
+ return bundle;
+ }
+ catch(IOException e) {
+ throw new AbortException("IO error in parser", e);
+ }
+ }
- int next = 0;
- for(int i = 0; i < targ.length; i++) {
- // Turn into an external ID column.
- if(ARFF_MAGIC_EID.matcher(names.get(i)).matches()) {
- targ[i] = next;
- etyp[next] = TypeUtil.EXTERNALID;
- dims[next] = 1;
- next++;
- continue;
+ private Object[] loadSparseInstance(StreamTokenizer tokenizer, int[] targ, int[] dimsize, TypeInformation[] elkitypes, int metaLength) throws IOException {
+ // logger.warning("Sparse instance.");
+ Map<Integer, Object> map = new TreeMap<Integer, Object>();
+ while(true) {
+ nextToken(tokenizer);
+ assert (tokenizer.ttype != StreamTokenizer.TT_EOF && tokenizer.ttype != StreamTokenizer.TT_EOL);
+ if(tokenizer.ttype == '}') {
+ nextToken(tokenizer);
+ assert (tokenizer.ttype == StreamTokenizer.TT_EOF || tokenizer.ttype == StreamTokenizer.TT_EOL);
+ break;
+ }
+ else {
+ // sparse token
+ if(tokenizer.ttype != StreamTokenizer.TT_NUMBER) {
+ throw new AbortException("Unexpected token type encountered: " + tokenizer.toString());
}
- else if(ARFF_MAGIC_CLASS.matcher(names.get(i)).matches()) {
- targ[i] = next;
- etyp[next] = TypeUtil.CLASSLABEL;
- dims[next] = 1;
- next++;
- continue;
+ int dim = (int) tokenizer.nval;
+ if(map.containsKey(dim)) {
+ throw new AbortException("Duplicate key in sparse vector: " + tokenizer.toString());
+ }
+ nextToken(tokenizer);
+ if(tokenizer.ttype == StreamTokenizer.TT_NUMBER) {
+ map.put(dim, tokenizer.nval);
+ }
+ else if(tokenizer.ttype == StreamTokenizer.TT_WORD) {
+ map.put(dim, tokenizer.sval);
}
- else if(ARFF_NUMERIC.matcher(types.get(i)).matches()) {
- if(next > 0 && etyp[next - 1] == TypeUtil.NUMBER_VECTOR_FIELD) {
- targ[i] = next - 1;
- dims[next - 1]++;
+ else {
+ throw new AbortException("Unexpected token type encountered: " + tokenizer.toString());
+ }
+ }
+ }
+ Object[] data = new Object[metaLength];
+ for(int out = 0; out < metaLength; out++) {
+ // Find the first index
+ int s = -1;
+ for(int i = 0; i < targ.length; i++) {
+ if(targ[i] == out && s < 0) {
+ s = i;
+ break;
+ }
+ }
+ assert (s >= 0);
+ if(elkitypes[out] == TypeUtil.NUMBER_VECTOR_FIELD) {
+ Map<Integer, Float> f = new HashMap<Integer, Float>(dimsize[out]);
+ for(Entry<Integer, Object> key : map.entrySet()) {
+ int i = key.getKey();
+ if(i < s) {
continue;
}
- else {
- targ[i] = next;
- etyp[next] = TypeUtil.NUMBER_VECTOR_FIELD;
- dims[next] = 1;
- next++;
- continue;
+ if(i >= s + dimsize[out]) {
+ break;
}
+ double v = (Double) key.getValue();
+ f.put(i - s + 1, (float) v);
}
- else {
- if(next > 0 && etyp[next - 1] == TypeUtil.LABELLIST) {
- targ[i] = next - 1;
- dims[next - 1]++;
+ data[out] = new SparseFloatVector(f, dimsize[out]);
+ }
+ else if(elkitypes[out] == TypeUtil.LABELLIST) {
+ // Build a label list out of successive labels
+ LabelList ll = new LabelList();
+ for(Entry<Integer, Object> key : map.entrySet()) {
+ int i = key.getKey();
+ if(i < s) {
continue;
}
- else {
- targ[i] = next;
- etyp[next] = TypeUtil.LABELLIST;
- dims[next] = 1;
- next++;
- continue;
+ if(i >= s + dimsize[out]) {
+ break;
+ }
+ String v = (String) key.getValue();
+ if(ll.size() < i - s) {
+ logger.warning("Sparse consecutive labels are currently not correctly supported.");
}
+ ll.add(v);
+ }
+ data[out] = ll;
+ }
+ else if(elkitypes[out] == TypeUtil.EXTERNALID) {
+ String val = (String) map.get(s);
+ if(val != null) {
+ data[out] = new ExternalID(val);
+ }
+ else {
+ throw new AbortException("External ID column not set in sparse instance." + tokenizer.toString());
+ }
+ }
+ else if(elkitypes[out] == TypeUtil.CLASSLABEL) {
+ String val = (String) map.get(s);
+ if(val != null) {
+ // TODO: support other class label types.
+ ClassLabel lbl = new SimpleClassLabel(val);
+ data[out] = lbl;
}
+ else {
+ throw new AbortException("Class label column not set in sparse instance." + tokenizer.toString());
+ }
+ }
+ else {
+ throw new AbortException("Unsupported type for column " + "->" + out + ": " + ((elkitypes[out] != null) ? elkitypes[out].toString() : "null"));
}
+ }
+ return data;
+ }
- // Prepare bundle:
- // This is a bit complicated to produce vector fields.
- MultipleObjectsBundle bundle = new MultipleObjectsBundle();
- for(int in = 0, out = 0; in < targ.length; out++) {
- int nin = in + 1;
- for(; nin < targ.length; nin++) {
- if(targ[nin] != targ[in]) {
- break;
+ private Object[] loadDenseInstance(StreamTokenizer tokenizer, int[] dimsize, TypeInformation[] etyp, int outdim) throws IOException {
+ // logger.warning("Regular instance.");
+ Object[] data = new Object[outdim];
+ for(int out = 0; out < outdim; out++) {
+ if(etyp[out] == TypeUtil.NUMBER_VECTOR_FIELD) {
+ // For multi-column vectors, read successive columns
+ double[] cur = new double[dimsize[out]];
+ for(int k = 0; k < dimsize[out]; k++) {
+ if(tokenizer.ttype != StreamTokenizer.TT_NUMBER) {
+ throw new AbortException("Expected word token, got: " + tokenizer.toString());
}
+ cur[k] = tokenizer.nval;
+ nextToken(tokenizer);
}
- if(etyp[out] == TypeUtil.NUMBER_VECTOR_FIELD) {
- String[] labels = new String[dims[out]];
- // Collect labels:
- for(int i = 0; i < dims[out]; i++) {
- labels[i] = names.get(out + i);
+ data[out] = new DoubleVector(cur);
+ }
+ else if(etyp[out] == TypeUtil.LABELLIST) {
+ // Build a label list out of successive labels
+ LabelList ll = new LabelList();
+ for(int k = 0; k < dimsize[out]; k++) {
+ if(tokenizer.ttype != StreamTokenizer.TT_WORD) {
+ throw new AbortException("Expected word token, got: " + tokenizer.toString());
}
- VectorFieldTypeInformation<DoubleVector> type = new VectorFieldTypeInformation<DoubleVector>(DoubleVector.class, dims[out], labels, new DoubleVector(new double[dims[out]]));
- bundle.appendColumn(type, new ArrayList<DoubleVector>());
+ ll.add(tokenizer.sval);
+ nextToken(tokenizer);
}
- else if(etyp[out] == TypeUtil.LABELLIST) {
- String label = names.get(out);
- for(int i = 1; i < dims[out]; i++) {
- label = label + " " + names.get(out + i);
- }
- bundle.appendColumn(new SimpleTypeInformation<LabelList>(LabelList.class, label), new ArrayList<LabelList>());
+ data[out] = ll;
+ }
+ else if(etyp[out] == TypeUtil.EXTERNALID) {
+ if(tokenizer.ttype != StreamTokenizer.TT_WORD) {
+ throw new AbortException("Expected word token, got: " + tokenizer.toString());
}
- else if(etyp[out] == TypeUtil.EXTERNALID) {
- bundle.appendColumn(new SimpleTypeInformation<ExternalID>(ExternalID.class, names.get(out)), new ArrayList<ExternalID>());
+ data[out] = new ExternalID(tokenizer.sval);
+ nextToken(tokenizer);
+ }
+ else if(etyp[out] == TypeUtil.CLASSLABEL) {
+ if(tokenizer.ttype != StreamTokenizer.TT_WORD) {
+ throw new AbortException("Expected word token, got: " + tokenizer.toString());
}
- else if(etyp[out] == TypeUtil.CLASSLABEL) {
- bundle.appendColumn(new SimpleTypeInformation<ClassLabel>(ClassLabel.class, names.get(out)), new ArrayList<ClassLabel>());
+ // TODO: support other class label types.
+ ClassLabel lbl = new SimpleClassLabel(tokenizer.sval);
+ data[out] = lbl;
+ nextToken(tokenizer);
+ }
+ else {
+ throw new AbortException("Unsupported type for column " + "->" + out + ": " + ((etyp[out] != null) ? etyp[out].toString() : "null"));
+ }
+ }
+ return data;
+ }
+
+ /**
+ * Make a StreamTokenizer for the ARFF format.
+ *
+ * @param br Buffered reader
+ * @return Tokenizer
+ */
+ private StreamTokenizer makeArffTokenizer(BufferedReader br) {
+ // Setup tokenizer
+ StreamTokenizer tokenizer = new StreamTokenizer(br);
+ {
+ tokenizer.whitespaceChars(0, ' ');
+ tokenizer.wordChars(' ' + 1, '\u00FF');
+ tokenizer.whitespaceChars(',', ',');
+ tokenizer.commentChar('%');
+ tokenizer.quoteChar('"');
+ tokenizer.quoteChar('\'');
+ tokenizer.ordinaryChar('{');
+ tokenizer.ordinaryChar('}');
+ tokenizer.eolIsSignificant(true);
+ }
+ return tokenizer;
+ }
+
+ /**
+ * Setup the headers for the object bundle.
+ *
+ * @param names Attribute names
+ * @param targ Target columns
+ * @param etyp ELKI type information
+ * @param dimsize Number of dimensions in the individual types
+ * @param bundle Output bundle
+ * @param sparse Flag to create sparse vectors
+ */
+ private void setupBundleHeaders(ArrayList<String> names, int[] targ, TypeInformation[] etyp, int[] dimsize, MultipleObjectsBundle bundle, boolean sparse) {
+ for(int in = 0, out = 0; in < targ.length; out++) {
+ int nin = in + 1;
+ for(; nin < targ.length; nin++) {
+ if(targ[nin] != targ[in]) {
+ break;
+ }
+ }
+ if(etyp[out] == TypeUtil.NUMBER_VECTOR_FIELD) {
+ String[] labels = new String[dimsize[out]];
+ // Collect labels:
+ for(int i = 0; i < dimsize[out]; i++) {
+ labels[i] = names.get(out + i);
+ }
+ if(!sparse) {
+ VectorFieldTypeInformation<DoubleVector> type = new VectorFieldTypeInformation<DoubleVector>(DoubleVector.class, dimsize[out], labels, new DoubleVector(new double[dimsize[out]]));
+ bundle.appendColumn(type, new ArrayList<DoubleVector>());
}
else {
- throw new AbortException("Unsupported type for column " + in + "->" + out + ": " + ((etyp[out] != null) ? etyp[out].toString() : "null"));
+ Map<Integer, Float> empty = Collections.emptyMap();
+ VectorFieldTypeInformation<SparseFloatVector> type = new VectorFieldTypeInformation<SparseFloatVector>(SparseFloatVector.class, dimsize[out], labels, new SparseFloatVector(empty, dimsize[out]));
+ bundle.appendColumn(type, new ArrayList<SparseFloatVector>());
}
- assert (out == bundle.metaLength() - 1);
- // logger.warning("Added meta: " + bundle.meta(bundle.metaLength() -
- // 1));
- in = nin;
- }
- // Setup tokenizer
- StreamTokenizer tokenizer = new StreamTokenizer(br);
- {
- tokenizer.whitespaceChars(0, ' ');
- tokenizer.wordChars(' ' + 1, '\u00FF');
- tokenizer.whitespaceChars(',', ',');
- tokenizer.commentChar('%');
- tokenizer.quoteChar('"');
- tokenizer.quoteChar('\'');
- tokenizer.ordinaryChar('{');
- tokenizer.ordinaryChar('}');
- tokenizer.eolIsSignificant(true);
- }
-
- final int outdim = bundle.metaLength();
- nextToken(tokenizer);
- while(tokenizer.ttype != StreamTokenizer.TT_EOF) {
- // Parse instance
- if(tokenizer.ttype == StreamTokenizer.TT_EOL) {
- // ignore empty lines
+ }
+ else if(etyp[out] == TypeUtil.LABELLIST) {
+ String label = names.get(out);
+ for(int i = 1; i < dimsize[out]; i++) {
+ label = label + " " + names.get(out + i);
}
- else if(tokenizer.ttype != '{') {
- // logger.warning("Regular instance.");
- Object[] data = new Object[outdim];
- for(int out = 0; out < outdim; out++) {
- if(etyp[out] == TypeUtil.NUMBER_VECTOR_FIELD) {
- double[] cur = new double[dims[out]];
- for(int k = 0; k < dims[out]; k++) {
- if(tokenizer.ttype != StreamTokenizer.TT_NUMBER) {
- throw new AbortException("Expected word token, got: " + tokenizer.toString());
- }
- cur[k] = tokenizer.nval;
- nextToken(tokenizer);
- }
- data[out] = new DoubleVector(cur);
- }
- else if(etyp[out] == TypeUtil.LABELLIST) {
- LabelList ll = new LabelList();
- for(int k = 0; k < dims[out]; k++) {
- if(tokenizer.ttype != StreamTokenizer.TT_WORD) {
- throw new AbortException("Expected word token, got: " + tokenizer.toString());
- }
- ll.add(tokenizer.sval);
- nextToken(tokenizer);
- }
- data[out] = ll;
- }
- else if(etyp[out] == TypeUtil.EXTERNALID) {
- if(tokenizer.ttype != StreamTokenizer.TT_WORD) {
- throw new AbortException("Expected word token, got: " + tokenizer.toString());
- }
- data[out] = new ExternalID(tokenizer.sval);
- nextToken(tokenizer);
- }
- else if(etyp[out] == TypeUtil.CLASSLABEL) {
- if(tokenizer.ttype != StreamTokenizer.TT_WORD) {
- throw new AbortException("Expected word token, got: " + tokenizer.toString());
- }
- ClassLabel lbl = new SimpleClassLabel();
- lbl.init(tokenizer.sval);
- data[out] = lbl;
- nextToken(tokenizer);
- }
- else {
- throw new AbortException("Unsupported type for column " + "->" + out + ": " + ((etyp[out] != null) ? etyp[out].toString() : "null"));
- }
- }
- bundle.appendSimple(data);
+ bundle.appendColumn(new SimpleTypeInformation<LabelList>(LabelList.class, label), new ArrayList<LabelList>());
+ }
+ else if(etyp[out] == TypeUtil.EXTERNALID) {
+ bundle.appendColumn(new SimpleTypeInformation<ExternalID>(ExternalID.class, names.get(out)), new ArrayList<ExternalID>());
+ }
+ else if(etyp[out] == TypeUtil.CLASSLABEL) {
+ bundle.appendColumn(new SimpleTypeInformation<ClassLabel>(ClassLabel.class, names.get(out)), new ArrayList<ClassLabel>());
+ }
+ else {
+ throw new AbortException("Unsupported type for column " + in + "->" + out + ": " + ((etyp[out] != null) ? etyp[out].toString() : "null"));
+ }
+ assert (out == bundle.metaLength() - 1);
+ in = nin;
+ }
+ }
+
+ /**
+ * Read the dataset header part of the ARFF file, to ensure consistency.
+ *
+ * @param br Buffered Reader
+ * @throws IOException
+ */
+ private void readHeader(BufferedReader br) throws IOException {
+ String line;
+ // Locate header line
+ while(true) {
+ line = br.readLine();
+ if(line == null) {
+ throw new AbortException(ARFF_HEADER_RELATION + " not found in file.");
+ }
+ // Skip comments and empty lines
+ if(ARFF_COMMENT.matcher(line).matches() || EMPTY.matcher(line).matches()) {
+ continue;
+ }
+ // Break on relation statement
+ if(ARFF_HEADER_RELATION.matcher(line).matches()) {
+ break;
+ }
+ throw new AbortException("Expected relation declaration: " + line);
+ }
+ }
+
+ /**
+ * Parse the "@attribute" section of the ARFF file.
+ *
+ * @param br Input
+ * @param names List (to fill) of attribute names
+ * @param types List (to fill) of attribute types
+ * @throws IOException
+ */
+ private void parseAttributeStatements(BufferedReader br, ArrayList<String> names, ArrayList<String> types) throws IOException {
+ String line;
+ // Load attribute metadata
+ while(true) {
+ line = br.readLine();
+ if(line == null) {
+ throw new AbortException(ARFF_HEADER_DATA + " not found in file.");
+ }
+ // Skip comments and empty lines
+ if(ARFF_COMMENT.matcher(line).matches() || EMPTY.matcher(line).matches()) {
+ continue;
+ }
+ // Break on data statement to continue
+ if(ARFF_HEADER_DATA.matcher(line).matches()) {
+ break;
+ }
+ // Expect an attribute specification
+ Matcher matcher = ARFF_HEADER_ATTRIBUTE.matcher(line);
+ if(matcher.matches()) {
+ String name = matcher.group(1);
+ if(name.charAt(0) == '\'' && name.charAt(name.length() - 1) == '\'') {
+ name = name.substring(1, name.length() - 1);
+ }
+ else if(name.charAt(0) == '"' && name.charAt(name.length() - 1) == '"') {
+ name = name.substring(1, name.length() - 1);
+ }
+ String type = matcher.group(2);
+ names.add(name);
+ types.add(type);
+ // logger.warning("Attribute name: " + name + " type: " + type);
+ continue;
+ }
+ throw new AbortException("Unrecognized line: " + line);
+ }
+ assert (names.size() == types.size());
+ }
+
+ /**
+ * Process the column types (and names!) into ELKI relation style. Note that
+ * this will for example merge successive numerical columns into a single
+ * vector.
+ *
+ * @param names Attribute names
+ * @param types Attribute types
+ * @param targ Target dimension mapping (ARFF to ELKI), return value
+ * @param etyp ELKI type information, return value
+ * @param dims Number of successive dimensions, return value
+ */
+ private void processColumnTypes(ArrayList<String> names, ArrayList<String> types, int[] targ, TypeInformation[] etyp, int[] dims) {
+ int next = 0;
+ for(int i = 0; i < targ.length; i++) {
+ if(magic_eid != null && magic_eid.matcher(names.get(i)).matches()) {
+ // Turn into an external ID column.
+ targ[i] = next;
+ etyp[next] = TypeUtil.EXTERNALID;
+ dims[next] = 1;
+ next++;
+ continue;
+ }
+ else if(magic_class != null && magic_class.matcher(names.get(i)).matches()) {
+ // Type as ClassLabel
+ targ[i] = next;
+ etyp[next] = TypeUtil.CLASSLABEL;
+ dims[next] = 1;
+ next++;
+ continue;
+ }
+ else if(ARFF_NUMERIC.matcher(types.get(i)).matches()) {
+ // Create a number vector field
+ if(next > 0 && etyp[next - 1] == TypeUtil.NUMBER_VECTOR_FIELD) {
+ targ[i] = next - 1;
+ dims[next - 1]++;
+ continue;
}
else {
- logger.warning("Sparse instance.");
- while(true) {
- nextToken(tokenizer);
- assert (tokenizer.ttype != StreamTokenizer.TT_EOF && tokenizer.ttype != StreamTokenizer.TT_EOL);
- if(tokenizer.ttype == '}') {
- nextToken(tokenizer);
- assert (tokenizer.ttype == StreamTokenizer.TT_EOF || tokenizer.ttype == StreamTokenizer.TT_EOL);
- break;
- }
- else {
- // sparse token
- }
- }
- throw new AbortException("Sparse ARFF are not (yet) supported.");
+ targ[i] = next;
+ etyp[next] = TypeUtil.NUMBER_VECTOR_FIELD;
+ dims[next] = 1;
+ next++;
+ continue;
}
- if(tokenizer.ttype != StreamTokenizer.TT_EOF) {
- nextToken(tokenizer);
+ }
+ else {
+ // Use LabelList
+ if(next > 0 && etyp[next - 1] == TypeUtil.LABELLIST) {
+ targ[i] = next - 1;
+ dims[next - 1]++;
+ continue;
+ }
+ else {
+ targ[i] = next;
+ etyp[next] = TypeUtil.LABELLIST;
+ dims[next] = 1;
+ next++;
+ continue;
}
}
- return bundle;
- }
- catch(IOException e) {
- throw new AbortException("IO error in parser", e);
}
}
+ /**
+ * Helper function for token handling.
+ *
+ * @param tokenizer Tokenizer
+ * @throws IOException
+ */
private void nextToken(StreamTokenizer tokenizer) throws IOException {
tokenizer.nextToken();
if((tokenizer.ttype == '\'') || (tokenizer.ttype == '"')) {
@@ -368,4 +601,51 @@ public class ArffParser implements Parser {
logger.debug("token type: " + tokenizer.ttype);
}
}
+
+ /**
+ * Parameterization class.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ public static class Parameterizer extends AbstractParameterizer {
+ /**
+ * Pattern for recognizing external ID attributes.
+ */
+ public static final OptionID MAGIC_EID_ID = OptionID.getOrCreateOptionID("arff.externalid", "Pattern to recognize external ID attributes.");
+
+ /**
+ * Pattern for recognizing class label attributes.
+ */
+ public static final OptionID MAGIC_CLASS_ID = OptionID.getOrCreateOptionID("arff.classlabel", "Pattern to recognize class label attributes.");
+
+ /**
+ * Pattern to recognize external ids
+ */
+ Pattern magic_eid;
+
+ /**
+ * Pattern to recognize class label columns
+ */
+ Pattern magic_class;
+
+ @Override
+ protected void makeOptions(Parameterization config) {
+ super.makeOptions(config);
+ PatternParameter eidP = new PatternParameter(MAGIC_EID_ID, DEFAULT_ARFF_MAGIC_EID);
+ if(config.grab(eidP)) {
+ magic_eid = eidP.getValue();
+ }
+ PatternParameter classP = new PatternParameter(MAGIC_CLASS_ID, DEFAULT_ARFF_MAGIC_CLASS);
+ if(config.grab(classP)) {
+ magic_class = classP.getValue();
+ }
+ }
+
+ @Override
+ protected ArffParser makeInstance() {
+ return new ArffParser(magic_eid, magic_class);
+ }
+ }
} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/AbstractDatabaseDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/AbstractDatabaseDistanceFunction.java
index e1055816..22e0cbc3 100644
--- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/AbstractDatabaseDistanceFunction.java
+++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/AbstractDatabaseDistanceFunction.java
@@ -32,6 +32,8 @@ import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
*
* @author Elke Achtert
*
+ * @apiviz.has AbstractDatabaseDistanceFunction.Instance
+ *
* @param <O> the type of DatabaseObject to compute the distances in between
* @param <D> the type of Distance used
*/
diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/AbstractIndexBasedDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/AbstractIndexBasedDistanceFunction.java
index 97280ba6..dfefb355 100644
--- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/AbstractIndexBasedDistanceFunction.java
+++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/AbstractIndexBasedDistanceFunction.java
@@ -38,6 +38,9 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ObjectParameter;
*
* @author Elke Achtert
*
+ * @apiviz.has AbstractIndexBasedDistanceFunction.Instance
+ * @apiviz.composedOf IndexFactory
+ *
* @param <O> the type of object to compute the distances in between
* @param <I> the type of Index used
* @param <D> the type of Distance used
diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/AbstractVectorDoubleDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/AbstractVectorDoubleDistanceFunction.java
index b06d1fbc..4bc2a381 100644
--- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/AbstractVectorDoubleDistanceFunction.java
+++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/AbstractVectorDoubleDistanceFunction.java
@@ -35,6 +35,8 @@ import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance;
* @author Erich Schubert
*
* @apiviz.landmark
+ * @apiviz.uses NumberVector
+ * @apiviz.has DoubleDistance
*/
public abstract class AbstractVectorDoubleDistanceFunction extends AbstractPrimitiveDistanceFunction<NumberVector<?, ?>, DoubleDistance> implements PrimitiveDoubleDistanceFunction<NumberVector<?, ?>> {
/**
diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/MinKDistance.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/MinKDistance.java
index 76717626..9c03134c 100644
--- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/MinKDistance.java
+++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/MinKDistance.java
@@ -63,6 +63,9 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ObjectParameter;
*
* @author Erich Schubert
*
+ * @apiviz.uses DistanceFunction
+ * @apiviz.has MinKDistance.Instance
+ *
* @param <O> Database object type
* @param <D> Distance type
*/
@@ -121,6 +124,8 @@ public class MinKDistance<O, D extends Distance<D>> extends AbstractDatabaseDist
* Instance for an actual database.
*
* @author Erich Schubert
+ *
+ * @apiviz.uses KNNQuery
*/
public class Instance<T extends O> extends AbstractDatabaseDistanceQuery<T, D> {
/**
diff --git a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/SharedNearestNeighborJaccardDistanceFunction.java b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/SharedNearestNeighborJaccardDistanceFunction.java
index 99f6ec56..0b80f512 100644
--- a/src/de/lmu/ifi/dbs/elki/distance/distancefunction/SharedNearestNeighborJaccardDistanceFunction.java
+++ b/src/de/lmu/ifi/dbs/elki/distance/distancefunction/SharedNearestNeighborJaccardDistanceFunction.java
@@ -39,8 +39,8 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameteriz
*
* @author Erich Schubert
*
- * @apiviz.has de.lmu.ifi.dbs.elki.index.preprocessed.snn.SharedNearestNeighborIndex.Factory
- * @apiviz.uses Instance oneway - - «create»
+ * @apiviz.composedOf de.lmu.ifi.dbs.elki.index.preprocessed.snn.SharedNearestNeighborIndex.Factory
+ * @apiviz.has SharedNearestNeighborJaccardDistanceFunction.Instance oneway - - «create»
*
* @param <O> object type
*/
diff --git a/src/de/lmu/ifi/dbs/elki/gui/configurator/ClassListParameterConfigurator.java b/src/de/lmu/ifi/dbs/elki/gui/configurator/ClassListParameterConfigurator.java
index e75a6f93..7be929b2 100644
--- a/src/de/lmu/ifi/dbs/elki/gui/configurator/ClassListParameterConfigurator.java
+++ b/src/de/lmu/ifi/dbs/elki/gui/configurator/ClassListParameterConfigurator.java
@@ -47,6 +47,14 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.TrackParame
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ClassListParameter;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.Parameter;
+/**
+ * Provide a configuration panel to choose classes with the help of a dropdown.
+ * Additionally, the classes can in turn have additional parameters.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.uses ClassListParameter
+ */
public class ClassListParameterConfigurator extends AbstractSingleParameterConfigurator<ClassListParameter<?>> implements ActionListener, ChangeListener {
final ConfiguratorPanel child;
diff --git a/src/de/lmu/ifi/dbs/elki/gui/configurator/ClassParameterConfigurator.java b/src/de/lmu/ifi/dbs/elki/gui/configurator/ClassParameterConfigurator.java
index 98e52444..34580f16 100644
--- a/src/de/lmu/ifi/dbs/elki/gui/configurator/ClassParameterConfigurator.java
+++ b/src/de/lmu/ifi/dbs/elki/gui/configurator/ClassParameterConfigurator.java
@@ -40,6 +40,14 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.TrackParame
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ClassParameter;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.Parameter;
+/**
+ * Provide a configuration panel to choose a class with the help of a dropdown.
+ * Additionally, the classes can in turn have additional parameters.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.uses ClassParameter
+ */
public class ClassParameterConfigurator extends AbstractSingleParameterConfigurator<ClassParameter<?>> implements ActionListener, ChangeListener {
final JComboBox value;
diff --git a/src/de/lmu/ifi/dbs/elki/gui/configurator/ConfiguratorPanel.java b/src/de/lmu/ifi/dbs/elki/gui/configurator/ConfiguratorPanel.java
index a4cf6977..5be0da35 100644
--- a/src/de/lmu/ifi/dbs/elki/gui/configurator/ConfiguratorPanel.java
+++ b/src/de/lmu/ifi/dbs/elki/gui/configurator/ConfiguratorPanel.java
@@ -38,6 +38,7 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.ListParamet
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.TrackParameters;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ClassListParameter;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ClassParameter;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.EnumParameter;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.FileParameter;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.Flag;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.Parameter;
@@ -125,6 +126,9 @@ public class ConfiguratorPanel extends JPanel implements ChangeListener {
if(param instanceof FileParameter) {
return new FileParameterConfigurator((FileParameter) param, this);
}
+ if(param instanceof EnumParameter) {
+ return new EnumParameterConfigurator((EnumParameter<?>) param, this);
+ }
return new TextParameterConfigurator(param, this);
}
diff --git a/src/de/lmu/ifi/dbs/elki/gui/configurator/EnumParameterConfigurator.java b/src/de/lmu/ifi/dbs/elki/gui/configurator/EnumParameterConfigurator.java
new file mode 100644
index 00000000..ad12b7ce
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/gui/configurator/EnumParameterConfigurator.java
@@ -0,0 +1,104 @@
+package de.lmu.ifi.dbs.elki.gui.configurator;
+
+/*
+ This file is part of ELKI:
+ Environment for Developing KDD-Applications Supported by Index-Structures
+
+ Copyright (C) 2011
+ Ludwig-Maximilians-Universität München
+ Lehr- und Forschungseinheit für Datenbanksysteme
+ ELKI Development Team
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+import java.awt.GridBagConstraints;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+
+import javax.swing.JComboBox;
+import javax.swing.JComponent;
+
+import de.lmu.ifi.dbs.elki.gui.util.DynamicParameters;
+import de.lmu.ifi.dbs.elki.logging.LoggingUtil;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.EnumParameter;
+
+/**
+ * Panel to configure EnumParameters by offering a dropdown to choose from.
+ *
+ * TODO: offer radio buttons when just a few choices are available?
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.uses EnumParameter
+ */
+public class EnumParameterConfigurator extends AbstractSingleParameterConfigurator<EnumParameter<?>> implements ActionListener {
+ final JComboBox value;
+
+ public EnumParameterConfigurator(EnumParameter<?> cp, JComponent parent) {
+ super(cp, parent);
+ // Input field
+ {
+ GridBagConstraints constraints = new GridBagConstraints();
+ constraints.fill = GridBagConstraints.HORIZONTAL;
+ constraints.weightx = 1.0;
+ value = new JComboBox();
+ value.setToolTipText(param.getShortDescription());
+ value.setPrototypeDisplayValue(cp.getPossibleValues().iterator().next());
+ parent.add(value, constraints);
+ finishGridRow();
+ }
+
+ if(!param.tookDefaultValue() && param.isDefined() && param.getGivenValue() != null) {
+ value.addItem(param.getValueAsString());
+ value.setSelectedIndex(0);
+ }
+
+ // For parameters with a default value, offer using the default
+ // For optional parameters, offer not specifying them.
+ if(cp.hasDefaultValue()) {
+ value.addItem(DynamicParameters.STRING_USE_DEFAULT + " " + cp.getDefaultValueAsString());
+ }
+ else if(cp.isOptional()) {
+ value.addItem(DynamicParameters.STRING_OPTIONAL);
+ }
+ // Offer the shorthand version of class names.
+ for(String s : cp.getPossibleValues()) {
+ value.addItem(s);
+ }
+ value.addActionListener(this);
+ }
+
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ if(e.getSource() == value) {
+ fireValueChanged();
+ }
+ else {
+ LoggingUtil.warning("actionPerformed triggered by unknown source: " + e.getSource());
+ }
+ }
+
+ @Override
+ public String getUserInput() {
+ String val = (String) value.getSelectedItem();
+ if(val.startsWith(DynamicParameters.STRING_USE_DEFAULT)) {
+ return null;
+ }
+ if(val == DynamicParameters.STRING_OPTIONAL) {
+ return null;
+ }
+ return val;
+ }
+} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/gui/configurator/FileParameterConfigurator.java b/src/de/lmu/ifi/dbs/elki/gui/configurator/FileParameterConfigurator.java
index add20f69..fd7168d3 100644
--- a/src/de/lmu/ifi/dbs/elki/gui/configurator/FileParameterConfigurator.java
+++ b/src/de/lmu/ifi/dbs/elki/gui/configurator/FileParameterConfigurator.java
@@ -39,6 +39,13 @@ import de.lmu.ifi.dbs.elki.gui.icons.StockIcon;
import de.lmu.ifi.dbs.elki.logging.LoggingUtil;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.FileParameter;
+/**
+ * Provide a configuration panel to choose a file with a file selector button.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.uses FileParameter
+ */
public class FileParameterConfigurator extends AbstractSingleParameterConfigurator<FileParameter> implements ActionListener {
/**
* The panel to store the components
diff --git a/src/de/lmu/ifi/dbs/elki/gui/configurator/FlagParameterConfigurator.java b/src/de/lmu/ifi/dbs/elki/gui/configurator/FlagParameterConfigurator.java
index 49fc0a13..15a4506f 100644
--- a/src/de/lmu/ifi/dbs/elki/gui/configurator/FlagParameterConfigurator.java
+++ b/src/de/lmu/ifi/dbs/elki/gui/configurator/FlagParameterConfigurator.java
@@ -33,6 +33,13 @@ import javax.swing.JComponent;
import de.lmu.ifi.dbs.elki.logging.LoggingUtil;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.Flag;
+/**
+ * Provide a configuration panel to modify a boolean via a checkbox.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.uses Flag
+ */
public class FlagParameterConfigurator extends AbstractParameterConfigurator<Flag> implements ActionListener {
final JCheckBox value;
diff --git a/src/de/lmu/ifi/dbs/elki/gui/configurator/TextParameterConfigurator.java b/src/de/lmu/ifi/dbs/elki/gui/configurator/TextParameterConfigurator.java
index 5a9848aa..3bf3dbb2 100644
--- a/src/de/lmu/ifi/dbs/elki/gui/configurator/TextParameterConfigurator.java
+++ b/src/de/lmu/ifi/dbs/elki/gui/configurator/TextParameterConfigurator.java
@@ -34,6 +34,13 @@ import javax.swing.JTextField;
import de.lmu.ifi.dbs.elki.logging.LoggingUtil;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.Parameter;
+/**
+ * Provide a configuration panel to input an arbitrary text parameter.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.uses ClassParameter
+ */
// FIXME: update on focus loss?
// FIXME: restrictions for number input?
public class TextParameterConfigurator extends AbstractSingleParameterConfigurator<Parameter<?, ?>> implements ActionListener {
diff --git a/src/de/lmu/ifi/dbs/elki/gui/multistep/MultiStepGUI.java b/src/de/lmu/ifi/dbs/elki/gui/multistep/MultiStepGUI.java
index ae550837..49745002 100644
--- a/src/de/lmu/ifi/dbs/elki/gui/multistep/MultiStepGUI.java
+++ b/src/de/lmu/ifi/dbs/elki/gui/multistep/MultiStepGUI.java
@@ -58,12 +58,12 @@ import de.lmu.ifi.dbs.elki.workflow.OutputStep;
* @author Erich Schubert
*
* @apiviz.landmark
- * @apiviz.composedOf SettingsComboboxModel
* @apiviz.composedOf AlgorithmTabPanel
* @apiviz.composedOf EvaluationTabPanel
* @apiviz.composedOf InputTabPanel
* @apiviz.composedOf LoggingTabPanel
* @apiviz.composedOf OutputTabPanel
+ * @apiviz.composedOf SavedSettingsTabPanel
*/
public class MultiStepGUI extends JPanel {
/**
diff --git a/src/de/lmu/ifi/dbs/elki/gui/multistep/panels/SavedSettingsTabPanel.java b/src/de/lmu/ifi/dbs/elki/gui/multistep/panels/SavedSettingsTabPanel.java
index 147943eb..ab7fc852 100644
--- a/src/de/lmu/ifi/dbs/elki/gui/multistep/panels/SavedSettingsTabPanel.java
+++ b/src/de/lmu/ifi/dbs/elki/gui/multistep/panels/SavedSettingsTabPanel.java
@@ -46,6 +46,8 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.SerializedP
* Tab panel to manage saved settings.
*
* @author Erich Schubert
+ *
+ * @apiviz.composedOf SavedSettingsTabPanel.SettingsComboboxModel
*/
public class SavedSettingsTabPanel extends JPanel {
/**
diff --git a/src/de/lmu/ifi/dbs/elki/gui/util/ParameterTable.java b/src/de/lmu/ifi/dbs/elki/gui/util/ParameterTable.java
index ea41213a..fc7deac8 100644
--- a/src/de/lmu/ifi/dbs/elki/gui/util/ParameterTable.java
+++ b/src/de/lmu/ifi/dbs/elki/gui/util/ParameterTable.java
@@ -50,6 +50,7 @@ import javax.swing.table.TableColumn;
import de.lmu.ifi.dbs.elki.logging.LoggingUtil;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ClassListParameter;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ClassParameter;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.EnumParameter;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.FileParameter;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.Flag;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.Parameter;
@@ -255,6 +256,19 @@ public class ParameterTable extends JTable {
comboBox.addItem(Flag.NOT_SET);
}
}
+ // and for Enum parameters.
+ else if (option instanceof EnumParameter<?>) {
+ EnumParameter<?> ep = (EnumParameter<?>) option;
+ for (String s : ep.getPossibleValues()) {
+ if (ep.hasDefaultValue() && ep.getDefaultValueAsString().equals(s)) {
+ if (!(DynamicParameters.STRING_USE_DEFAULT + " " + ep.getDefaultValueAsString()).equals(val)) {
+ comboBox.addItem(DynamicParameters.STRING_USE_DEFAULT + " " + s);
+ }
+ } else if (!s.equals(val)) {
+ comboBox.addItem(s);
+ }
+ }
+ }
// No completion for others
}
return c;
@@ -616,6 +630,10 @@ public class ParameterTable extends JTable {
activeEditor = fileNameEditor;
return fileNameEditor.getTableCellEditorComponent(table, value, isSelected, row, column);
}
+ if(option instanceof EnumParameter<?>) {
+ activeEditor = dropdownEditor;
+ return dropdownEditor.getTableCellEditorComponent(table, value, isSelected, row, column);
+ }
}
activeEditor = plaintextEditor;
return plaintextEditor.getTableCellEditorComponent(table, value, isSelected, row, column);
diff --git a/src/de/lmu/ifi/dbs/elki/index/IndexFactory.java b/src/de/lmu/ifi/dbs/elki/index/IndexFactory.java
index c09f579b..b1eb649b 100644
--- a/src/de/lmu/ifi/dbs/elki/index/IndexFactory.java
+++ b/src/de/lmu/ifi/dbs/elki/index/IndexFactory.java
@@ -33,7 +33,7 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.Parameterizable;
* @author Erich Schubert
*
* @apiviz.stereotype factory,interface
- * @apiviz.uses Index oneway - - «create»
+ * @apiviz.has Index oneway - - «create»
*
* @param <V> Input object type
* @param <I> Index type
diff --git a/src/de/lmu/ifi/dbs/elki/index/preprocessed/AbstractPreprocessorIndex.java b/src/de/lmu/ifi/dbs/elki/index/preprocessed/AbstractPreprocessorIndex.java
index 6ae84286..4b6fbe3a 100644
--- a/src/de/lmu/ifi/dbs/elki/index/preprocessed/AbstractPreprocessorIndex.java
+++ b/src/de/lmu/ifi/dbs/elki/index/preprocessed/AbstractPreprocessorIndex.java
@@ -34,6 +34,8 @@ import de.lmu.ifi.dbs.elki.logging.Logging;
*
* @author Erich Schubert
*
+ * @apiviz.composedOf WritableDataStore
+ *
* @param <O> Object type
* @param <R> Stored data type
*/
diff --git a/src/de/lmu/ifi/dbs/elki/index/preprocessed/LocalProjectionIndex.java b/src/de/lmu/ifi/dbs/elki/index/preprocessed/LocalProjectionIndex.java
index 9bcbe9ce..8b4272d5 100644
--- a/src/de/lmu/ifi/dbs/elki/index/preprocessed/LocalProjectionIndex.java
+++ b/src/de/lmu/ifi/dbs/elki/index/preprocessed/LocalProjectionIndex.java
@@ -55,7 +55,7 @@ public interface LocalProjectionIndex<V extends NumberVector<?, ?>, P extends Pr
* @author Erich Schubert
*
* @apiviz.stereotype factory
- * @apiviz.uses LocalProjectionIndex oneway - - «create»
+ * @apiviz.has LocalProjectionIndex oneway - - «create»
*
* @param <V> Vector type
* @param <I> Index type
diff --git a/src/de/lmu/ifi/dbs/elki/index/preprocessed/preference/DiSHPreferenceVectorIndex.java b/src/de/lmu/ifi/dbs/elki/index/preprocessed/preference/DiSHPreferenceVectorIndex.java
index 09ba95b3..8626e5b7 100644
--- a/src/de/lmu/ifi/dbs/elki/index/preprocessed/preference/DiSHPreferenceVectorIndex.java
+++ b/src/de/lmu/ifi/dbs/elki/index/preprocessed/preference/DiSHPreferenceVectorIndex.java
@@ -65,12 +65,11 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.OptionID;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.ParameterException;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.WrongParameterValueException;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.constraints.EqualStringConstraint;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.constraints.GreaterConstraint;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.DoubleListParameter;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.EnumParameter;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.IntParameter;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.StringParameter;
/**
* Preprocessor for DiSH preference vector assignment to objects of a certain
@@ -607,19 +606,9 @@ public class DiSHPreferenceVectorIndex<V extends NumberVector<?, ?>> extends Abs
}
// parameter strategy
- final StringParameter strategyP = new StringParameter(STRATEGY_ID, DEFAULT_STRATEGY.toString());
- strategyP.addConstraint(new EqualStringConstraint(new String[] { Strategy.APRIORI.toString(), Strategy.MAX_INTERSECTION.toString() }));
+ final EnumParameter<Strategy> strategyP = new EnumParameter<Strategy>(STRATEGY_ID, Strategy.class, DEFAULT_STRATEGY);
if(config.grab(strategyP)) {
- String strategyString = strategyP.getValue();
- if(strategyString.equals(Strategy.APRIORI.toString())) {
- strategy = Strategy.APRIORI;
- }
- else if(strategyString.equals(Strategy.MAX_INTERSECTION.toString())) {
- strategy = Strategy.MAX_INTERSECTION;
- }
- else {
- config.reportError(new WrongParameterValueException(strategyP, strategyString));
- }
+ strategy = strategyP.getValue();
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/DistanceEntry.java b/src/de/lmu/ifi/dbs/elki/index/tree/DistanceEntry.java
index 63aa5978..b7bf3e0c 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/DistanceEntry.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/DistanceEntry.java
@@ -30,6 +30,10 @@ import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
* belonging to this entry.
*
* @author Elke Achtert
+ *
+ * @apiviz.composedOf Distance
+ * @apiviz.uses Entry
+ *
* @param <E> the type of Entry used in the index
* @param <D> the type of Distance used
*/
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/IndexTree.java b/src/de/lmu/ifi/dbs/elki/index/tree/IndexTree.java
index f16b0e0e..fa9c0e0a 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/IndexTree.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/IndexTree.java
@@ -33,6 +33,7 @@ import de.lmu.ifi.dbs.elki.utilities.exceptions.AbortException;
*
* @author Elke Achtert
*
+ * @apiviz.composedOf PageFile
* @apiviz.has Node oneway - - contains
* @apiviz.has TreeIndexHeader oneway
*
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/IndexTreePath.java b/src/de/lmu/ifi/dbs/elki/index/tree/IndexTreePath.java
index c8fa3e82..feb134e3 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/IndexTreePath.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/IndexTreePath.java
@@ -33,6 +33,7 @@ import java.util.List;
* @author Elke Achtert
*
* @apiviz.composedOf TreeIndexPathComponent
+ * @apiviz.uses Entry
*
* @param <E> the type of Entry used in the index
*/
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/TreeIndexFactory.java b/src/de/lmu/ifi/dbs/elki/index/tree/TreeIndexFactory.java
index fc479cba..b55700ec 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/TreeIndexFactory.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/TreeIndexFactory.java
@@ -46,11 +46,12 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.LongParameter;
* @author Erich Schubert
*
* @apiviz.stereotype factory,interface
- * @apiviz.uses Index oneway - - «create»
+ * @apiviz.has Index oneway - - «create»
*
* @param <O> Object type
* @param <I> Index type
*/
+// TODO: actually, this class should be called PagedIndexFactory?
public abstract class TreeIndexFactory<O, I extends Index> implements IndexFactory<O, I> {
/**
* Optional parameter that specifies the name of the file storing the index.
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/TreeIndexPathComponent.java b/src/de/lmu/ifi/dbs/elki/index/tree/TreeIndexPathComponent.java
index 1cc170f3..2309c7e5 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/TreeIndexPathComponent.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/TreeIndexPathComponent.java
@@ -30,6 +30,9 @@ package de.lmu.ifi.dbs.elki.index.tree;
* index of the component in its parent.
*
* @author Elke Achtert
+ *
+ * @apiviz.uses Entry oneway - - «references»
+ *
* @param <E> the type of Entry used in the index
*/
public class TreeIndexPathComponent<E extends Entry> {
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkapp/MkAppEntry.java b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkapp/MkAppEntry.java
index cc56d1fb..ef50e3bc 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkapp/MkAppEntry.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkapp/MkAppEntry.java
@@ -32,10 +32,10 @@ import de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.MTreeEntry;
* provided.
*
* @author Elke Achtert
+ *
+ * @apiviz.composedOf PolynomialApproximation
*/
-
interface MkAppEntry<D extends NumberDistance<D, ?>> extends MTreeEntry<D> {
-
/**
* Returns the approximated value at the specified k.
*
@@ -57,4 +57,4 @@ interface MkAppEntry<D extends NumberDistance<D, ?>> extends MTreeEntry<D> {
* @param approximation the polynomial approximation to be set
*/
public void setKnnDistanceApproximation(PolynomialApproximation approximation);
-}
+} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkcop/ConvexHull.java b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkcop/ConvexHull.java
index d87986cb..7924c13d 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkcop/ConvexHull.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkcop/ConvexHull.java
@@ -23,7 +23,6 @@ package de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.mktrees.mkcop;
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-
/**
* Holds the lower and upper hull for some values.
*
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkcop/MkCoPEntry.java b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkcop/MkCoPEntry.java
index bdc83f17..cd1155c3 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkcop/MkCoPEntry.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkcop/MkCoPEntry.java
@@ -28,19 +28,21 @@ import de.lmu.ifi.dbs.elki.distance.distancevalue.NumberDistance;
import de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.MTreeEntry;
/**
- * Defines the requirements for an entry in an MkCop-Tree node.
- * Additionally to an entry in an M-Tree conservative approximation of the
- * knn distances is provided.
- *
- * @author Elke Achtert
+ * Defines the requirements for an entry in an MkCop-Tree node. Additionally to
+ * an entry in an M-Tree conservative approximation of the knn distances is
+ * provided.
+ *
+ * @author Elke Achtert
+ *
+ * @apiviz.composedOf ApproximationLine
*/
interface MkCoPEntry<D extends NumberDistance<D, ?>> extends MTreeEntry<D> {
/**
* Returns the conservative approximated knn distance of the entry.
- *
+ *
* @param <O> Object type
- * @param k the parameter k of the knn distance
+ * @param k the parameter k of the knn distance
* @param distanceFunction the distance function
* @return the conservative approximated knn distance of the entry
*/
@@ -48,15 +50,16 @@ interface MkCoPEntry<D extends NumberDistance<D, ?>> extends MTreeEntry<D> {
/**
* Returns the conservative approximation line.
- *
+ *
* @return the conservative approximation line
*/
public ApproximationLine getConservativeKnnDistanceApproximation();
/**
* Sets the conservative approximation line
- *
- * @param conservativeApproximation the conservative approximation line to be set
+ *
+ * @param conservativeApproximation the conservative approximation line to be
+ * set
*/
public void setConservativeKnnDistanceApproximation(ApproximationLine conservativeApproximation);
-}
+} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkcop/MkCoPTree.java b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkcop/MkCoPTree.java
index e6abc753..a2f684ad 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkcop/MkCoPTree.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkcop/MkCoPTree.java
@@ -57,6 +57,7 @@ import de.lmu.ifi.dbs.elki.utilities.datastructures.heap.UpdatableHeap;
* @author Elke Achtert
*
* @apiviz.has MkCoPTreeNode oneway - - contains
+ * @apiviz.uses ConvexHull
*
* @param <O> Object type
* @param <D> Distance type
diff --git a/src/de/lmu/ifi/dbs/elki/math/MathUtil.java b/src/de/lmu/ifi/dbs/elki/math/MathUtil.java
index f04fdef7..6856a44b 100644
--- a/src/de/lmu/ifi/dbs/elki/math/MathUtil.java
+++ b/src/de/lmu/ifi/dbs/elki/math/MathUtil.java
@@ -32,6 +32,11 @@ import de.lmu.ifi.dbs.elki.math.linearalgebra.Vector;
/**
* A collection of math related utility functions.
+ *
+ * @author Arthur Zimekt
+ * @author Erich Schubert
+ *
+ * @apiviz.landmark
*/
public final class MathUtil {
/**
diff --git a/src/de/lmu/ifi/dbs/elki/persistent/ByteArrayUtil.java b/src/de/lmu/ifi/dbs/elki/persistent/ByteArrayUtil.java
index 5b7c34df..f4959167 100644
--- a/src/de/lmu/ifi/dbs/elki/persistent/ByteArrayUtil.java
+++ b/src/de/lmu/ifi/dbs/elki/persistent/ByteArrayUtil.java
@@ -275,7 +275,7 @@ public final class ByteArrayUtil {
}
@Override
- public int getByteSize(@SuppressWarnings("unused") Byte object) {
+ public int getByteSize(Byte object) {
return getFixedByteSize();
}
@@ -309,7 +309,7 @@ public final class ByteArrayUtil {
}
@Override
- public int getByteSize(@SuppressWarnings("unused") Short object) {
+ public int getByteSize(Short object) {
return getFixedByteSize();
}
@@ -343,7 +343,7 @@ public final class ByteArrayUtil {
}
@Override
- public int getByteSize(@SuppressWarnings("unused") Integer object) {
+ public int getByteSize(Integer object) {
return getFixedByteSize();
}
@@ -377,7 +377,7 @@ public final class ByteArrayUtil {
}
@Override
- public int getByteSize(@SuppressWarnings("unused") Long object) {
+ public int getByteSize(Long object) {
return getFixedByteSize();
}
@@ -411,7 +411,7 @@ public final class ByteArrayUtil {
}
@Override
- public int getByteSize(@SuppressWarnings("unused") Float object) {
+ public int getByteSize(Float object) {
return getFixedByteSize();
}
@@ -445,7 +445,7 @@ public final class ByteArrayUtil {
}
@Override
- public int getByteSize(@SuppressWarnings("unused") Double object) {
+ public int getByteSize(Double object) {
return getFixedByteSize();
}
diff --git a/src/de/lmu/ifi/dbs/elki/properties/ELKI.properties b/src/de/lmu/ifi/dbs/elki/properties/ELKI.properties
index 905b1751..5c45ecfa 100644
--- a/src/de/lmu/ifi/dbs/elki/properties/ELKI.properties
+++ b/src/de/lmu/ifi/dbs/elki/properties/ELKI.properties
@@ -178,9 +178,9 @@ de.lmu.ifi.dbs.elki.data.images.ComputeColorHistogram=\
de.lmu.ifi.dbs.elki.data.images.ComputeNaiveRGBColorHistogram,\
# #######################################################
# Classlabel - default package: de.lmu.ifi.dbs.elki.data
-de.lmu.ifi.dbs.elki.data.ClassLabel=\
- de.lmu.ifi.dbs.elki.data.SimpleClassLabel,\
- de.lmu.ifi.dbs.elki.data.HierarchicalClassLabel,\
+de.lmu.ifi.dbs.elki.data.ClassLabel$Factory=\
+ de.lmu.ifi.dbs.elki.data.SimpleClassLabel$Factory,\
+ de.lmu.ifi.dbs.elki.data.HierarchicalClassLabel$Factory,\
# #######################################################
# Databases - default package: de.lmu.ifi.dbs.elki.database
de.lmu.ifi.dbs.elki.database.Database=\
@@ -195,11 +195,12 @@ de.lmu.ifi.dbs.elki.database.UpdatableDatabase=\
# Database connections - default package: de.lmu.ifi.dbs.elki.database.connection
de.lmu.ifi.dbs.elki.datasource.DatabaseConnection=\
de.lmu.ifi.dbs.elki.datasource.FileBasedDatabaseConnection,\
- de.lmu.ifi.dbs.elki.datasource.InputStreamDatabaseConnection,\
- de.lmu.ifi.dbs.elki.datasource.RandomDoubleVectorDatabaseConnection,\
- de.lmu.ifi.dbs.elki.datasource.LabelJoinDatabaseConnection,\
de.lmu.ifi.dbs.elki.datasource.ExternalIDJoinDatabaseConnection,\
+ de.lmu.ifi.dbs.elki.datasource.LabelJoinDatabaseConnection,\
+ de.lmu.ifi.dbs.elki.datasource.GeneratorXMLDatabaseConnection,\
+ de.lmu.ifi.dbs.elki.datasource.RandomDoubleVectorDatabaseConnection,\
de.lmu.ifi.dbs.elki.datasource.EmptyDatabaseConnection,\
+# de.lmu.ifi.dbs.elki.datasource.InputStreamDatabaseConnection,\
# #######################################################
# distance functions - default package: de.lmu.ifi.dbs.elki.distance.distancefunction
de.lmu.ifi.dbs.elki.distance.distancefunction.DistanceFunction=\
@@ -342,7 +343,7 @@ de.lmu.ifi.dbs.elki.distance.distancefunction.SpatialPrimitiveDoubleDistanceFunc
de.lmu.ifi.dbs.elki.distance.distancefunction.subspace.DimensionSelectingDistanceFunction,\
de.lmu.ifi.dbs.elki.distance.distancefunction.subspace.DimensionsSelectingEuclideanDistanceFunction,\
# #######################################################
-# preprocessor based distance functions functions - default package: de.lmu.ifi.dbs.elki.distance.distancefunction
+# preprocessor based distance functions - default package: de.lmu.ifi.dbs.elki.distance.distancefunction
de.lmu.ifi.dbs.elki.distance.distancefunction.AbstractIndexBasedDistanceFunction=\
de.lmu.ifi.dbs.elki.distance.distancefunction.LocallyWeightedDistanceFunction,\
de.lmu.ifi.dbs.elki.distance.distancefunction.SharedNearestNeighborJaccardDistanceFunction,\
@@ -352,6 +353,9 @@ de.lmu.ifi.dbs.elki.distance.distancefunction.AbstractIndexBasedDistanceFunction
de.lmu.ifi.dbs.elki.distance.distancefunction.subspace.DiSHDistanceFunction,\
de.lmu.ifi.dbs.elki.distance.distancefunction.subspace.HiSCDistanceFunction,\
# #######################################################
+# locally weighted distance functions - default package: de.lmu.ifi.dbs.elki.distance.distancefunction
+de.lmu.ifi.dbs.elki.distance.distancefunction.LocallyWeightedDistanceFunction=\
+# #######################################################
# distance parser - default package: de.lmu.ifi.dbs.elki.datasource.parser
de.lmu.ifi.dbs.elki.datasource.parser.DistanceParser=\
de.lmu.ifi.dbs.elki.datasource.parser.NumberDistanceParser,\
diff --git a/src/de/lmu/ifi/dbs/elki/result/DiscardResultHandler.java b/src/de/lmu/ifi/dbs/elki/result/DiscardResultHandler.java
index ee65e64e..486a47a9 100644
--- a/src/de/lmu/ifi/dbs/elki/result/DiscardResultHandler.java
+++ b/src/de/lmu/ifi/dbs/elki/result/DiscardResultHandler.java
@@ -23,8 +23,6 @@ package de.lmu.ifi.dbs.elki.result;
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-
-
/**
* A dummy result handler that discards the actual result, for use in
* benchmarks.
@@ -39,7 +37,6 @@ public class DiscardResultHandler implements ResultHandler {
// empty constructor
}
- @SuppressWarnings("unused")
@Override
public void processNewResult(HierarchicalResult baseResult, Result newResult) {
// always ignore the new result.
diff --git a/src/de/lmu/ifi/dbs/elki/result/ResultHierarchy.java b/src/de/lmu/ifi/dbs/elki/result/ResultHierarchy.java
index 101d6855..0ecf6f82 100644
--- a/src/de/lmu/ifi/dbs/elki/result/ResultHierarchy.java
+++ b/src/de/lmu/ifi/dbs/elki/result/ResultHierarchy.java
@@ -74,14 +74,12 @@ public class ResultHierarchy extends HierarchyHashmapList<Result> {
fireResultAdded(child, parent);
}
- @SuppressWarnings("unused")
@Override
public void remove(Result parent, Result child) {
// TODO: unlink from hierarchy, fire event
throw new UnsupportedOperationException();
}
- @SuppressWarnings("unused")
@Override
public void put(Result obj, List<Result> parents, List<Result> children) {
// TODO: can we support this somehow? Or reduce visibility?
diff --git a/src/de/lmu/ifi/dbs/elki/result/optics/ClusterOrderResult.java b/src/de/lmu/ifi/dbs/elki/result/optics/ClusterOrderResult.java
index 9c5c6cdd..4a5a9636 100644
--- a/src/de/lmu/ifi/dbs/elki/result/optics/ClusterOrderResult.java
+++ b/src/de/lmu/ifi/dbs/elki/result/optics/ClusterOrderResult.java
@@ -267,13 +267,11 @@ public class ClusterOrderResult<D extends Distance<D>> extends BasicResult imple
return null; // FIXME
}
- @SuppressWarnings("unused")
@Override
public void set(DBID id, D val) {
throw new UnsupportedOperationException();
}
- @SuppressWarnings("unused")
@Override
public void delete(DBID id) {
throw new UnsupportedOperationException();
@@ -358,13 +356,11 @@ public class ClusterOrderResult<D extends Distance<D>> extends BasicResult imple
return null; // FIXME
}
- @SuppressWarnings("unused")
@Override
public void set(DBID id, DBID val) {
throw new UnsupportedOperationException();
}
- @SuppressWarnings("unused")
@Override
public void delete(DBID id) {
throw new UnsupportedOperationException();
diff --git a/src/de/lmu/ifi/dbs/elki/result/outlier/OutlierResult.java b/src/de/lmu/ifi/dbs/elki/result/outlier/OutlierResult.java
index cafe4958..4389c7c8 100644
--- a/src/de/lmu/ifi/dbs/elki/result/outlier/OutlierResult.java
+++ b/src/de/lmu/ifi/dbs/elki/result/outlier/OutlierResult.java
@@ -33,6 +33,7 @@ import de.lmu.ifi.dbs.elki.result.OrderingResult;
*
* @author Erich Schubert
*
+ * @apiviz.landmark
* @apiviz.composedOf OutlierScoreMeta
* @apiviz.composedOf Relation oneway - - contains
* @apiviz.composedOf OrderingFromRelation
diff --git a/src/de/lmu/ifi/dbs/elki/result/textwriter/TextWriter.java b/src/de/lmu/ifi/dbs/elki/result/textwriter/TextWriter.java
index 743e787f..bbe3212b 100644
--- a/src/de/lmu/ifi/dbs/elki/result/textwriter/TextWriter.java
+++ b/src/de/lmu/ifi/dbs/elki/result/textwriter/TextWriter.java
@@ -40,6 +40,7 @@ import de.lmu.ifi.dbs.elki.data.FeatureVector;
import de.lmu.ifi.dbs.elki.data.HierarchicalClassLabel;
import de.lmu.ifi.dbs.elki.data.LabelList;
import de.lmu.ifi.dbs.elki.data.SimpleClassLabel;
+import de.lmu.ifi.dbs.elki.data.model.ClusterModel;
import de.lmu.ifi.dbs.elki.data.model.Model;
import de.lmu.ifi.dbs.elki.data.type.TypeUtil;
import de.lmu.ifi.dbs.elki.database.Database;
@@ -301,9 +302,14 @@ public class TextWriter {
owriter.writeObject(out, lbl, obj);
}
+ Collection<Relation<?>> dbrels = db.getRelations();
// print the annotations
if(ra != null) {
for(Relation<?> a : ra) {
+ // Avoid duplicated output.
+ if (dbrels.contains(a)) {
+ continue;
+ }
String label = a.getShortName();
Object value = a.get(objID);
if(value == null) {
@@ -350,6 +356,11 @@ public class TextWriter {
// Write cluster information
out.commentPrintLn("Cluster: " + naming.getNameFor(clus));
+ Model model = clus.getModel();
+ if (model != ClusterModel.CLUSTER) {
+ TextWriterWriterInterface<?> mwri = writers.getHandler(model);
+ mwri.writeObject(out, null, model);
+ }
if(clus.getParents().size() > 0) {
StringBuffer buf = new StringBuffer();
buf.append("Parents:");
diff --git a/src/de/lmu/ifi/dbs/elki/utilities/Util.java b/src/de/lmu/ifi/dbs/elki/utilities/Util.java
index 639c0d64..fcaca269 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/Util.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/Util.java
@@ -599,7 +599,7 @@ public final class Util {
}
@Override
- public boolean add(@SuppressWarnings("unused") T e) {
+ public boolean add(T e) {
throw new UnsupportedOperationException();
}
diff --git a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/KNNList.java b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/KNNList.java
index 8e0e2372..02a5264c 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/KNNList.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/datastructures/heap/KNNList.java
@@ -137,22 +137,22 @@ public class KNNList<D extends Distance<D>> extends ArrayList<DistanceResultPair
/* Make the list unmodifiable! */
@Override
- public boolean add(@SuppressWarnings("unused") DistanceResultPair<D> e) {
+ public boolean add(DistanceResultPair<D> e) {
throw new UnsupportedOperationException();
}
@Override
- public void add(@SuppressWarnings("unused") int index, @SuppressWarnings("unused") DistanceResultPair<D> element) {
+ public void add(int index, DistanceResultPair<D> element) {
throw new UnsupportedOperationException();
}
@Override
- public boolean addAll(@SuppressWarnings("unused") Collection<? extends DistanceResultPair<D>> c) {
+ public boolean addAll(Collection<? extends DistanceResultPair<D>> c) {
throw new UnsupportedOperationException();
}
@Override
- public boolean addAll(@SuppressWarnings("unused") int index, @SuppressWarnings("unused") Collection<? extends DistanceResultPair<D>> c) {
+ public boolean addAll(int index, Collection<? extends DistanceResultPair<D>> c) {
throw new UnsupportedOperationException();
}
@@ -162,17 +162,17 @@ public class KNNList<D extends Distance<D>> extends ArrayList<DistanceResultPair
}
@Override
- public DistanceResultPair<D> remove(@SuppressWarnings("unused") int index) {
+ public DistanceResultPair<D> remove(int index) {
throw new UnsupportedOperationException();
}
@Override
- public boolean remove(@SuppressWarnings("unused") Object o) {
+ public boolean remove(Object o) {
throw new UnsupportedOperationException();
}
@Override
- public DistanceResultPair<D> set(@SuppressWarnings("unused") int index, @SuppressWarnings("unused") DistanceResultPair<D> element) {
+ public DistanceResultPair<D> set(int index, DistanceResultPair<D> element) {
throw new UnsupportedOperationException();
}
diff --git a/src/de/lmu/ifi/dbs/elki/utilities/iterator/UnmodifiableListIterator.java b/src/de/lmu/ifi/dbs/elki/utilities/iterator/UnmodifiableListIterator.java
index 46affd34..0123216d 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/iterator/UnmodifiableListIterator.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/iterator/UnmodifiableListIterator.java
@@ -87,12 +87,12 @@ public final class UnmodifiableListIterator<T> implements ListIterator<T> {
}
@Override
- public void add(@SuppressWarnings("unused") T e) {
+ public void add(T e) {
throw new UnsupportedOperationException();
}
@Override
- public void set(@SuppressWarnings("unused") T e) {
+ public void set(T e) {
throw new UnsupportedOperationException();
}
} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/AbstractNumberConstraint.java b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/AbstractNumberConstraint.java
index a631a316..6b49faea 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/AbstractNumberConstraint.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/AbstractNumberConstraint.java
@@ -23,15 +23,16 @@ package de.lmu.ifi.dbs.elki.utilities.optionhandling.constraints;
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-
/**
* Abstract super class for constraints dealing with a certain number value.
*
* @author Elke Achtert
+ *
+ * @apiviz.uses de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.NumberParameter
+ *
* @param <P> the type of the parameter to be tested by this constraint (e.g., Number, List<Number>)
*/
public abstract class AbstractNumberConstraint<P> implements ParameterConstraint<P> {
-
/**
* The constraint value.
*/
@@ -45,4 +46,4 @@ public abstract class AbstractNumberConstraint<P> implements ParameterConstraint
public AbstractNumberConstraint(Number constraintValue) {
this.constraintValue = constraintValue;
}
-}
+} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/EqualStringConstraint.java b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/EqualStringConstraint.java
index ea952a30..342ffd00 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/EqualStringConstraint.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/EqualStringConstraint.java
@@ -35,6 +35,8 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.WrongParameterValueException
* ) to be tested is equal to the specified constraint-strings.
*
* @author Steffi Wanka
+ *
+ * @apiviz.uses de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.StringParameter
*/
public class EqualStringConstraint implements ParameterConstraint<String> {
/**
diff --git a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/IntervalConstraint.java b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/IntervalConstraint.java
index a2d5b8b3..8a9f1bcf 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/IntervalConstraint.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/IntervalConstraint.java
@@ -27,148 +27,135 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.ParameterException;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.WrongParameterValueException;
/**
- * Represents an interval parameter constraint testing if a given value lies within
- * the specified interval.
- * The value of the number parameter ({@link de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.NumberParameter})
- * tested has to be greater than (or equal to, if specified) than the specified low constraint value
- * and less than (or equal to, if specified) than the specified high constraint value.
- *
+ * Represents an interval parameter constraint testing if a given value lies
+ * within the specified interval. The value of the number parameter (
+ * {@link de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.NumberParameter}
+ * ) tested has to be greater than (or equal to, if specified) than the
+ * specified low constraint value and less than (or equal to, if specified) than
+ * the specified high constraint value.
+ *
* @author Steffi Wanka
+ *
+ * @apiviz.uses de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.NumberParameter
*/
public class IntervalConstraint implements ParameterConstraint<Number> {
+ /**
+ * Available interval boundary types types:
+ * {@link IntervalConstraint.IntervalBoundary#OPEN} denotes an opend interval,
+ * i.e. less than (or greater than) comparison
+ * {@link IntervalConstraint.IntervalBoundary#CLOSE} denotes a closed
+ * interval, i.e. an equal to or less than (or equal to or greater than)
+ * comparison
+ *
+ * @apiviz.exclude
+ */
+ public enum IntervalBoundary {
/**
- * Available interval boundary types types:
- * {@link IntervalConstraint.IntervalBoundary#OPEN} denotes an opend interval,
- * i.e. less than (or greater than) comparison
- * {@link IntervalConstraint.IntervalBoundary#CLOSE} denotes a closed interval,
- * i.e. an equal to or less than (or equal to or greater than) comparison
- *
- * @apiviz.exclude
+ * Open interval boundary
*/
- public enum IntervalBoundary {
- /**
- * Open interval boundary
- */
- OPEN,
- /**
- * Closed interval boundary
- */
- CLOSE
- }
-
- /**
- * The low constraint value (left interval boundary).
- */
- private final Number lowConstraintValue;
-
- /**
- * The interval boundary for the low constraint value (@see IntervalBoundary)
- */
- private final IntervalBoundary lowBoundary;
-
- /**
- * The high constraint value (right interval boundary).
- */
- private final Number highConstraintValue;
-
+ OPEN,
/**
- * The interval boundary for the high constraint value (@see IntervalBoundary)
+ * Closed interval boundary
*/
- private final IntervalBoundary highBoundary;
+ CLOSE
+ }
+
+ /**
+ * The low constraint value (left interval boundary).
+ */
+ private final Number lowConstraintValue;
+
+ /**
+ * The interval boundary for the low constraint value (@see IntervalBoundary)
+ */
+ private final IntervalBoundary lowBoundary;
+
+ /**
+ * The high constraint value (right interval boundary).
+ */
+ private final Number highConstraintValue;
+
+ /**
+ * The interval boundary for the high constraint value (@see IntervalBoundary)
+ */
+ private final IntervalBoundary highBoundary;
+
+ /**
+ * Creates an IntervalConstraint parameter constraint.
+ * <p/>
+ * That is, the value of the number parameter given has to be greater than (or
+ * equal to, if specified) than the specified low constraint value and less
+ * than (or equal to, if specified) than the specified high constraint value.
+ *
+ * @param lowConstraintValue the low constraint value (left interval boundary)
+ * @param lowBoundary the interval boundary for the low constraint value (@see
+ * IntervalBoundary)
+ * @param highConstraintValue the high constraint value (right interval
+ * boundary)
+ * @param highBoundary the interval boundary for the high constraint value
+ * (@see IntervalBoundary)
+ */
+ public IntervalConstraint(Number lowConstraintValue, IntervalBoundary lowBoundary, Number highConstraintValue, IntervalBoundary highBoundary) {
+ if(lowConstraintValue.doubleValue() >= highConstraintValue.doubleValue()) {
+ throw new IllegalArgumentException("Left interval boundary is greater than " + "or equal to right interval boundary!");
+ }
- /**
- * Creates an IntervalConstraint parameter constraint.
- * <p/>
- * That is, the value of the number parameter given
- * has to be greater than (or equal to, if specified) than the specified low constraint value
- * and less than (or equal to, if specified) than the specified high constraint value.
- *
- * @param lowConstraintValue the low constraint value (left interval boundary)
- * @param lowBoundary the interval boundary for the low constraint value (@see IntervalBoundary)
- * @param highConstraintValue the high constraint value (right interval boundary)
- * @param highBoundary the interval boundary for the high constraint value (@see IntervalBoundary)
- */
- public IntervalConstraint(Number lowConstraintValue, IntervalBoundary lowBoundary,
- Number highConstraintValue, IntervalBoundary highBoundary) {
- if (lowConstraintValue.doubleValue() >= highConstraintValue.doubleValue()) {
- throw new IllegalArgumentException("Left interval boundary is greater than " +
- "or equal to right interval boundary!");
- }
-
- this.lowConstraintValue = lowConstraintValue;
- this.lowBoundary = lowBoundary;
- this.highConstraintValue = highConstraintValue;
- this.highBoundary = highBoundary;
+ this.lowConstraintValue = lowConstraintValue;
+ this.lowBoundary = lowBoundary;
+ this.highConstraintValue = highConstraintValue;
+ this.highBoundary = highBoundary;
+ }
+
+ /**
+ * Checks if the number value given by the number parameter is greater equal
+ * than the constraint value. If not, a parameter exception is thrown.
+ *
+ */
+ @Override
+ public void test(Number t) throws ParameterException {
+ // lower value
+ if(lowBoundary.equals(IntervalBoundary.CLOSE)) {
+ if(t.doubleValue() < lowConstraintValue.doubleValue()) {
+ throw new WrongParameterValueException("Parameter Constraint Error: \n" + "The parameter value specified has to be " + "equal to or greater than " + lowConstraintValue.toString() + ". (current value: " + t.doubleValue() + ")\n");
+ }
+ }
+ else if(lowBoundary.equals(IntervalBoundary.OPEN)) {
+ if(t.doubleValue() <= lowConstraintValue.doubleValue()) {
+ throw new WrongParameterValueException("Parameter Constraint Error: \n" + "The parameter value specified has to be " + "greater than " + lowConstraintValue.toString() + ". (current value: " + t.doubleValue() + ")\n");
+ }
}
- /**
- * Checks if the number value given by the number parameter is
- * greater equal than the constraint
- * value. If not, a parameter exception is thrown.
- *
- */
- @Override
- public void test(Number t) throws ParameterException {
- // lower value
- if (lowBoundary.equals(IntervalBoundary.CLOSE)) {
- if (t.doubleValue() < lowConstraintValue.doubleValue()) {
- throw new WrongParameterValueException("Parameter Constraint Error: \n" +
- "The parameter value specified has to be " +
- "equal to or greater than " +
- lowConstraintValue.toString() +
- ". (current value: " + t.doubleValue() + ")\n");
- }
- }
- else if (lowBoundary.equals(IntervalBoundary.OPEN)) {
- if (t.doubleValue() <= lowConstraintValue.doubleValue()) {
- throw new WrongParameterValueException("Parameter Constraint Error: \n" +
- "The parameter value specified has to be " +
- "greater than " +
- lowConstraintValue.toString() +
- ". (current value: " + t.doubleValue() + ")\n");
- }
- }
-
- // higher value
- if (highBoundary.equals(IntervalBoundary.CLOSE)) {
- if (t.doubleValue() > highConstraintValue.doubleValue()) {
- throw new WrongParameterValueException("Parameter Constraint Error: \n" +
- "The parameter value specified has to be " +
- "equal to or less than " +
- highConstraintValue.toString() +
- ". (current value: " + t.doubleValue() + ")\n");
- }
- }
- else if (highBoundary.equals(IntervalBoundary.OPEN)) {
- if (t.doubleValue() >= highConstraintValue.doubleValue()) {
- throw new WrongParameterValueException("Parameter Constraint Error: \n" +
- "The parameter value specified has to be " +
- "less than " +
- highConstraintValue.toString() +
- ". (current value: " + t.doubleValue() + ")\n");
- }
- }
+ // higher value
+ if(highBoundary.equals(IntervalBoundary.CLOSE)) {
+ if(t.doubleValue() > highConstraintValue.doubleValue()) {
+ throw new WrongParameterValueException("Parameter Constraint Error: \n" + "The parameter value specified has to be " + "equal to or less than " + highConstraintValue.toString() + ". (current value: " + t.doubleValue() + ")\n");
+ }
}
+ else if(highBoundary.equals(IntervalBoundary.OPEN)) {
+ if(t.doubleValue() >= highConstraintValue.doubleValue()) {
+ throw new WrongParameterValueException("Parameter Constraint Error: \n" + "The parameter value specified has to be " + "less than " + highConstraintValue.toString() + ". (current value: " + t.doubleValue() + ")\n");
+ }
+ }
+ }
- @Override
- public String getDescription(String parameterName) {
- String description = parameterName + " in ";
- if (lowBoundary.equals(IntervalBoundary.CLOSE)) {
- description += "[";
- }
- else if (lowBoundary.equals(IntervalBoundary.OPEN)) {
- description += "(";
- }
-
- description += lowConstraintValue.toString() + ", " + highConstraintValue;
-
- if (highBoundary.equals(IntervalBoundary.CLOSE)) {
- description += "]";
- }
- if (highBoundary.equals(IntervalBoundary.OPEN)) {
- description += ")";
- }
- return description;
+ @Override
+ public String getDescription(String parameterName) {
+ String description = parameterName + " in ";
+ if(lowBoundary.equals(IntervalBoundary.CLOSE)) {
+ description += "[";
+ }
+ else if(lowBoundary.equals(IntervalBoundary.OPEN)) {
+ description += "(";
}
-}
+ description += lowConstraintValue.toString() + ", " + highConstraintValue;
+
+ if(highBoundary.equals(IntervalBoundary.CLOSE)) {
+ description += "]";
+ }
+ if(highBoundary.equals(IntervalBoundary.OPEN)) {
+ description += ")";
+ }
+ return description;
+ }
+} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/ListSizeConstraint.java b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/ListSizeConstraint.java
index f2fef29d..5c6a5156 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/ListSizeConstraint.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/ListSizeConstraint.java
@@ -35,6 +35,9 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ListParameter;
* size constraint.
*
* @author Steffi Wanka
+ *
+ * @apiviz.uses de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ListParameter
+ *
* @param <T> Parameter type
*/
public class ListSizeConstraint<T> implements ParameterConstraint<List<T>> {
diff --git a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/ParameterFlagGlobalConstraint.java b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/ParameterFlagGlobalConstraint.java
index bb2239b3..4c5b9262 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/ParameterFlagGlobalConstraint.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/ParameterFlagGlobalConstraint.java
@@ -36,6 +36,10 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.Parameter;
* the flag the parameter is tested for keeping its constraints or not.
*
* @author Steffi Wanka
+ *
+ * @apiviz.uses de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.Flag
+ * @apiviz.uses de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.Parameter
+ *
* @param <C> Constraint type
* @param <S> Parameter type
*/
diff --git a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/StringLengthConstraint.java b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/StringLengthConstraint.java
index 4fc2592c..ac8c48b3 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/StringLengthConstraint.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/constraints/StringLengthConstraint.java
@@ -32,6 +32,8 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.WrongParameterValueException
* .
*
* @author Erich Schubert
+ *
+ * @apiviz.uses de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.StringParameter
*/
public class StringLengthConstraint implements ParameterConstraint<String> {
/**
diff --git a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameterization/EmptyParameterization.java b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameterization/EmptyParameterization.java
index 6def810a..05a85b49 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameterization/EmptyParameterization.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameterization/EmptyParameterization.java
@@ -37,7 +37,6 @@ public class EmptyParameterization extends AbstractParameterization {
return false;
}
- @SuppressWarnings("unused")
@Override
public boolean setValueForOption(Parameter<?,?> opt) throws ParameterException {
// Always return false, we don't have extra parameters,
@@ -49,7 +48,7 @@ public class EmptyParameterization extends AbstractParameterization {
* Default implementation, for flat parameterizations.
*/
@Override
- public Parameterization descend(@SuppressWarnings("unused") Object option) {
+ public Parameterization descend(Object option) {
return this;
}
} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameterization/ListParameterization.java b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameterization/ListParameterization.java
index 8366a089..8e751fe7 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameterization/ListParameterization.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameterization/ListParameterization.java
@@ -138,7 +138,7 @@ public class ListParameterization extends AbstractParameterization {
* Default implementation, for flat parameterizations.
*/
@Override
- public Parameterization descend(@SuppressWarnings("unused") Object option) {
+ public Parameterization descend(Object option) {
return this;
}
diff --git a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameterization/SerializedParameterization.java b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameterization/SerializedParameterization.java
index 6d19cfd5..a4eeda1a 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameterization/SerializedParameterization.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameterization/SerializedParameterization.java
@@ -166,7 +166,7 @@ public class SerializedParameterization extends AbstractParameterization {
* Default implementation, for flat parameterizations.
*/
@Override
- public Parameterization descend(@SuppressWarnings("unused") Object option) {
+ public Parameterization descend(Object option) {
return this;
}
} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameterization/UnParameterization.java b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameterization/UnParameterization.java
index 4704e1da..5fc930db 100644
--- a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameterization/UnParameterization.java
+++ b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameterization/UnParameterization.java
@@ -51,7 +51,6 @@ public class UnParameterization implements Parameterization {
}
@Override
- @SuppressWarnings("unused")
public boolean checkConstraint(GlobalParameterConstraint constraint) {
return false;
}
@@ -67,7 +66,6 @@ public class UnParameterization implements Parameterization {
}
@Override
- @SuppressWarnings("unused")
public boolean grab(Parameter<?, ?> opt) {
return false;
}
@@ -78,13 +76,12 @@ public class UnParameterization implements Parameterization {
}
@Override
- @SuppressWarnings("unused")
public boolean setValueForOption(Parameter<?, ?> opt) throws ParameterException {
return false;
}
@Override
- public Parameterization descend(@SuppressWarnings("unused") Object option) {
+ public Parameterization descend(Object option) {
return this;
}
diff --git a/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/EnumParameter.java b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/EnumParameter.java
new file mode 100644
index 00000000..afab86c8
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/utilities/optionhandling/parameters/EnumParameter.java
@@ -0,0 +1,167 @@
+package de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters;
+
+/*
+ This file is part of ELKI:
+ Environment for Developing KDD-Applications Supported by Index-Structures
+
+ Copyright (C) 2011
+ Ludwig-Maximilians-Universität München
+ Lehr- und Forschungseinheit für Datenbanksysteme
+ ELKI Development Team
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.OptionID;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.ParameterException;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.UnspecifiedParameterException;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.WrongParameterValueException;
+
+/**
+ * Parameter class for a parameter specifying an enum type.
+ *
+ * <p>
+ * Usage:
+ *
+ * <pre>
+ * // Enum declaration.
+ * enum MyEnum { VALUE1, VALUE2 };
+ * // Parameter value holder.
+ * MyEnum myEnumParameter;
+ *
+ * // ...
+ *
+ * // Parameterization.
+ * EnumParameter&lt;MyEnum&gt; param = new EnumParameter&lt;MyEnum&gt;(ENUM_PROPERTY_ID, MyEnum.class);
+ * // OR
+ * EnumParameter&lt;MyEnum&gt; param = new EnumParameter&lt;MyEnum&gt;(ENUM_PROPERTY_ID, MyEnum.class, MyEnum.VALUE1);
+ * // OR
+ * EnumParameter&lt;MyEnum&gt; param = new EnumParameter&lt;MyEnum&gt;(ENUM_PROPERTY_ID, MyEnum.class, true);
+ *
+ * if(config.grab(param)) {
+ * myEnumParameter = param.getValue();
+ * }
+ *
+ * </p>
+ *
+ * @author Florian Nuecke
+ *
+ * @param <E> Enum type
+ */
+public class EnumParameter<E extends Enum<E>> extends Parameter<Enum<E>, E> {
+
+ /**
+ * Reference to the actual enum type, for T.valueOf().
+ */
+ protected Class<E> enumClass;
+
+ /**
+ * Constructs an enum parameter with the given optionID, constraints and
+ * default value.
+ *
+ * @param optionID the unique id of the parameter
+ * @param defaultValue the default value of the parameter
+ */
+ public EnumParameter(OptionID optionID, Class<E> enumClass, E defaultValue) {
+ super(optionID, defaultValue);
+ this.enumClass = enumClass;
+ }
+
+ /**
+ * Constructs an enum parameter with the given optionID, constraints and
+ * default value.
+ *
+ * @param optionID the unique id of the parameter
+ * @param optional Flag to signal an optional parameter.
+ */
+ public EnumParameter(OptionID optionID, Class<E> enumClass, boolean optional) {
+ super(optionID, optional);
+ this.enumClass = enumClass;
+ }
+
+ /**
+ * Constructs an enum parameter with the given optionID, constraints and
+ * default value.
+ *
+ * @param optionID the unique id of the parameter
+ */
+ public EnumParameter(OptionID optionID, Class<E> enumClass) {
+ super(optionID);
+ this.enumClass = enumClass;
+ }
+
+ @Override
+ public String getSyntax() {
+ return "<" + joinEnumNames(" | ") + ">";
+ }
+
+ @Override
+ protected E parseValue(Object obj) throws ParameterException {
+ if(obj == null) {
+ throw new UnspecifiedParameterException("Parameter \"" + getName() + "\": Null value given!");
+ }
+ if(obj instanceof String) {
+ try {
+ return Enum.valueOf(enumClass, (String) obj);
+ }
+ catch(IllegalArgumentException ex) {
+ throw new WrongParameterValueException("Enum parameter " + getName() + " is invalid (must be one of [" + joinEnumNames(", ") + "].");
+ }
+ }
+ throw new WrongParameterValueException("Enum parameter " + getName() + " is not given as a string.");
+ }
+
+ @Override
+ public String getValueAsString() {
+ return getValue().name();
+ }
+
+ /**
+ * Get a list of possible values for this enum parameter.
+ *
+ * @return list of strings representing possible enum values.
+ */
+ public Collection<String> getPossibleValues() {
+ // Convert to string array
+ final E[] enums = enumClass.getEnumConstants();
+ ArrayList<String> values = new ArrayList<String>(enums.length);
+ for(E t : enums) {
+ values.add(t.name());
+ }
+ return values;
+ }
+
+ /**
+ * Utility method for merging possible values into a string for informational
+ * messages.
+ *
+ * @param separator char sequence to use as a separator for enum values.
+ * @return <code>{VAL1}{separator}{VAL2}{separator}...</code>
+ */
+ private String joinEnumNames(String separator) {
+ E[] enumTypes = enumClass.getEnumConstants();
+ StringBuilder sb = new StringBuilder();
+ for(int i = 0; i < enumTypes.length; ++i) {
+ if(i > 0) {
+ sb.append(separator);
+ }
+ sb.append(enumTypes[i].name());
+ }
+ return sb.toString();
+ }
+
+}
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/VisualizationTask.java b/src/de/lmu/ifi/dbs/elki/visualization/VisualizationTask.java
index c648a9dd..04d2c5eb 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/VisualizationTask.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/VisualizationTask.java
@@ -38,7 +38,7 @@ import de.lmu.ifi.dbs.elki.visualization.visualizers.VisFactory;
* @apiviz.landmark
* @apiviz.composedOf VisFactory
* @apiviz.has SVGPlot
- * @apiviz.has VisualizerContext
+ * @apiviz.has VisFactory
* @apiviz.has Projection oneway - 0:1
* @apiviz.has Visualization oneway
*/
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/VisualizerContext.java b/src/de/lmu/ifi/dbs/elki/visualization/VisualizerContext.java
index ed30f3a3..532e7de5 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/VisualizerContext.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/VisualizerContext.java
@@ -397,17 +397,15 @@ public class VisualizerContext extends AnyMap<String> implements DataStoreListen
}
@Override
- public void resultAdded(Result child, @SuppressWarnings("unused") Result parent) {
+ public void resultAdded(Result child, Result parent) {
processNewResult(getResult(), child);
}
- @SuppressWarnings("unused")
@Override
public void resultChanged(Result current) {
// FIXME: need to do anything?
}
- @SuppressWarnings("unused")
@Override
public void resultRemoved(Result child, Result parent) {
// FIXME: implement
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/batikutil/JSVGUpdateSynchronizer.java b/src/de/lmu/ifi/dbs/elki/visualization/batikutil/JSVGUpdateSynchronizer.java
index 96d99002..0ecb6e0e 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/batikutil/JSVGUpdateSynchronizer.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/batikutil/JSVGUpdateSynchronizer.java
@@ -226,12 +226,12 @@ class JSVGUpdateSynchronizer implements UpdateSynchronizer {
* React to an update manager becoming available.
*/
@Override
- public void managerStarted(@SuppressWarnings("unused") UpdateManagerEvent e) {
+ public void managerStarted(UpdateManagerEvent e) {
makeRunnerIfNeeded();
}
@Override
- public void managerStopped(@SuppressWarnings("unused") UpdateManagerEvent e) {
+ public void managerStopped(UpdateManagerEvent e) {
forgetSynchronizedRunner();
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/gui/ResultWindow.java b/src/de/lmu/ifi/dbs/elki/visualization/gui/ResultWindow.java
index a3b8a458..c5bdf408 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/gui/ResultWindow.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/gui/ResultWindow.java
@@ -165,7 +165,7 @@ public class ResultWindow extends JFrame implements ResultListener {
exportItem.setEnabled(false);
exportItem.addActionListener(new ActionListener() {
@Override
- public void actionPerformed(@SuppressWarnings("unused") ActionEvent ae) {
+ public void actionPerformed(ActionEvent ae) {
saveCurrentPlot();
}
});
@@ -174,7 +174,7 @@ public class ResultWindow extends JFrame implements ResultListener {
quitItem.setMnemonic(KeyEvent.VK_Q);
quitItem.addActionListener(new ActionListener() {
@Override
- public void actionPerformed(@SuppressWarnings("unused") ActionEvent e) {
+ public void actionPerformed(ActionEvent e) {
close();
}
});
@@ -184,7 +184,7 @@ public class ResultWindow extends JFrame implements ResultListener {
overviewItem.setEnabled(false);
overviewItem.addActionListener(new ActionListener() {
@Override
- public void actionPerformed(@SuppressWarnings("unused") ActionEvent ae) {
+ public void actionPerformed(ActionEvent ae) {
showOverview();
}
});
@@ -193,7 +193,7 @@ public class ResultWindow extends JFrame implements ResultListener {
editItem.setMnemonic(KeyEvent.VK_T);
editItem.addActionListener(new ActionListener() {
@Override
- public void actionPerformed(@SuppressWarnings("unused") ActionEvent ae) {
+ public void actionPerformed(ActionEvent ae) {
showTableView();
}
});
@@ -416,7 +416,7 @@ public class ResultWindow extends JFrame implements ResultListener {
final JCheckBoxMenuItem visItem = new JCheckBoxMenuItem(name, enabled);
visItem.addItemListener(new ItemListener() {
@Override
- public void itemStateChanged(@SuppressWarnings("unused") ItemEvent e) {
+ public void itemStateChanged(ItemEvent e) {
// We need SwingUtilities to avoid a deadlock!
SwingUtilities.invokeLater(new Runnable() {
@Override
@@ -432,7 +432,7 @@ public class ResultWindow extends JFrame implements ResultListener {
final JRadioButtonMenuItem visItem = new JRadioButtonMenuItem(name, enabled);
visItem.addItemListener(new ItemListener() {
@Override
- public void itemStateChanged(@SuppressWarnings("unused") ItemEvent e) {
+ public void itemStateChanged(ItemEvent e) {
// We need SwingUtilities to avoid a deadlock!
SwingUtilities.invokeLater(new Runnable() {
@Override
@@ -448,19 +448,16 @@ public class ResultWindow extends JFrame implements ResultListener {
return null;
}
- @SuppressWarnings("unused")
@Override
public void resultAdded(Result child, Result parent) {
updateVisualizerMenus();
}
- @SuppressWarnings("unused")
@Override
public void resultChanged(Result current) {
updateVisualizerMenus();
}
- @SuppressWarnings("unused")
@Override
public void resultRemoved(Result child, Result parent) {
updateVisualizerMenus();
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/gui/SelectionTableWindow.java b/src/de/lmu/ifi/dbs/elki/visualization/gui/SelectionTableWindow.java
index c2190e63..6bcf5f0b 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/gui/SelectionTableWindow.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/gui/SelectionTableWindow.java
@@ -163,14 +163,14 @@ public class SelectionTableWindow extends JFrame implements DataStoreListener, R
closeButton = new JButton("close");
closeButton.addActionListener(new ActionListener() {
@Override
- public void actionPerformed(@SuppressWarnings("unused") ActionEvent arg0) {
+ public void actionPerformed(ActionEvent arg0) {
dispose();
}
});
deleteButton = new JButton("delete");
deleteButton.addActionListener(new ActionListener() {
@Override
- public void actionPerformed(@SuppressWarnings("unused") ActionEvent arg0) {
+ public void actionPerformed(ActionEvent arg0) {
handleDelete();
}
});
@@ -291,7 +291,7 @@ public class SelectionTableWindow extends JFrame implements DataStoreListener, R
}
@Override
- public boolean isCellEditable(@SuppressWarnings("unused") int rowIndex, int columnIndex) {
+ public boolean isCellEditable(int rowIndex, int columnIndex) {
if(columnIndex == 0) {
return false;
}
@@ -310,8 +310,7 @@ public class SelectionTableWindow extends JFrame implements DataStoreListener, R
}
if(columnIndex == 2 && aValue instanceof String) {
// FIXME: better class label handling!
- SimpleClassLabel lbl = new SimpleClassLabel();
- lbl.init((String) aValue);
+ SimpleClassLabel lbl = new SimpleClassLabel((String) aValue);
crep.set(id, lbl);
}
if(!(aValue instanceof String)) {
@@ -361,13 +360,11 @@ public class SelectionTableWindow extends JFrame implements DataStoreListener, R
}
}
- @SuppressWarnings("unused")
@Override
public void resultAdded(Result child, Result parent) {
// TODO Auto-generated method stub
}
- @SuppressWarnings("unused")
@Override
public void resultRemoved(Result child, Result parent) {
// TODO Auto-generated method stub
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/gui/SimpleSVGViewer.java b/src/de/lmu/ifi/dbs/elki/visualization/gui/SimpleSVGViewer.java
index e249eed3..a08be9b5 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/gui/SimpleSVGViewer.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/gui/SimpleSVGViewer.java
@@ -84,7 +84,7 @@ public class SimpleSVGViewer extends JFrame {
exportItem.setMnemonic(KeyEvent.VK_E);
exportItem.addActionListener(new ActionListener() {
@Override
- public void actionPerformed(@SuppressWarnings("unused") ActionEvent ae) {
+ public void actionPerformed(ActionEvent ae) {
saveCurrentPlot();
}
});
@@ -93,7 +93,7 @@ public class SimpleSVGViewer extends JFrame {
quitItem.setMnemonic(KeyEvent.VK_Q);
quitItem.addActionListener(new ActionListener() {
@Override
- public void actionPerformed(@SuppressWarnings("unused") ActionEvent e) {
+ public void actionPerformed(ActionEvent e) {
close();
}
});
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/gui/detail/DetailView.java b/src/de/lmu/ifi/dbs/elki/visualization/gui/detail/DetailView.java
index 99bbc78d..341aa69f 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/gui/detail/DetailView.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/gui/detail/DetailView.java
@@ -52,9 +52,9 @@ import de.lmu.ifi.dbs.elki.visualization.visualizers.VisualizerUtil;
*
* @author Erich Schubert
*
- * @apiviz.has VisualizerContext
* @apiviz.has Visualization
* @apiviz.has PlotItem
+ * @apiviz.uses VisualizerContext
* @apiviz.uses VisualizationTask
*/
public class DetailView extends SVGPlot implements ResultListener {
@@ -245,7 +245,6 @@ public class DetailView extends SVGPlot implements ResultListener {
}
}
- @SuppressWarnings("unused")
@Override
public void resultAdded(Result child, Result parent) {
// Ignore. The PlotItem will need to change.
@@ -285,7 +284,6 @@ public class DetailView extends SVGPlot implements ResultListener {
}
}
- @SuppressWarnings("unused")
@Override
public void resultRemoved(Result child, Result parent) {
// Ignore. The PlotItem will need to change.
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/gui/overview/OverviewPlot.java b/src/de/lmu/ifi/dbs/elki/visualization/gui/overview/OverviewPlot.java
index 5c8b8d44..f05719ae 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/gui/overview/OverviewPlot.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/gui/overview/OverviewPlot.java
@@ -64,7 +64,7 @@ import de.lmu.ifi.dbs.elki.visualization.visualizers.VisualizerUtil;
*
* @apiviz.landmark
* @apiviz.has VisualizerContext
- * @apiviz.composedOf PlotMap
+ * @apiviz.composedOf RectangleArranger
* @apiviz.has DetailViewSelectedEvent
* @apiviz.uses DetailView
* @apiviz.uses de.lmu.ifi.dbs.elki.visualization.projections.Projection
@@ -300,31 +300,33 @@ public class OverviewPlot extends SVGPlot implements ResultListener {
boolean refreshcss = false;
final int thumbsize = (int) Math.max(screenwidth / plotmap.getWidth(), screenheight / plotmap.getHeight());
for(Entry<PlotItem, double[]> ent : plotmap.entrySet()) {
- PlotItem it = ent.getKey();
- for(Iterator<VisualizationTask> iter = it.visIterator(); iter.hasNext(); ) {
- VisualizationTask task = iter.next();
- Element parent = vistoelem.get(new Pair<PlotItem, VisualizationTask>(it, task));
- if(parent == null) {
- LoggingUtil.warning("No container element produced by " + task);
- continue;
- }
- if(VisualizerUtil.thumbnailEnabled(task) && VisualizerUtil.isVisible(task)) {
- // unhide when hidden.
- if(parent.hasAttribute(SVGConstants.CSS_VISIBILITY_PROPERTY)) {
- parent.removeAttribute(SVGConstants.CSS_VISIBILITY_PROPERTY);
+ for(Iterator<PlotItem> iter = ent.getKey().itemIterator(); iter.hasNext();) {
+ PlotItem it = iter.next();
+
+ for(VisualizationTask task : it.visualizations) {
+ Element parent = vistoelem.get(new Pair<PlotItem, VisualizationTask>(it, task));
+ if(parent == null) {
+ LoggingUtil.warning("No container element found for " + task);
+ continue;
}
- // if not yet rendered, add a thumbnail
- if(!parent.hasChildNodes()) {
- makeThumbnail(thumbsize, it, task, parent);
- refreshcss = true;
+ if(VisualizerUtil.thumbnailEnabled(task) && VisualizerUtil.isVisible(task)) {
+ // unhide when hidden.
+ if(parent.hasAttribute(SVGConstants.CSS_VISIBILITY_PROPERTY)) {
+ parent.removeAttribute(SVGConstants.CSS_VISIBILITY_PROPERTY);
+ }
+ // if not yet rendered, add a thumbnail
+ if(!parent.hasChildNodes()) {
+ makeThumbnail(thumbsize, it, task, parent);
+ refreshcss = true;
+ }
}
- }
- else {
- // hide if there is anything to hide.
- if(parent != null && parent.hasChildNodes()) {
- parent.setAttribute(SVGConstants.CSS_VISIBILITY_PROPERTY, SVGConstants.CSS_HIDDEN_VALUE);
+ else {
+ // hide if there is anything to hide.
+ if(parent != null && parent.hasChildNodes()) {
+ parent.setAttribute(SVGConstants.CSS_VISIBILITY_PROPERTY, SVGConstants.CSS_HIDDEN_VALUE);
+ }
+ // TODO: unqueue pending thumbnails
}
- // TODO: unqueue pending thumbnails
}
}
}
@@ -419,7 +421,7 @@ public class OverviewPlot extends SVGPlot implements ResultListener {
}
@Override
- public void handleEvent(@SuppressWarnings("unused") Event evt) {
+ public void handleEvent(Event evt) {
triggerSubplotSelectEvent(it);
}
}
@@ -464,7 +466,6 @@ public class OverviewPlot extends SVGPlot implements ResultListener {
scheduleUpdate(pr);
}
- @SuppressWarnings("unused")
@Override
public void resultAdded(Result child, Result parent) {
logger.debug("result added: " + child);
@@ -480,7 +481,6 @@ public class OverviewPlot extends SVGPlot implements ResultListener {
lazyRefresh();
}
- @SuppressWarnings("unused")
@Override
public void resultRemoved(Result child, Result parent) {
logger.debug("result removed: " + child);
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/opticsplot/OPTICSColorStatic.java b/src/de/lmu/ifi/dbs/elki/visualization/opticsplot/OPTICSColorStatic.java
index 359d3062..af28008e 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/opticsplot/OPTICSColorStatic.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/opticsplot/OPTICSColorStatic.java
@@ -47,7 +47,7 @@ public class OPTICSColorStatic implements OPTICSColorAdapter {
}
@Override
- public int getColorForEntry(@SuppressWarnings("unused") ClusterOrderEntry<?> coe) {
+ public int getColorForEntry(ClusterOrderEntry<?> coe) {
return color;
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/projector/HistogramFactory.java b/src/de/lmu/ifi/dbs/elki/visualization/projector/HistogramFactory.java
index 06e94891..3836379a 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/projector/HistogramFactory.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/projector/HistogramFactory.java
@@ -40,8 +40,9 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.IntParameter;
* Produce one-dimensional projections.
*
* @author Erich Schubert
+ *
+ * @apiviz.has HistogramProjector
*/
-// TODO: re-add maxdim option
public class HistogramFactory implements ProjectorFactory {
/**
* Maximum dimensionality
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/projector/HistogramProjector.java b/src/de/lmu/ifi/dbs/elki/visualization/projector/HistogramProjector.java
index 5ddc7b32..40bd55ee 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/projector/HistogramProjector.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/projector/HistogramProjector.java
@@ -46,6 +46,8 @@ import de.lmu.ifi.dbs.elki.visualization.visualizers.visunproj.LabelVisFactory;
*
* @author Erich Schubert
*
+ * @apiviz.has LinearScale
+ *
* @param <V> Vector type
*/
public class HistogramProjector<V extends NumberVector<?, ?>> extends AbstractHierarchicalResult implements Projector {
@@ -80,21 +82,26 @@ public class HistogramProjector<V extends NumberVector<?, ?>> extends AbstractHi
@Override
public Collection<PlotItem> arrange() {
- List<PlotItem> layout = new ArrayList<PlotItem>(1);
+ List<PlotItem> layout = new ArrayList<PlotItem>(1 + dmax);
List<VisualizationTask> tasks = ResultUtil.filterResults(this, VisualizationTask.class);
if (tasks.size() > 0){
- PlotItem master = new PlotItem(dmax + .1, .5 + .1, null);
- for(int d1 = 1; d1 <= dmax; d1++) {
- Projection1D proj = new Simple1D(scales, d1);
- final PlotItem it = new PlotItem(d1 - 1 + .1, 0. + .1, 1., .5, proj);
+ final double xoff = (dmax > 1) ? .1 : 0.;
+ final double hheight = .5;
+ final double lheight = .1;
+ PlotItem master = new PlotItem(dmax + xoff, hheight + lheight, null);
+ for(int d1 = 0; d1 < dmax; d1++) {
+ Projection1D proj = new Simple1D(scales, d1 + 1);
+ final PlotItem it = new PlotItem(d1 + xoff, lheight, 1., hheight, proj);
it.visualizations = tasks;
master.subitems.add(it);
}
layout.add(master);
- for(int d1 = 1; d1 <= dmax; d1++) {
- PlotItem it = new PlotItem(d1 - 1 + .1, 0, 1., .1, null);
- final VisualizationTask task = new VisualizationTask("", null, null, new LabelVisFactory(DatabaseUtil.getColumnLabel(rel, d1)));
- task.height = .1;
+ // Add labels
+ for(int d1 = 0; d1 < dmax; d1++) {
+ PlotItem it = new PlotItem(d1 + xoff, 0, 1., lheight, null);
+ LabelVisFactory lbl = new LabelVisFactory(DatabaseUtil.getColumnLabel(rel, d1 + 1));
+ final VisualizationTask task = new VisualizationTask("", null, null, lbl);
+ task.height = lheight;
task.width = 1;
task.put(VisualizationTask.META_NODETAIL, true);
it.visualizations.add(task);
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/projector/OPTICSProjectorFactory.java b/src/de/lmu/ifi/dbs/elki/visualization/projector/OPTICSProjectorFactory.java
index 580eb532..25023029 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/projector/OPTICSProjectorFactory.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/projector/OPTICSProjectorFactory.java
@@ -36,6 +36,8 @@ import de.lmu.ifi.dbs.elki.visualization.opticsplot.OPTICSPlot;
* Produce OPTICS plot projections
*
* @author Erich Schubert
+ *
+ * @apiviz.has OPTICSProjector
*/
public class OPTICSProjectorFactory implements ProjectorFactory {
/**
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/projector/ProjectorFactory.java b/src/de/lmu/ifi/dbs/elki/visualization/projector/ProjectorFactory.java
index d0996822..3dbb803f 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/projector/ProjectorFactory.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/projector/ProjectorFactory.java
@@ -33,6 +33,8 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.Parameterizable;
* detecting appropriate relations in the database.
*
* @author Erich Schubert
+ *
+ * @apiviz.has Projector
*/
public interface ProjectorFactory extends ResultProcessor, Parameterizable {
/**
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/projector/ScatterPlotFactory.java b/src/de/lmu/ifi/dbs/elki/visualization/projector/ScatterPlotFactory.java
index 3d996bdc..5957233d 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/projector/ScatterPlotFactory.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/projector/ScatterPlotFactory.java
@@ -41,8 +41,9 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.IntParameter;
* Produce scatterplot projections.
*
* @author Erich Schubert
+ *
+ * @apiviz.has ScatterPlotProjector
*/
-// TODO: re-add maxdim option
public class ScatterPlotFactory implements ProjectorFactory {
/**
* Maximum number of dimensions to visualize.
@@ -114,7 +115,7 @@ public class ScatterPlotFactory implements ProjectorFactory {
}
@Override
- protected Object makeInstance() {
+ protected ScatterPlotFactory makeInstance() {
return new ScatterPlotFactory(maxdim);
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/projector/ScatterPlotProjector.java b/src/de/lmu/ifi/dbs/elki/visualization/projector/ScatterPlotProjector.java
index ee692531..a090f523 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/projector/ScatterPlotProjector.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/projector/ScatterPlotProjector.java
@@ -48,9 +48,10 @@ import de.lmu.ifi.dbs.elki.visualization.visualizers.visunproj.LabelVisFactory;
*
* @author Erich Schubert
*
+ * @apiviz.has LinearScale
+ *
* @param <V> Vector type
*/
-// FIXME: re-add column labels
public class ScatterPlotProjector<V extends NumberVector<?, ?>> extends AbstractHierarchicalResult implements Projector {
/**
* Relation we project
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/savedialog/SaveOptionsPanel.java b/src/de/lmu/ifi/dbs/elki/visualization/savedialog/SaveOptionsPanel.java
index 9a678218..9c41fbab 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/savedialog/SaveOptionsPanel.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/savedialog/SaveOptionsPanel.java
@@ -171,7 +171,7 @@ public class SaveOptionsPanel extends JPanel {
spinnerWidth = new JSpinner(modelWidth);
spinnerWidth.addChangeListener(new ChangeListener() {
@Override
- public void stateChanged(@SuppressWarnings("unused") ChangeEvent e) {
+ public void stateChanged(ChangeEvent e) {
if(aspectRatioLock.isSelected()) {
int val = modelWidth.getNumber().intValue();
spinnerHeight.setValue(new Integer((int) Math.round(val / ratio)));
@@ -183,7 +183,7 @@ public class SaveOptionsPanel extends JPanel {
spinnerHeight = new JSpinner(modelHeight);
spinnerHeight.addChangeListener(new ChangeListener() {
@Override
- public void stateChanged(@SuppressWarnings("unused") ChangeEvent e) {
+ public void stateChanged(ChangeEvent e) {
if(aspectRatioLock.isSelected()) {
int val = modelHeight.getNumber().intValue();
spinnerWidth.setValue(new Integer((int) Math.round(val * ratio)));
@@ -207,7 +207,7 @@ public class SaveOptionsPanel extends JPanel {
resetSizeButton = new JButton(STR_RESET_IMAGE_SIZE);
resetSizeButton.addActionListener(new ActionListener() {
@Override
- public void actionPerformed(@SuppressWarnings("unused") ActionEvent e) {
+ public void actionPerformed(ActionEvent e) {
modelWidth.setValue(width);
modelHeight.setValue(height);
aspectRatioLock.setSelected(true);
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/AbstractVisualization.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/AbstractVisualization.java
index 8d1b184d..dab1c6dd 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/AbstractVisualization.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/AbstractVisualization.java
@@ -169,7 +169,6 @@ public abstract class AbstractVisualization implements Visualization, ContextCha
*/
protected abstract void redraw();
- @SuppressWarnings("unused")
@Override
public void resultAdded(Result child, Result parent) {
// Ignore by default
@@ -183,7 +182,6 @@ public abstract class AbstractVisualization implements Visualization, ContextCha
}
}
- @SuppressWarnings("unused")
@Override
public void resultRemoved(Result child, Result parent) {
// Ignore by default.
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/optics/AbstractOPTICSVisualization.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/optics/AbstractOPTICSVisualization.java
index 9cb95c23..bcf25a84 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/optics/AbstractOPTICSVisualization.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/optics/AbstractOPTICSVisualization.java
@@ -39,7 +39,9 @@ import de.lmu.ifi.dbs.elki.visualization.visualizers.AbstractVisualization;
* Abstract base class for OPTICS visualizer
*
* @author Erich Schubert
- *
+ *
+ * @apiviz.uses OPTICSProjector
+ *
* @param <D>
*/
public abstract class AbstractOPTICSVisualization<D extends Distance<D>> extends AbstractVisualization {
@@ -47,12 +49,12 @@ public abstract class AbstractOPTICSVisualization<D extends Distance<D>> extends
* The plot
*/
final protected OPTICSProjector<D> optics;
-
+
/**
* Width of plot (in display units)
*/
protected double plotwidth;
-
+
/**
* Height of plot (in display units)
*/
@@ -60,7 +62,7 @@ public abstract class AbstractOPTICSVisualization<D extends Distance<D>> extends
/**
* Constructor.
- *
+ *
* @param task Visualization task.
*/
public AbstractOPTICSVisualization(VisualizationTask task) {
@@ -79,7 +81,7 @@ public abstract class AbstractOPTICSVisualization<D extends Distance<D>> extends
final String transform = SVGUtil.makeMarginTransform(task.getWidth(), task.getHeight(), plotwidth, plotheight, margin / 2);
SVGUtil.setAtt(layer, SVGConstants.SVG_TRANSFORM_ATTRIBUTE, transform);
}
-
+
/**
* Access the raw cluster order
*
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/optics/OPTICSClusterVisualization.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/optics/OPTICSClusterVisualization.java
index 0898d9d0..542dcea7 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/optics/OPTICSClusterVisualization.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/optics/OPTICSClusterVisualization.java
@@ -53,8 +53,7 @@ import de.lmu.ifi.dbs.elki.visualization.visualizers.Visualization;
*
* @author Erich Schubert
*
- * @apiviz.uses ClusterOrderResult
- * @apiviz.uses OPTICSPlot
+ * @apiviz.uses Clustering oneway - - «visualizes»
*
* @param <D> Distance type (actually unused)
*/
@@ -210,7 +209,7 @@ public class OPTICSClusterVisualization<D extends Distance<D>> extends AbstractO
}
@Override
- public boolean allowThumbnails(@SuppressWarnings("unused") VisualizationTask task) {
+ public boolean allowThumbnails(VisualizationTask task) {
// Don't use thumbnails
return false;
}
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/optics/OPTICSPlotCutVisualization.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/optics/OPTICSPlotCutVisualization.java
index 9f2a5734..08ca7504 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/optics/OPTICSPlotCutVisualization.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/optics/OPTICSPlotCutVisualization.java
@@ -57,9 +57,6 @@ import de.lmu.ifi.dbs.elki.visualization.visualizers.Visualization;
*
* @author Heidi Kolb
*
- * @apiviz.uses ClusterOrderResult oneway - 1 visualizes
- * @apiviz.uses OPTICSPlot oneway - 1 visualizes
- *
* @param <D> distance type
*/
public class OPTICSPlotCutVisualization<D extends Distance<D>> extends AbstractOPTICSVisualization<D> implements DragableArea.DragListener {
@@ -204,7 +201,7 @@ public class OPTICSPlotCutVisualization<D extends Distance<D>> extends AbstractO
}
@Override
- public boolean startDrag(SVGPoint start, @SuppressWarnings("unused") Event evt) {
+ public boolean startDrag(SVGPoint start, Event evt) {
epsilon = getEpsilonFromY(plotheight - start.getY());
// opvis.unsetEpsilonExcept(this);
synchronizedRedraw();
@@ -212,7 +209,7 @@ public class OPTICSPlotCutVisualization<D extends Distance<D>> extends AbstractO
}
@Override
- public boolean duringDrag(@SuppressWarnings("unused") SVGPoint start, SVGPoint end, @SuppressWarnings("unused") Event evt, boolean inside) {
+ public boolean duringDrag(SVGPoint start, SVGPoint end, Event evt, boolean inside) {
if(inside) {
epsilon = getEpsilonFromY(plotheight - end.getY());
}
@@ -222,7 +219,7 @@ public class OPTICSPlotCutVisualization<D extends Distance<D>> extends AbstractO
}
@Override
- public boolean endDrag(@SuppressWarnings("unused") SVGPoint start, SVGPoint end, @SuppressWarnings("unused") Event evt, boolean inside) {
+ public boolean endDrag(SVGPoint start, SVGPoint end, Event evt, boolean inside) {
if(inside) {
epsilon = getEpsilonFromY(plotheight - end.getY());
// opvis.unsetEpsilonExcept(this);
@@ -294,7 +291,7 @@ public class OPTICSPlotCutVisualization<D extends Distance<D>> extends AbstractO
}
@Override
- public boolean allowThumbnails(@SuppressWarnings("unused") VisualizationTask task) {
+ public boolean allowThumbnails(VisualizationTask task) {
// Don't use thumbnails
return false;
}
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/optics/OPTICSPlotSelectionVisualization.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/optics/OPTICSPlotSelectionVisualization.java
index b75bd3b5..69bc781e 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/optics/OPTICSPlotSelectionVisualization.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/optics/OPTICSPlotSelectionVisualization.java
@@ -59,8 +59,6 @@ import de.lmu.ifi.dbs.elki.visualization.visualizers.Visualization;
*
* @author Heidi Kolb
*
- * @apiviz.uses ClusterOrderResult oneway - 1
- * @apiviz.uses OPTICSPlot oneway - 1
* @apiviz.uses DBIDSelection oneway - 1 visualizes
*
* @param <D> distance type
@@ -181,7 +179,7 @@ public class OPTICSPlotSelectionVisualization<D extends Distance<D>> extends Abs
}
@Override
- public boolean startDrag(SVGPoint startPoint, @SuppressWarnings("unused") Event evt) {
+ public boolean startDrag(SVGPoint startPoint, Event evt) {
List<ClusterOrderEntry<D>> order = getClusterOrder();
int mouseActIndex = getSelectedIndex(order, startPoint);
if(mouseActIndex >= 0 && mouseActIndex < order.size()) {
@@ -196,7 +194,7 @@ public class OPTICSPlotSelectionVisualization<D extends Distance<D>> extends Abs
}
@Override
- public boolean duringDrag(SVGPoint startPoint, SVGPoint dragPoint, @SuppressWarnings("unused") Event evt, @SuppressWarnings("unused") boolean inside) {
+ public boolean duringDrag(SVGPoint startPoint, SVGPoint dragPoint, Event evt, boolean inside) {
List<ClusterOrderEntry<D>> order = getClusterOrder();
int mouseDownIndex = getSelectedIndex(order, startPoint);
int mouseActIndex = getSelectedIndex(order, dragPoint);
@@ -213,7 +211,7 @@ public class OPTICSPlotSelectionVisualization<D extends Distance<D>> extends Abs
}
@Override
- public boolean endDrag(SVGPoint startPoint, SVGPoint dragPoint, Event evt, @SuppressWarnings("unused") boolean inside) {
+ public boolean endDrag(SVGPoint startPoint, SVGPoint dragPoint, Event evt, boolean inside) {
List<ClusterOrderEntry<D>> order = getClusterOrder();
int mouseDownIndex = getSelectedIndex(order, startPoint);
int mouseActIndex = getSelectedIndex(order, dragPoint);
@@ -366,7 +364,7 @@ public class OPTICSPlotSelectionVisualization<D extends Distance<D>> extends Abs
}
@Override
- public boolean allowThumbnails(@SuppressWarnings("unused") VisualizationTask task) {
+ public boolean allowThumbnails(VisualizationTask task) {
// Don't use thumbnails
return false;
}
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/optics/OPTICSPlotVisualizer.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/optics/OPTICSPlotVisualizer.java
index 4af5d466..7f4e3248 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/optics/OPTICSPlotVisualizer.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/optics/OPTICSPlotVisualizer.java
@@ -51,9 +51,6 @@ import de.lmu.ifi.dbs.elki.visualization.visualizers.Visualization;
*
* @author Erich Schubert
*
- * @apiviz.has OPTICSPlot oneway - 1 visualizes
- * @apiviz.has ClusterOrderResult oneway - 1 visualizes
- *
* @param <D> Distance type
*/
public class OPTICSPlotVisualizer<D extends Distance<D>> extends AbstractOPTICSVisualization<D> {
@@ -138,7 +135,7 @@ public class OPTICSPlotVisualizer<D extends Distance<D>> extends AbstractOPTICSV
}
@Override
- public boolean allowThumbnails(@SuppressWarnings("unused") VisualizationTask task) {
+ public boolean allowThumbnails(VisualizationTask task) {
// Don't use thumbnails
return false;
}
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/optics/OPTICSSteepAreaVisualization.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/optics/OPTICSSteepAreaVisualization.java
index f9430145..b082836f 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/optics/OPTICSSteepAreaVisualization.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/optics/OPTICSSteepAreaVisualization.java
@@ -215,7 +215,7 @@ public class OPTICSSteepAreaVisualization<D extends Distance<D>> extends Abstrac
}
@Override
- public boolean allowThumbnails(@SuppressWarnings("unused") VisualizationTask task) {
+ public boolean allowThumbnails(VisualizationTask task) {
// Don't use thumbnails
return false;
}
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/thumbs/ThumbnailVisualization.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/thumbs/ThumbnailVisualization.java
index e352d599..25f55d41 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/thumbs/ThumbnailVisualization.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/thumbs/ThumbnailVisualization.java
@@ -152,7 +152,7 @@ public class ThumbnailVisualization extends AbstractVisualization implements Thu
}
@Override
- public void contentChanged(@SuppressWarnings("unused") DataStoreEvent e) {
+ public void contentChanged(DataStoreEvent e) {
refreshThumbnail();
}
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/vis2d/AbstractTooltipVisualization.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/vis2d/AbstractTooltipVisualization.java
index 9b8d19b6..4e0171ae 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/vis2d/AbstractTooltipVisualization.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/vis2d/AbstractTooltipVisualization.java
@@ -172,7 +172,7 @@ public abstract class AbstractTooltipVisualization<NV extends NumberVector<NV, ?
abstract protected void setupCSS(SVGPlot svgp);
@Override
- public void contentChanged(@SuppressWarnings("unused") DataStoreEvent e) {
+ public void contentChanged(DataStoreEvent e) {
synchronizedRedraw();
}
} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/vis2d/AxisVisualization.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/vis2d/AxisVisualization.java
index 4e927ace..4dc7e820 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/vis2d/AxisVisualization.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/vis2d/AxisVisualization.java
@@ -158,7 +158,7 @@ public class AxisVisualization<NV extends NumberVector<NV, ?>> extends P2DVisual
}
@Override
- public boolean allowThumbnails(@SuppressWarnings("unused") VisualizationTask task) {
+ public boolean allowThumbnails(VisualizationTask task) {
// Don't use thumbnails
return false;
}
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/vis2d/ClusterOrderVisualization.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/vis2d/ClusterOrderVisualization.java
index 644083f9..f758ff99 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/vis2d/ClusterOrderVisualization.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/vis2d/ClusterOrderVisualization.java
@@ -108,7 +108,7 @@ public class ClusterOrderVisualization<NV extends NumberVector<NV, ?>> extends P
}
@Override
- public void contentChanged(@SuppressWarnings("unused") DataStoreEvent e) {
+ public void contentChanged(DataStoreEvent e) {
synchronizedRedraw();
}
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/vis2d/ClusteringVisualization.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/vis2d/ClusteringVisualization.java
index 58f71ef3..4bef6e11 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/vis2d/ClusteringVisualization.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/vis2d/ClusteringVisualization.java
@@ -101,7 +101,7 @@ public class ClusteringVisualization<NV extends NumberVector<NV, ?>> extends P2D
}
@Override
- public void contentChanged(@SuppressWarnings("unused") DataStoreEvent e) {
+ public void contentChanged(DataStoreEvent e) {
synchronizedRedraw();
}
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/vis2d/MoveObjectsToolVisualization.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/vis2d/MoveObjectsToolVisualization.java
index 66b442f9..6d798247 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/vis2d/MoveObjectsToolVisualization.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/vis2d/MoveObjectsToolVisualization.java
@@ -95,7 +95,7 @@ public class MoveObjectsToolVisualization<NV extends NumberVector<NV, ?>> extend
}
@Override
- public void contextChanged(@SuppressWarnings("unused") ContextChangedEvent e) {
+ public void contextChanged(ContextChangedEvent e) {
synchronizedRedraw();
}
@@ -169,19 +169,19 @@ public class MoveObjectsToolVisualization<NV extends NumberVector<NV, ?>> extend
}
@Override
- public boolean startDrag(@SuppressWarnings("unused") SVGPoint startPoint, @SuppressWarnings("unused") Event evt) {
+ public boolean startDrag(SVGPoint startPoint, Event evt) {
return true;
}
@Override
- public boolean duringDrag(SVGPoint startPoint, SVGPoint dragPoint, @SuppressWarnings("unused") Event evt, @SuppressWarnings("unused") boolean inside) {
+ public boolean duringDrag(SVGPoint startPoint, SVGPoint dragPoint, Event evt, boolean inside) {
deleteChildren(rtag);
rtag.appendChild(svgp.svgLine(startPoint.getX(), startPoint.getY(), dragPoint.getX(), dragPoint.getY()));
return true;
}
@Override
- public boolean endDrag(SVGPoint startPoint, SVGPoint dragPoint, @SuppressWarnings("unused") Event evt, @SuppressWarnings("unused") boolean inside) {
+ public boolean endDrag(SVGPoint startPoint, SVGPoint dragPoint, Event evt, boolean inside) {
Vector movingVector = new Vector(2);
movingVector.set(0, dragPoint.getX() - startPoint.getX());
movingVector.set(1, dragPoint.getY() - startPoint.getY());
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/vis2d/SelectionConvexHullVisualization.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/vis2d/SelectionConvexHullVisualization.java
index 9e70ffd8..fde2c00d 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/vis2d/SelectionConvexHullVisualization.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/vis2d/SelectionConvexHullVisualization.java
@@ -140,7 +140,7 @@ public class SelectionConvexHullVisualization<NV extends NumberVector<NV, ?>> ex
}
@Override
- public void contentChanged(@SuppressWarnings("unused") DataStoreEvent e) {
+ public void contentChanged(DataStoreEvent e) {
synchronizedRedraw();
}
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/vis2d/SelectionCubeVisualization.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/vis2d/SelectionCubeVisualization.java
index 7f6d9c04..087ec6af 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/vis2d/SelectionCubeVisualization.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/vis2d/SelectionCubeVisualization.java
@@ -95,14 +95,8 @@ public class SelectionCubeVisualization<NV extends NumberVector<NV, ?>> extends
*/
protected boolean nofill = false;
- /**
- * The result we process
- */
- private SelectionResult result;
-
public SelectionCubeVisualization(VisualizationTask task, boolean nofill) {
super(task);
- this.result = task.getResult();
this.nofill = nofill;
addCSSClasses(svgp);
context.addContextChangeListener(this);
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/vis2d/SelectionDotVisualization.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/vis2d/SelectionDotVisualization.java
index 283eafaa..06167532 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/vis2d/SelectionDotVisualization.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/vis2d/SelectionDotVisualization.java
@@ -75,18 +75,12 @@ public class SelectionDotVisualization<NV extends NumberVector<NV, ?>> extends P
public static final String MARKER = "selectionDotMarker";
/**
- * The selection result we work on
- */
- private SelectionResult result;
-
- /**
* Constructor.
*
* @param task Task
*/
public SelectionDotVisualization(VisualizationTask task) {
super(task);
- this.result = task.getResult();
context.addContextChangeListener(this);
context.addResultListener(this);
context.addDataStoreListener(this);
@@ -131,7 +125,7 @@ public class SelectionDotVisualization<NV extends NumberVector<NV, ?>> extends P
}
@Override
- public void contentChanged(@SuppressWarnings("unused") DataStoreEvent e) {
+ public void contentChanged(DataStoreEvent e) {
synchronizedRedraw();
}
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/vis2d/SelectionToolCubeVisualization.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/vis2d/SelectionToolCubeVisualization.java
index fc2af9da..ed0b456d 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/vis2d/SelectionToolCubeVisualization.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/vis2d/SelectionToolCubeVisualization.java
@@ -101,18 +101,12 @@ public class SelectionToolCubeVisualization<NV extends NumberVector<NV, ?>> exte
private Element etag;
/**
- * Our result
- */
- private SelectionResult result;
-
- /**
* Constructor.
*
* @param task Task
*/
public SelectionToolCubeVisualization(VisualizationTask task) {
super(task);
- this.result = task.getResult();
this.dim = DatabaseUtil.dimensionality(rel);
context.addContextChangeListener(this);
incrementalRedraw();
@@ -125,7 +119,7 @@ public class SelectionToolCubeVisualization<NV extends NumberVector<NV, ?>> exte
}
@Override
- public void contextChanged(@SuppressWarnings("unused") ContextChangedEvent e) {
+ public void contextChanged(ContextChangedEvent e) {
synchronizedRedraw();
}
@@ -184,12 +178,12 @@ public class SelectionToolCubeVisualization<NV extends NumberVector<NV, ?>> exte
}
@Override
- public boolean startDrag(@SuppressWarnings("unused") SVGPoint startPoint, @SuppressWarnings("unused") Event evt) {
+ public boolean startDrag(SVGPoint startPoint, Event evt) {
return true;
}
@Override
- public boolean duringDrag(SVGPoint startPoint, SVGPoint dragPoint, @SuppressWarnings("unused") Event evt, @SuppressWarnings("unused") boolean inside) {
+ public boolean duringDrag(SVGPoint startPoint, SVGPoint dragPoint, Event evt, boolean inside) {
deleteChildren(rtag);
double x = Math.min(startPoint.getX(), dragPoint.getX());
double y = Math.min(startPoint.getY(), dragPoint.getY());
@@ -200,7 +194,7 @@ public class SelectionToolCubeVisualization<NV extends NumberVector<NV, ?>> exte
}
@Override
- public boolean endDrag(SVGPoint startPoint, SVGPoint dragPoint, @SuppressWarnings("unused") Event evt, @SuppressWarnings("unused") boolean inside) {
+ public boolean endDrag(SVGPoint startPoint, SVGPoint dragPoint, Event evt, boolean inside) {
deleteChildren(rtag);
if(startPoint.getX() != dragPoint.getX() || startPoint.getY() != dragPoint.getY()) {
updateSelection(proj, startPoint, dragPoint);
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/vis2d/SelectionToolDotVisualization.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/vis2d/SelectionToolDotVisualization.java
index a50a6cbb..7593dac5 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/vis2d/SelectionToolDotVisualization.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/vis2d/SelectionToolDotVisualization.java
@@ -95,18 +95,12 @@ public class SelectionToolDotVisualization<NV extends NumberVector<NV, ?>> exten
Element etag;
/**
- * Our result
- */
- private SelectionResult result;
-
- /**
* Constructor.
*
* @param task Task
*/
public SelectionToolDotVisualization(VisualizationTask task) {
super(task);
- this.result = task.getResult();
context.addContextChangeListener(this);
incrementalRedraw();
}
@@ -118,7 +112,7 @@ public class SelectionToolDotVisualization<NV extends NumberVector<NV, ?>> exten
}
@Override
- public void contextChanged(@SuppressWarnings("unused") ContextChangedEvent e) {
+ public void contextChanged(ContextChangedEvent e) {
synchronizedRedraw();
}
@@ -149,12 +143,12 @@ public class SelectionToolDotVisualization<NV extends NumberVector<NV, ?>> exten
}
@Override
- public boolean startDrag(@SuppressWarnings("unused") SVGPoint startPoint, @SuppressWarnings("unused") Event evt) {
+ public boolean startDrag(SVGPoint startPoint, Event evt) {
return true;
}
@Override
- public boolean duringDrag(SVGPoint startPoint, SVGPoint dragPoint, @SuppressWarnings("unused") Event evt, @SuppressWarnings("unused") boolean inside) {
+ public boolean duringDrag(SVGPoint startPoint, SVGPoint dragPoint, Event evt, boolean inside) {
deleteChildren(rtag);
double x = Math.min(startPoint.getX(), dragPoint.getX());
double y = Math.min(startPoint.getY(), dragPoint.getY());
@@ -165,7 +159,7 @@ public class SelectionToolDotVisualization<NV extends NumberVector<NV, ?>> exten
}
@Override
- public boolean endDrag(SVGPoint startPoint, SVGPoint dragPoint, Event evt, @SuppressWarnings("unused") boolean inside) {
+ public boolean endDrag(SVGPoint startPoint, SVGPoint dragPoint, Event evt, boolean inside) {
Mode mode = getInputMode(evt);
deleteChildren(rtag);
if(startPoint.getX() != dragPoint.getX() || startPoint.getY() != dragPoint.getY()) {
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/vis2d/ToolBox2DVisualization.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/vis2d/ToolBox2DVisualization.java
index ba91975c..c2339fe2 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/vis2d/ToolBox2DVisualization.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/vis2d/ToolBox2DVisualization.java
@@ -107,7 +107,7 @@ public class ToolBox2DVisualization<NV extends NumberVector<NV, ?>> extends P2DV
}
@Override
- public void contextChanged(@SuppressWarnings("unused") ContextChangedEvent e) {
+ public void contextChanged(ContextChangedEvent e) {
synchronizedRedraw();
}
@@ -232,7 +232,7 @@ public class ToolBox2DVisualization<NV extends NumberVector<NV, ?>> extends P2DV
EventTarget targ = (EventTarget) tag;
targ.addEventListener(SVGConstants.SVG_EVENT_CLICK, new EventListener() {
@Override
- public void handleEvent(@SuppressWarnings("unused") Event evt) {
+ public void handleEvent(Event evt) {
handleMouseClick(tool);
}
}, false);
@@ -252,7 +252,7 @@ public class ToolBox2DVisualization<NV extends NumberVector<NV, ?>> extends P2DV
}
@Override
- public void resultAdded(Result child, @SuppressWarnings("unused") Result parent) {
+ public void resultAdded(Result child, Result parent) {
if(child instanceof VisualizationTask) {
VisualizationTask task = (VisualizationTask) child;
if(VisualizerUtil.isTool(task)) {
@@ -262,7 +262,7 @@ public class ToolBox2DVisualization<NV extends NumberVector<NV, ?>> extends P2DV
}
@Override
- public void resultRemoved(Result child, @SuppressWarnings("unused") Result parent) {
+ public void resultRemoved(Result child, Result parent) {
if(child instanceof VisualizationTask) {
VisualizationTask task = (VisualizationTask) child;
if(VisualizerUtil.isTool(task)) {
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/vis2d/TreeMBRVisualization.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/vis2d/TreeMBRVisualization.java
index 5fe6aac2..cc3dfbe8 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/vis2d/TreeMBRVisualization.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/vis2d/TreeMBRVisualization.java
@@ -179,7 +179,7 @@ public class TreeMBRVisualization<NV extends NumberVector<NV, ?>, N extends Abst
}
@Override
- public void contentChanged(@SuppressWarnings("unused") DataStoreEvent e) {
+ public void contentChanged(DataStoreEvent e) {
synchronizedRedraw();
}
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/vis2d/TreeSphereVisualization.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/vis2d/TreeSphereVisualization.java
index 1aec1ead..73a02ddb 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/vis2d/TreeSphereVisualization.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/vis2d/TreeSphereVisualization.java
@@ -248,7 +248,7 @@ public class TreeSphereVisualization<NV extends NumberVector<NV, ?>, D extends N
}
@Override
- public void contentChanged(@SuppressWarnings("unused") DataStoreEvent e) {
+ public void contentChanged(DataStoreEvent e) {
synchronizedRedraw();
}
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/ClusterEvaluationVisFactory.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/ClusterEvaluationVisFactory.java
index 469d6db5..405ba673 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/ClusterEvaluationVisFactory.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/ClusterEvaluationVisFactory.java
@@ -123,7 +123,7 @@ public class ClusterEvaluationVisFactory extends AbstractVisFactory {
}
@Override
- public boolean allowThumbnails(@SuppressWarnings("unused") VisualizationTask task) {
+ public boolean allowThumbnails(VisualizationTask task) {
// Don't use thumbnails
return false;
}
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/CurveVisFactory.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/CurveVisFactory.java
index a45f2007..4d0e3dc0 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/CurveVisFactory.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/CurveVisFactory.java
@@ -235,7 +235,7 @@ public class CurveVisFactory extends AbstractVisFactory {
}
@Override
- public boolean allowThumbnails(@SuppressWarnings("unused") VisualizationTask task) {
+ public boolean allowThumbnails(VisualizationTask task) {
// TODO: depending on the curve complexity?
return false;
}
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/HistogramVisFactory.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/HistogramVisFactory.java
index c8dfe0c8..81a77c13 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/HistogramVisFactory.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/HistogramVisFactory.java
@@ -177,7 +177,7 @@ public class HistogramVisFactory extends AbstractVisFactory {
}
@Override
- public boolean allowThumbnails(@SuppressWarnings("unused") VisualizationTask task) {
+ public boolean allowThumbnails(VisualizationTask task) {
// TODO: depending on the histogram complexity?
return false;
}
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/KeyVisFactory.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/KeyVisFactory.java
index 69813d99..e3a5dfd4 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/KeyVisFactory.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/KeyVisFactory.java
@@ -116,7 +116,7 @@ public class KeyVisFactory extends AbstractVisFactory {
}
@Override
- public boolean allowThumbnails(@SuppressWarnings("unused") VisualizationTask task) {
+ public boolean allowThumbnails(VisualizationTask task) {
return false;
}
} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/PixmapVisualizer.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/PixmapVisualizer.java
index 06268dac..825d64b6 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/PixmapVisualizer.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/PixmapVisualizer.java
@@ -135,7 +135,7 @@ public class PixmapVisualizer extends AbstractVisualization {
}
@Override
- public boolean allowThumbnails(@SuppressWarnings("unused") VisualizationTask task) {
+ public boolean allowThumbnails(VisualizationTask task) {
// Don't use thumbnails
return false;
}
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/SettingsVisFactory.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/SettingsVisFactory.java
index 9be580f7..5d33fede 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/SettingsVisFactory.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/SettingsVisFactory.java
@@ -149,7 +149,7 @@ public class SettingsVisFactory extends AbstractVisFactory {
}
@Override
- public boolean allowThumbnails(@SuppressWarnings("unused") VisualizationTask task) {
+ public boolean allowThumbnails(VisualizationTask task) {
return false;
}
} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/SimilarityMatrixVisualizer.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/SimilarityMatrixVisualizer.java
index f9b1ef52..17424519 100644
--- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/SimilarityMatrixVisualizer.java
+++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/SimilarityMatrixVisualizer.java
@@ -163,7 +163,7 @@ public class SimilarityMatrixVisualizer extends AbstractVisualization {
}
@Override
- public boolean allowThumbnails(@SuppressWarnings("unused") VisualizationTask task) {
+ public boolean allowThumbnails(VisualizationTask task) {
// Don't use thumbnails
return false;
}
diff --git a/src/de/lmu/ifi/dbs/elki/workflow/EvaluationStep.java b/src/de/lmu/ifi/dbs/elki/workflow/EvaluationStep.java
index 50081404..70a7478c 100644
--- a/src/de/lmu/ifi/dbs/elki/workflow/EvaluationStep.java
+++ b/src/de/lmu/ifi/dbs/elki/workflow/EvaluationStep.java
@@ -41,7 +41,6 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ObjectListParamet
* @author Erich Schubert
*
* @apiviz.has Evaluator
- * @apiviz.has Result
* @apiviz.uses Result
*/
public class EvaluationStep implements WorkflowStep {
@@ -77,6 +76,8 @@ public class EvaluationStep implements WorkflowStep {
* Class to handle running the evaluators on a database instance.
*
* @author Erich Schubert
+ *
+ * @apiviz.exclude
*/
public class Evaluation implements ResultListener {
/**