/* Parser for pxgraph command line arguments and binary files.
@Author: Edward A. Lee and Christopher Hylands
@Version: $Id: PxgraphParser.java,v 1.22 2003/04/29 01:24:48 cxh Exp $
@Copyright (c) 1997-2003 The Regents of the University of California.
All rights reserved.
Permission is hereby granted, without written agreement and without
license or royalty fees, to use, copy, modify, and distribute this
software and its documentation for any purpose, provided that the
above copyright notice and the following two paragraphs appear in all
copies of this software.
IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY
FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.
THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE
PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF
CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
ENHANCEMENTS, OR MODIFICATIONS.
PT_COPYRIGHT_VERSION_2
COPYRIGHTENDKEY
@ProposedRating red (eal@eecs.berkeley.edu)
@AcceptedRating red (cxh@eecs.berkeley.edu)
*/
package ptolemy.plot.compat;
import ptolemy.plot.Plot;
import ptolemy.plot.CmdLineArgException;
import ptolemy.plot.PlotBox;
import java.io.BufferedInputStream;
import java.io.DataInputStream;
import java.io.EOFException;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.StreamTokenizer;
import java.io.StringReader;
import java.util.Vector;
import java.net.URL;
import java.net.MalformedURLException;
//////////////////////////////////////////////////////////////////////////
//// PxgraphParser
/**
This class provides backwards compatibility with an older plotting
program, pxgraph. It provides two methods, one for parsing command-line
arguments, and one for reading binary data from a file. In pxgraph,
the binary files have no format information; all format information
is provided by command line arguments.
Below we describe the pxgraph
arguments. The
text is based on the xgraph
Unix man page written
by David Harrison (University of California).
To see the command line options, you can type
pxgraph -help
.
The pxgraph
program draws a graph on a display given data
read from either data files or from standard input if no
files are specified. It can display up to 64 independent
data sets using different colors and/or line styles for each
set. It annotates the graph with a title, axis labels,
grid lines or tick marks, grid labels, and a legend. There
are options to control the appearance of most components of
the graph.
The input format is similar to graph(1G)
but differs
slightly. The data consists of a number of data sets. Data
sets are separated by a blank line. A new data set is also
assumed at the start of each input file. A data set consists
of an ordered list of points of the form directive
X Y
.
The directive is either draw
or move
and can
be omitted (Note that with binary data files, you must have a directive,
the above statement only applies to ascii format data files). If the
directive is draw
, a line will be drawn
between the previous point and the current point (if a line
graph is chosen). Specifying a move
directive tells
xgraph not to draw a line between the points. If the directive
is omitted, draw
is assumed for all points in a data
set except the first point where move
is assumed. The
move
directive is used most often to allow discontinuous
data in a data set.
After pxgraph
has read the data, it will create a new window
to graphically display the data.
Once the window has been opened, all of the data sets will
be displayed graphically (subject to the options explained
below) with a legend in the upper right corner of the
screen. To zoom in on a portion of the graph, depress a
mouse button in the window and sweep out a region. pxgraph
will then the window will be redrawn with just that portion of
the graph. pxgraph
also presents four control buttons in
the lower left corner of each window: Exit
,
Print
, HTML
and About
.
The Exit
button will exit the process. You can also
type Control-D
, Control-C
or q
to exit.
The Print
button brings up a print dialog window.
The About
button brings up a message about
pxgraph
.
The HTML
button prints an HTML file to stdout that
can be used to display the file with applet Plot
classes
(Experimental).
pxgraph
accepts a large number of command line options.
A list of these options is given below.
=WxH+X+Y
- Specifies the initial size and location of the pxgraph
window.
-
-<digit> <name>
- These options specify the data
set name for the corresponding data set. The digit
should be in the range 0 to 63. This name will be
used in the legend.
-bar
- Specifies that vertical bars should be drawn from the
data points to a base point which can be specified with
-brb
.
Usually, the -nl
flag is used with this option.
The point itself is located at the center of the bar.
-bb
- Draw a bounding box around the data region. This is
very useful if you prefer to see tick marks rather than
grid lines (see
-tk
).
Ignored in the Java version because the plotting area is a different
color than the border where the axes are labeled.
-bd
<color>
- This specifies the border color of the
pxgraph
window.
Unsupported in the Java version.
-bg
<color>
- Background color of the area where the labels and legend are rendered.
In the Java version, this argument takes hexadecimal color values
(
fffff
), not color names. Note that the background
of the data plotting region is always white because the dataset colors
were designed for a white background.
-bigendian
- Data files are in big-endian, or network binary format.
See the
-binary
command line argument documentation
below for details about the format.
If you are on a little-endian machine, such as a machine
with an Intel x86 chip, and you would like to read a binary
format file, created on a big-endian machine, such as a Sun SPARC,
use the -bigendian
flag.
-binary
- Data files are in a binary format.
The endian-ism of the data depends on which of the two
subformats below are chosen.
The
-binary
argument is the primary difference between xgraph
and pxgraph
. The
Ptolemy Project software
makes extensive use of -binary
.
There are two binary formats, both of which use 4 byte floats.
- If the first byte of the data file is not a
d
, then
we assume that the file contains 4 byte floats in big-endian ordering
with no plot commands.
- If the first byte of the data file is a
d
, then
we assume that the plot commands are encoded as single characters,
and the numeric data is a 4 byte float encoded in the
native endian format of the machine that the java interpreter is
running on.
The commands are encoded as follows:
-
d <4byte float> <4byte float>
- Draw a X, Y point
-
e
- End of dataset
-
n <dataset name>\n
- New dataset name, ends in
\n
-
m <4byte float> <4byte float>
- Move to a X, Y point.
To view a binary plot file under unix, we can use the
od
command. Note that the first character is a d
followed by eight bytes of data consisting of two floats of four bytes.
cxh@carson 324% od -c data/integrator1.plt
0000000 d \0 \0 \0 \0 \0 \0 \0 \0 d ? 200 \0 \0 ? 200
0000020 \0 \0 d @ \0 \0 \0 @ , 314 315 d @ @ \0 \0
For further information about endian-ism, see the
-bigendian
and -littleendian
command
line argument documentation.
-brb
<base>
- This specifies the base for a bar graph. By default,
the base is zero.
Unsupported in the Java version.
-brw
<width>
- This specifies the width of bars in a bar graph. The
amount is specified in the user units. By default,
a bar one pixel wide is drawn.
-bw
<size>
- Border width (in pixels) of the
pxgraph
window.
Unsupported in the Java version.
-db
- Causes xgraph to run in synchronous mode and prints out
the values of all known defaults.
-fg
<color>
- Foreground color. This color is used to draw all text
and the normal grid lines in the window.
In the Java version, this argument takes hexadecimal color values
(
fffff
), not color names.
-gw
-
Width, in pixels, of normal grid lines.
Unsupported in the Java version.
-gs
-
Line style pattern of normal grid lines.
-impulses
-
Draw a line from any plotted point down to the x axis.
(This argument is not present in the X11
pxgraph
,
but it is similar to -nl -bar
).
-lf
<fontname>
- Label font. All axis labels and grid labels are drawn
using this font.
Note that the Java version does not use X11 style font specification.
In the Java version, fonts may be specified as
The default is
helvetica-PLAIN-12
.
-littleendian
- Data files are in little-endian, or x86 binary format.
See the
-binary
command line argument documentation
above for details about the format.
If you are on a big-endian machine, such as a Sun Sparc,
and you would like to read a binary
format file created on a little-endian machine, such as Intel x86
machine, then use the -littleendian
flag.
-lnx
-
Specifies a logarithmic X axis. Grid labels represent
powers of ten. If
-lnx
is present, then
x values must be greater than zero.
-lny
-
Specifies a logarithmic Y axis. Grid labels represent
powers of ten. If
-lny
is present, then
y values must be greater than zero.
-lw
width
-
Specifies the width of the data lines in pixels. The
default is zero.
Unsupported in the Java version.
-lx
<xl,xh>
-
This option limits the range of the X axis to the
specified interval. This (along with
-ly
) can be used
to zoom in on a particularly interesting portion of a
larger graph.
-ly
<yl,yh>
-
This option limits the range of the Y axis to the
specified interval.
-m
-
Mark each data point with a distinctive marker. There
are eight distinctive markers used by xgraph. These
markers are assigned uniquely to each different line
style on black and white machines and varies with each
color on color machines.
-M
- Similar to
-m
but markers are assigned uniquely to each
eight consecutive data sets (this corresponds to each
different line style on color machines).
-nl
- Turn off drawing lines. When used with
-m
,
-M
, -p
, or -P
this can be used
to produce scatter plots. When used with -bar, it can be used to
produce standard bar graphs.
-o
output filename
- The name of the file to place the print output in. Currently
defaults to
/tmp/t.ps
. See also the
-print
option.
-p
- Marks each data point with a small marker (pixel
sized). This is usually used with the -nl option for
scatter plots.
-P
- Similar to
-p
but marks each pixel with a large dot.
-print
- Bring up the print dialog immediately upon startup. Unfortunately,
there is no way to automatically print in JDK1.1, the user must hit
the
Ok
button. See also the -o
option.
-rv
- Reverse video. On black and white displays, this will
invert the foreground and background colors. The
behaviour on color displays is undefined.
-t
<string>
- Title of the plot. This string is centered at the top
of the graph.
-tf
<fontname>
- Title font. This is the name of the font to use for
the graph title. See the
-lf
description above
for how to specify fonts.
The default is helvetica-BOLD-14
-tk
- This option causes
pxgraph
to draw tick marks rather
than full grid lines. The -bb
option is also useful
when viewing graphs with tick marks only.
-x
<unitname>
- This is the unit name for the X axis. Its default is "X".
-y
<unitname>
- This is the unit name for the Y axis. Its default is "Y".
-zg
<color>
- This is the color used to draw the zero grid line.
Unsupported in the Java version.
-zw
<width>
- This is the width of the zero grid line in pixels.
Unsupported in the Java version.
Various compatibility issues are documented above in bold.
Below are some other issues:
- The original
xgraph
program allowed many formatting
directives inside the file. This version only supports
draw
and move
.
- This original
xgraph
program allowed blank lines
to separate datasets. This version does not. Instead, use the
move X Y
directive.
- This version does not support X resources.
- The Java version of
pxgraph
takes longer to start up
than the X11 version. This is an inherent problem with standalone
Java applications. One guess is that most of the startup time comes
from paging in the shared libraries.
For further information about this tool, see the
Java Plot Website.
@author Edward A. Lee and Christopher Hylands
@version $Id: PxgraphParser.java,v 1.22 2003/04/29 01:24:48 cxh Exp $
@since Ptolemy II 0.4
@see PxgraphApplication
@see PxgraphApplet
*/
public class PxgraphParser {
/** Construct a parser to configure the specified plot.
*/
public PxgraphParser(Plot plot) {
_plot = plot;
}
///////////////////////////////////////////////////////////////////
//// public methods ////
/** Parse pxgraph style command-line arguments.
* @param args A set of command-line arguments.
* @return The number of arguments read.
* @exception CmdLineArgException If there is a problem parsing
* the command line arguments.
* @exception FileNotFoundException If a file is specified that is not
* found.
* @exception IOException If an error occurs reading an input file.
*/
public int parseArgs(String args[]) throws CmdLineArgException,
FileNotFoundException, IOException {
return parseArgs(args, null);
}
/** Parse pxgraph style command-line arguments, using the specified
* base URL for any relative URL references.
* @param args A set of command-line arguments.
* @param base A base URL for relative URL references, or null if
* there is none.
* @return The number of arguments read.
* @exception CmdLineArgException If there is a problem parsing
* the command line arguments.
* @exception FileNotFoundException If a file is specified that is not
* found.
* @exception IOException If an error occurs reading an input file.
*/
public int parseArgs(String args[], URL base) throws CmdLineArgException,
FileNotFoundException, IOException {
int i = 0, j, argumentsRead = 0;
// If we see both -nl and -bar, assume we do a stem plot.
boolean sawbararg = false; // Saw -bar arg.
boolean sawnlarg = false; // Saw -nl arg.
String savedmarks = "none"; // Save _marks in case we have -P -bar -nl.
_binary = false; // Read a binary xgraph file.
int width = 400, height = 400;
String arg;
String unsupportedOptions[] = {
"-bd", "-brb", "-bw", "-gw", "-lw", "-zg", "-zw"
};
while ( args != null && i < args.length && (args[i].startsWith("-") ||
args[i].startsWith("=")) ) {
arg = args[i++];
if (arg.startsWith("-")) {
// Search for unsupported options that take arguments
boolean badarg = false;
for (j = 0; j < unsupportedOptions.length; j++) {
if (arg.equals(unsupportedOptions[j])) {
System.err.println("Warning: pxgraph: " + arg +
" is not supported");
i++;
badarg = true;
}
}
if (badarg) continue;
if (arg.equals("-bb")) {
// We ignore -bb because the Java version of pxgraph plot
// region is a different color from the surrounding region.
continue;
} else if (arg.equals("-bg")) {
_plot.setBackground(Plot.getColorByName(args[i++]));
continue;
} else if (arg.equals("-brw")) {
// -brw BarWidth Bars:
// We default the baroffset to 0 here if the value does
// not include a comma.
double[] spec = _parseDoubles(args[i++]);
if (spec.length == 1) {
_plot.setBars(spec[0], 0);
} else {
_plot.setBars(spec[0], spec[1]);
}
continue;
} else if (arg.equals("-lf")) {
// -lf
_plot.setLabelFont(args[i++]);
continue;
} else if (arg.equals("-lx")) {
double[] spec = _parseDoubles(args[i++]);
if (spec.length == 1) {
throw new
CmdLineArgException("Failed to parse `"+arg+"'");
} else {
_plot.setXRange(spec[0], spec[1]);
}
continue;
} else if (arg.equals("-ly")) {
double[] spec = _parseDoubles(args[i++]);
if (spec.length == 1) {
throw new
CmdLineArgException("Failed to parse `"+arg+"'");
} else {
_plot.setYRange(spec[0], spec[1]);
}
continue;
} else if (arg.equals("-t")) {
// -t TitleText "An X Graph"
String title = args[i++];
_plot.setTitle(title);
continue;
} else if (arg.equals("-tf")) {
// -tf
_plot.setTitleFont(args[i++]);
continue;
} else if (arg.equals("-x")) {
// -x XUnitText XLabel:
_plot.setXLabel(args[i++]);
continue;
} else if (arg.equals("-y")) {
// -y YUnitText YLabel:
_plot.setYLabel(args[i++]);
continue;
} else if (arg.equals("-bar")) {
//-bar BarGraph Bars: on Marks: none Lines: off
// If we saw the -nl arg, then assume impulses
sawbararg = true;
if (sawnlarg) {
_plot.setImpulses(true);
} else {
_plot.setBars(true);
_plot.setMarksStyle("none");
}
_plot.setConnected(false);
continue;
} else if (arg.equals("-binary")) {
_binary = true;
_endian = _NATIVE_ENDIAN;
continue;
} else if (arg.equals("-bigendian")) {
_binary = true;
_endian = _BIG_ENDIAN;
continue;
} else if (arg.equals("-littleendian")) {
_binary = true;
_endian = _LITTLE_ENDIAN;
continue;
} else if (arg.equals("-db")) {
_debug = 10;
continue;
} else if (arg.equals("-debug")) {
// -debug is not in the original X11 pxgraph.
_debug = (int)Integer.valueOf(args[i++]).intValue();
continue;
} else if (arg.equals("-fg")) {
_plot.setForeground(PlotBox.getColorByName(args[i++]));
continue;
} else if (arg.equals("-help")) {
// -help is not in the original X11 pxgraph.
//_help();
continue;
} else if (arg.equals("-impulses")) {
// -impulses is not in the original X11 pxgraph.
_plot.setImpulses(true);
_plot.setConnected(false);
continue;
} else if (arg.equals("-lnx")) {
_plot.setXLog(true);
continue;
} else if (arg.equals("-lny")) {
_plot.setYLog(true);
continue;
} else if (arg.equals("-m")) {
// -m Markers Marks: various
_plot.setMarksStyle("various");
savedmarks = "various";
continue;
} else if (arg.equals("-M")) {
// -M StyleMarkers Marks: various
_plot.setMarksStyle("various");
savedmarks = "various";
continue;
} else if (arg.equals("-nl")) {
// -nl NoLines Lines: off
// If we saw the -bar arg, then assume impulses
sawnlarg = true;
if (sawbararg) {
// Restore the _marks in case we did -P -bar -nl
_plot.setMarksStyle(savedmarks);
_plot.setBars(false);
_plot.setImpulses(true);
}
_plot.setConnected(false);
continue;
} else if (arg.equals("-o")) {
// -o