[Swift-commit] r4022 - in usertools/plotter/src: . plotter
noreply at svn.ci.uchicago.edu
noreply at svn.ci.uchicago.edu
Fri Jan 21 11:39:55 CST 2011
Author: wozniak
Date: 2011-01-21 11:39:55 -0600 (Fri, 21 Jan 2011)
New Revision: 4022
Added:
usertools/plotter/src/plotter/
usertools/plotter/src/plotter/Bits.java
usertools/plotter/src/plotter/LineReader.java
usertools/plotter/src/plotter/Lines.java
usertools/plotter/src/plotter/Util.java
Log:
Adding
Added: usertools/plotter/src/plotter/Bits.java
===================================================================
--- usertools/plotter/src/plotter/Bits.java (rev 0)
+++ usertools/plotter/src/plotter/Bits.java 2011-01-21 17:39:55 UTC (rev 4022)
@@ -0,0 +1,150 @@
+package plotter;
+
+import java.math.BigInteger;
+import java.util.*;
+
+/**
+ * Provides random bits, statically.
+ * Kills VM exit code 2 on misuse.
+ * */
+
+public class Bits
+{
+ public static Random rng = null;
+ static boolean locked = false;
+ static boolean ready = false;
+
+ /**
+ If not locked, seed the generator with the clock.
+ */
+ public static void init()
+ {
+ init(System.currentTimeMillis());
+ }
+
+ /**
+ If not locked, seed the generator with the clock mod 1000.
+ Useful for debugging.
+ @param print If true, print the seed.
+ */
+ public static long init(boolean print)
+ {
+ long seed = System.currentTimeMillis() % 1000;
+ init(seed);
+
+ if (print)
+ System.out.println("Bits.seed: " + seed);
+
+ return seed;
+ }
+
+ /**
+ If not locked, seed the generator
+ @param seed The seed.
+ */
+ public static void init(long seed)
+ {
+ assert (!locked) : "Bits locked!";
+ // System.out.println("Seeding RNG...");
+ rng = new Random(seed);
+ ready = true;
+ }
+
+ /**
+ Lock the generator to prevent seeding
+ */
+ public static void lock()
+ {
+ locked = true;
+ }
+
+ /**
+ Unlock the generator
+ */
+ public static void unlock()
+ {
+ locked = false;
+ }
+
+ public static double nextDouble()
+ {
+ if (! ready)
+ {
+ System.err.println("Bits not ready!");
+ System.exit(2);
+ }
+ return rng.nextDouble();
+ }
+
+ public static double nextDouble(double d)
+ {
+ return rng.nextDouble() * d;
+ }
+
+ public static int nextInt()
+ {
+ if (! ready)
+ {
+ System.err.println("Bits not ready!");
+ System.exit(2);
+ }
+ return rng.nextInt();
+ }
+
+ /**
+ Return a integer in [0..t).
+ */
+ public static int nextInt(int t)
+ {
+ double d = nextDouble();
+ int i = (new Double(d * t)).intValue();
+ return i;
+ }
+
+ public static boolean nextBoolean()
+ {
+ if (! ready)
+ {
+ System.err.println("Bits not ready!");
+ System.exit(2);
+ }
+ return rng.nextBoolean();
+ }
+
+ public static long nextLong()
+ {
+ if (! ready)
+ {
+ System.err.println("Bits not ready!");
+ System.exit(2);
+ }
+ return rng.nextLong();
+ }
+
+ public static long nextLong(long t)
+ {
+ double d = nextDouble();
+ long i = (new Double(d * t)).longValue();
+ return i;
+ }
+
+ public static BigInteger nextBigInteger(BigInteger i)
+ {
+ if (i.equals(BigInteger.ZERO))
+ return BigInteger.ZERO;
+
+ int b = i.bitLength()+1;
+ BigInteger result;
+ do
+ {
+ result = BigInteger.valueOf(b);
+ } while (result.compareTo(i) >= 0);
+
+ return result;
+ }
+
+ public static void nextBytes(byte[] bytes)
+ {
+ rng.nextBytes(bytes);
+ }
+}
Added: usertools/plotter/src/plotter/LineReader.java
===================================================================
--- usertools/plotter/src/plotter/LineReader.java (rev 0)
+++ usertools/plotter/src/plotter/LineReader.java 2011-01-21 17:39:55 UTC (rev 4022)
@@ -0,0 +1,158 @@
+package plotter;
+
+import java.util.*;
+
+/**
+ * Utility to read a file into a List of String lines.
+ *
+ * Omits comments with #
+ * Omits blank lines
+ * Wraps lines that end on backslash
+ * */
+public class LineReader
+{
+ LineReader()
+ {}
+
+ public static List<String> read(java.io.File file)
+ throws java.io.FileNotFoundException
+ {
+ java.io.BufferedReader reader =
+ new java.io.BufferedReader(new java.io.FileReader(file));
+ return read(reader);
+ }
+
+ public static List<String> read(String s)
+ {
+ java.io.BufferedReader reader =
+ new java.io.BufferedReader(new java.io.StringReader(s));
+ return read(reader);
+ }
+
+ public static List<String> read(java.io.BufferedReader reader)
+ {
+ List<String> result = new ArrayList<String>();
+ try
+ {
+ String prevline = "";
+ String line = "";
+ while ((line = reader.readLine()) != null)
+ {
+ int hash = line.indexOf("#");
+ if (hash >= 0)
+ line = line.substring(0,hash);
+ line = spaces(line);
+ line = (prevline + " " + line).trim();
+ if (line.endsWith("\\"))
+ {
+ line = line.substring(0, line.length()-2);
+ prevline = line;
+ continue;
+ }
+ else
+ {
+ prevline = "";
+ line = line.trim();
+ if (line.length() > 0)
+ result.add(line);
+ }
+ }
+ reader.close();
+ }
+ catch (java.io.IOException e)
+ {
+ System.out.println("LineReader: I/O problem.");
+ return null;
+ }
+ return result;
+ }
+
+ public static List<String[]> tokens(List<String> lines)
+ {
+ List<String[]> result = new ArrayList<String[]>(lines.size());
+ for (String line : lines)
+ {
+ String[] tokens = tokenize(line);
+ result.add(tokens);
+ }
+ return result;
+ }
+
+ public static int maxTokens(List<String[]> tokens)
+ {
+ int result = 0;
+ for (String[] t : tokens)
+ if (t.length > result)
+ result = t.length;
+ return result;
+ }
+
+ /**
+ Take line-oriented data and produce an array of doubles.
+ */
+ public static double[][] array(List<String> lines)
+ {
+ List<String[]> tokens = tokens(lines);
+ int columns = maxTokens(tokens);
+ int rows = lines.size();
+ double[][] result = new double[rows][columns];
+ for (int i = 0; i < rows; i++)
+ for (int j = 0; j < columns; j++)
+ {
+ try
+ {
+ String v = tokens.get(i)[j];
+ double d = Double.parseDouble(v);
+ result[i][j] = d;
+ }
+ catch (NumberFormatException e)
+ {
+ throw new RuntimeException("Problem in row: " + i);
+ }
+ }
+ return result;
+ }
+
+ public static String spaces(String line)
+ {
+ String result = "";
+ for (int i = 0; i < line.length(); i++)
+ {
+ if (line.charAt(i) == '=' &&
+ line.charAt(i+1) != '=' &&
+ line.charAt(i-1) != '=')
+ {
+ result += " = ";
+ }
+ else
+ result += line.substring(i,i+1);
+ }
+ return result;
+ }
+
+ public static String[] tokenize(String line)
+ {
+ if (line == null)
+ return null;
+ List<String> words = new ArrayList<String>();
+ String[] ws = line.split("\\s");
+ for (int i = 0; i < ws.length; i++)
+ if (ws[i].length() > 0)
+ words.add(ws[i]);
+ String[] result = new String[words.size()];
+ for (int i = 0; i < words.size(); i++)
+ result[i] = words.get(i);
+ return result;
+ }
+
+ /*
+ public static List<String> list(String line)
+ {
+ List<String> result = new ArrayList<String>();
+ String[] tokens = tokenize(line);
+ for (int i = 0; i < tokens.length; i++)
+ result.add(tokens[i]);
+ return result;
+ }
+ */
+}
Added: usertools/plotter/src/plotter/Lines.java
===================================================================
--- usertools/plotter/src/plotter/Lines.java (rev 0)
+++ usertools/plotter/src/plotter/Lines.java 2011-01-21 17:39:55 UTC (rev 4022)
@@ -0,0 +1,345 @@
+package plotter;
+
+import java.awt.Color;
+import java.awt.geom.Rectangle2D;
+
+import java.io.*;
+import java.util.*;
+
+import gnu.getopt.Getopt;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.xmlgraphics.java2d.ps.EPSDocumentGraphics2D;
+
+import org.jfree.chart.ChartFactory;
+import org.jfree.chart.JFreeChart;
+import org.jfree.chart.axis.NumberAxis;
+import org.jfree.chart.plot.PlotOrientation;
+import org.jfree.chart.plot.XYPlot;
+import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
+import org.jfree.data.Range;
+import org.jfree.data.general.Series;
+import org.jfree.data.xy.XYSeriesCollection;
+
+/**
+ * See main() for command-line arguments
+ * */
+public class Lines
+{
+ static Properties properties;
+
+ public static boolean bw = false;
+
+ static int w = 400;
+ static int h = 400;
+
+ // null indicates the value was not set by the user
+ static Double xmin = null;
+ static Double xmax = null;
+ static Double ymin = null;
+ static Double ymax = null;
+
+ /**
+ Generate simple plot.
+ @param collection The x,y data.
+ @param title Plot title.
+ @param xlabel X label text.
+ @param ylabel Y label text.
+ @param output EPS filename.
+ */
+ public static boolean plot(XYSeriesCollection collection,
+ String title, String xlabel,
+ String ylabel, String output)
+ {
+ EPSDocumentGraphics2D g2d = null;
+ Rectangle2D.Double rectangle = null;
+ OutputStream out = null;
+
+ try
+ {
+ out = new FileOutputStream(output);
+ out = new BufferedOutputStream(out);
+
+ g2d = new EPSDocumentGraphics2D(false);
+ g2d.setGraphicContext
+ (new org.apache.xmlgraphics.java2d.GraphicContext());
+
+ rectangle = new Rectangle2D.Double(0, 0, w, h);
+
+ g2d.setGraphicContext
+ (new org.apache.xmlgraphics.java2d.GraphicContext());
+ g2d.setupDocument(out, w, h);
+ }
+ catch (IOException e)
+ {
+ System.out.println("Problem with file: " + output);
+ return false;
+ }
+
+ final boolean withLegend = true;
+
+ JFreeChart chart =
+ ChartFactory.createXYLineChart
+ (title, xlabel, ylabel, collection,
+ PlotOrientation.VERTICAL, withLegend, false, false);
+
+ setupPlot(chart, collection);
+ chart.draw(g2d, rectangle);
+
+ try
+ {
+ g2d.finish();
+ }
+ catch (Exception e)
+ {
+ System.out.println("Err!");
+ }
+
+ IOUtils.closeQuietly(out);
+ System.out.println("PLOTTED: " + output);
+
+ return true;
+ }
+
+ private static void setupPlot(JFreeChart chart,
+ XYSeriesCollection collection)
+ {
+ XYPlot plot = chart.getXYPlot();
+ XYLineAndShapeRenderer renderer = new XYLineAndShapeRenderer();
+ if (bw)
+ for (int i = 0; i < plot.getSeriesCount(); i++)
+ renderer.setSeriesPaint(i, Color.BLACK);
+ for (int i = 0; i < plot.getSeriesCount(); i++)
+ {
+ Series series = collection.getSeries(i);
+ if (! showShape(series.getDescription()))
+ {
+ // System.out.println("invis");
+ renderer.setSeriesShapesVisible(i, false);
+ }
+ }
+
+ setAxes(plot);
+ plot.setRenderer(renderer);
+ plot.setBackgroundPaint(Color.WHITE);
+ }
+
+ static void setAxes(XYPlot plot)
+ {
+ // Actual values: modify if necessary
+ double axmin, axmax, aymin, aymax;
+
+ if (xmin != null || xmax != null)
+ {
+ NumberAxis axis = (NumberAxis) plot.getDomainAxis();
+ Range range = axis.getRange();
+ axmin = range.getLowerBound();
+ axmax = range.getUpperBound();
+ if (xmin != null) axmin = xmin;
+ if (xmax != null) axmax = xmax;
+ axis.setRange(axmin, axmax);
+ }
+
+ if (ymin != null || ymax != null)
+ {
+ NumberAxis axis = (NumberAxis) plot.getRangeAxis();
+ Range range = axis.getRange();
+ aymin = range.getLowerBound();
+ aymax = range.getUpperBound();
+ if (ymin != null) aymin = ymin;
+ if (ymax != null) aymax = ymax;
+ axis.setRange(aymin, aymax);
+ }
+ }
+
+ /**
+ Args: Lines <properties> <output file> <data file>*
+ Reads settings from properties: see scanProperties()
+ Produces EPS output file
+ Data files are two-columns of numbers each -
+ see LineReader.read() and LineReader.array()
+ */
+ public static void main(String[] args)
+ {
+ // Settings:
+ boolean verbose = false;
+
+ Getopt g = new Getopt("testprog", args, "v");
+ int c = -1;
+ while ((c = g.getopt()) != -1)
+ {
+ switch (c)
+ {
+ case 'v':
+ verbose = true;
+ }
+ }
+
+ if (args.length < 3)
+ {
+ System.out.println
+ ("usage: [<options>] <properties> <output> <data>*");
+ System.exit(2);
+ }
+
+ Bits.init();
+ Util.verbose(verbose);
+
+ String propFile = args[0];
+ String output = args[1];
+ List<String> names = new ArrayList<String>();
+ for (int i = 2; i < args.length; i++)
+ names.add(args[i]);
+
+ String title = null;
+ String xlabel = null;
+ String ylabel = null;
+ List<double[][]> data = new ArrayList<double[][]>();
+ List<String> labels = new ArrayList<String>();
+
+ properties = new Properties();
+ load(propFile);
+ title = properties.getProperty("title");
+ xlabel = properties.getProperty("xlabel");
+ ylabel = properties.getProperty("ylabel");
+
+ scanProperties();
+
+ for (String name : names)
+ {
+ File file = new File(name);
+ Util.verbose("open: " + file);
+ List<String> lines = null;
+ try
+ {
+ lines = LineReader.read(file);
+ }
+ catch (FileNotFoundException e)
+ {
+ System.out.println("not found: " + file);
+ System.exit(1);
+ }
+ double[][] array = LineReader.array(lines);
+ data.add(array);
+ addLabel(name, labels);
+ Util.verbose("array:\n" + toString(array));
+ }
+
+ XYSeriesCollection collection = Util.collection(data, labels,
+ names);
+
+ plot(collection, title, xlabel, ylabel, output);
+ }
+
+ static void load(String propFile)
+ {
+ try
+ {
+ if (propFile.equals("-"))
+ properties.load(System.in);
+ else
+ properties.load(new FileInputStream(propFile));
+ }
+ catch (FileNotFoundException e)
+ {
+ System.out.println(e);
+ System.exit(1);
+ }
+ catch (IOException e)
+ {
+ e.printStackTrace();
+ System.exit(1);
+ }
+ }
+
+ /**
+ Various plot properties. All are currently optional
+
+ Example.
+ Assume you want to plot a two-column table in file.data.
+ The first column is the x values and the second column
+ is the y values. See LineReader for details.
+
+ Your properties may include:
+ title = Plot
+ xlabel = size
+ ylabel = speed
+ label.file.data = legend text
+ width (output image width)
+ height (output image height)
+ xmin, xmax, ymin, ymax (auto-selected if not given)
+ */
+ static void scanProperties()
+ {
+ String tmp;
+ tmp = properties.getProperty("width");
+ if (tmp != null)
+ w = Integer.parseInt(tmp.trim());
+ tmp = properties.getProperty("height");
+ if (tmp != null)
+ h = Integer.parseInt(tmp.trim());
+ tmp = properties.getProperty("xmin");
+ if (tmp != null)
+ xmin = Double.parseDouble(tmp);
+ tmp = properties.getProperty("xmax");
+ if (tmp != null)
+ xmax = Double.parseDouble(tmp);
+ tmp = properties.getProperty("ymin");
+ if (tmp != null)
+ ymin = Double.parseDouble(tmp);
+ tmp = properties.getProperty("ymax");
+ if (tmp != null)
+ ymax = Double.parseDouble(tmp);
+ }
+
+ /**
+ Arrays.copyOfRange is a Java 1.6 feature.
+ This has the same signature.
+ */
+ /*
+ static String[] select(String[] s, int p, int q)
+ {
+ String[] result = new String[q-p];
+ int j = 0;
+ for (int i = p; i < q; i++)
+ result[j++] = s[i];
+ return result;
+ }
+ */
+
+ static void addLabel(String name,
+ List<String> labels)
+ {
+ String label = properties.getProperty("label."+name);
+ if (label == null)
+ label = "";
+ labels.add(label);
+ }
+
+ static boolean showShape(String name)
+ {
+ // System.out.println(name);
+ String mode = properties.getProperty("shape."+name);
+ // System.out.println(mode);
+ if ("none".equals(mode))
+ return false;
+ return true;
+ }
+
+ static String toString(double[][] array)
+ {
+ StringBuilder sb = new StringBuilder();
+ for (int i = 0; i < array.length; i++)
+ {
+ double[] row = array[i];
+ for (int j = 0; j < row.length; j++)
+ {
+ sb.append(array[i][j]);
+ if (j < row.length-1)
+ sb.append(" ");
+ }
+ sb.append("\n");
+ }
+ return sb.toString();
+ }
+}
Added: usertools/plotter/src/plotter/Util.java
===================================================================
--- usertools/plotter/src/plotter/Util.java (rev 0)
+++ usertools/plotter/src/plotter/Util.java 2011-01-21 17:39:55 UTC (rev 4022)
@@ -0,0 +1,58 @@
+package plotter;
+
+/**
+ * Plot data helpers.
+ * */
+
+import java.util.List;
+
+import org.jfree.data.xy.XYSeries;
+import org.jfree.data.xy.XYSeriesCollection;
+
+public class Util
+{
+ static boolean v = false;
+
+ /**
+ Stores the label as the Series key.
+ Stores the filename as the Series description.
+ */
+ static XYSeriesCollection collection(List<double[][]> data,
+ List<String> labels,
+ List<String> names)
+ {
+ final XYSeriesCollection collection = new XYSeriesCollection();
+
+ int count = 0;
+ for (double[][] d : data)
+ {
+ String label = "data: " + count;
+ try
+ {
+ label = labels.get(count);
+ }
+ catch (IndexOutOfBoundsException e)
+ {}
+
+ XYSeries series = new XYSeries(label);
+ for (int i = 0; i < d.length; i++)
+ series.add(d[i][0], d[i][1]);
+
+ series.setDescription(names.get(count));
+ collection.addSeries(series);
+ count++;
+ }
+ return collection;
+ }
+
+ public static void verbose(String s)
+ {
+ if (v)
+ System.out.println(s);
+ }
+
+ public static void verbose(boolean status)
+ {
+ v = status;
+ }
+}
More information about the Swift-commit
mailing list