summaryrefslogtreecommitdiff
path: root/src/de/lmu/ifi/dbs/elki/application
diff options
context:
space:
mode:
Diffstat (limited to 'src/de/lmu/ifi/dbs/elki/application')
-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
2 files changed, 136 insertions, 595 deletions
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.");
}
}
}