[Biojava-l] Using ChromatogramGraphic
Rhett Sutphin
rhett-sutphin at uiowa.edu
Tue Jun 17 17:41:41 EDT 2003
Hi,
A couple of folks have asked for examples of the features of the
Chromatogram support that we recently contributed to BioJava. This
message will provide some info on using ChromatogramGraphic, the
Java2D-based class for rendering chromatograms.
First, there's Chromatogram Viewer, which is a simple Java Web Start
application for, well, viewing chromatograms. I don't have permission
to release the source (yet), but you can use it for free. (I
anticipate that I will be able to release the source for at least the
swing components that are directly involved in viewing the chromatogram
in the not-to-distant future.) You can run it from:
http://pdb.eng.uiowa.edu/~rsutphin/public-webstart/chromatogram-
viewer.jnlp . You'll need a 1.3+ series JRE and Java Web Start 1.0 or
later. Note that Sun's JRE version 1.4+ come with Java Web Start, as
do all JREs on OS X 10.1+.
In addition to looking at the chromatogram, Chromatogram Viewer allows
you to save all or part of the chromatogram as a PNG image and to copy
all or part of the sequence to the system clipboard. The checkboxes &
sliders in the panel on the right of the interface allow for twiddling
many of output options available in ChromatogramGraphic. (Note that
the "Fixed Base Width" option reflects functionality not incorporated
into the 1.30 released version of ChromatogramGraphic. I just
committed it to CVS today.)
But probably more useful for developers is the attached source code.
It is a command-line demo program that reads in a chromatogram and
outputs an image. It uses the Image I/O API (new in JDK 1.4), and is
capable of writing in any format Image I/O supports. (By default, this
is just PNG and JPEG, but there are more available:
http://java.sun.com/products/java-media/jai/ ).
-------------- next part --------------
/*
* BioJava development code
*
* This code may be freely distributed and modified under the
* terms of the GNU Lesser General Public Licence. This should
* be distributed with the code. If you do not have a copy,
* see:
*
* http://www.gnu.org/copyleft/lesser.html
*
* Copyright for this code is held jointly by the individual
* authors. These should be listed in @author doc comments.
*
* For more information on the BioJava project and its aims,
* or to join the biojava-l mailing list, visit the home page
* at:
*
* http://www.biojava.org/
*
*/
package chromatogram;
import java.awt.image.BufferedImage;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.io.IOException;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Iterator;
import javax.imageio.ImageIO;
import javax.imageio.ImageWriter;
import javax.imageio.stream.FileImageOutputStream;
import org.biojava.bio.chromatogram.Chromatogram;
import org.biojava.bio.chromatogram.ChromatogramFactory;
import org.biojava.bio.chromatogram.UnsupportedChromatogramFormatException;
import org.biojava.bio.chromatogram.graphic.ChromatogramGraphic;
/**
* A command-line utility for dumping a chromatogram to an image using
* <code>javax.imageio</code>. Demos {@link ChromatogramFactory} and
* {@link ChromatogramGraphic}. Run it with no parameters to get help with
* command line options. Requires JDK 1.4.
*/
public class Chromat2Image {
private static final int OUT_HEIGHT = 240;
private static final float OUT_HORIZ_SCALE = 2.0f;
private static final String USAGE =
"USAGE:\n"
+ "Chromat2Image chromat-file output-image-file\n"
+ " chromat-file\n"
+ " - The chromatogram file from which to create the image\n"
+ " output-image-file\n"
+ " - The name of the file to which the chromatogram image\n"
+ " will be written. The format will be determined from\n"
+ " the extension, which must be png or jpg (unless there\n"
+ " are additional image writers on the classpath). PNG\n"
+ " is highly recommended over JPEG due to the discrete-\n"
+ " tone nature of chromatogram images.\n";
public static void main(String[] args) {
if (args.length != 2) {
System.err.println("Invalid args.\n");
System.err.println(USAGE);
System.exit(1);
}
/* create Chromatogram object */
File infile = new File(args[0]);
if (!infile.canRead()) {
System.err.println("Can't read " + infile);
System.exit(1);
}
Chromatogram c = null;
try {
c = ChromatogramFactory.create(infile);
} catch (UnsupportedChromatogramFormatException ucfe) {
System.err.println("Unsupported chromatogram format (" + ucfe.getMessage());
System.exit(1);
} catch (IOException ioe) {
System.err.println("Problem reading from " + infile + " (" + ioe.getMessage() + ")");
System.exit(1);
}
/* find appropriate ImageWriter */
String outExt = null;
int lastdot = args[1].lastIndexOf('.');
if (lastdot >= 0) {
outExt = args[1].substring(lastdot+1);
}
if (outExt == null || outExt.length() == 0) {
System.err.println("No extension on output file, so will use PNG format");
outExt = "png";
}
Iterator writers = ImageIO.getImageWritersBySuffix(outExt);
if (!writers.hasNext()) {
System.err.println("No image writer found for suffix '" + outExt + "'");
System.exit(1);
}
ImageWriter iw = (ImageWriter) writers.next();
/* build output stream */
File outfile = new File(args[1]);
FileImageOutputStream out = null;
try {
out = new FileImageOutputStream(outfile);
} catch (FileNotFoundException fnfe) {
System.err.println("Can't write to " + outfile + " (" + fnfe.getMessage() + ")");
System.exit(1);
} catch (IOException ioe) {
System.err.println("Problem writing to " + outfile + " (" + ioe.getMessage() + ")");
System.exit(1);
}
/* create ChromatogramGraphic */
ChromatogramGraphic gfx = new ChromatogramGraphic(c);
gfx.setHeight(OUT_HEIGHT);
gfx.setHorizontalScale(OUT_HORIZ_SCALE);
// set some options that affect the output
// turn off filled-in "callboxes"
gfx.setOption(ChromatogramGraphic.Option.DRAW_CALL_A, Boolean.FALSE);
gfx.setOption(ChromatogramGraphic.Option.DRAW_CALL_C, Boolean.FALSE);
gfx.setOption(ChromatogramGraphic.Option.DRAW_CALL_G, Boolean.FALSE);
gfx.setOption(ChromatogramGraphic.Option.DRAW_CALL_T, Boolean.FALSE);
gfx.setOption(ChromatogramGraphic.Option.DRAW_CALL_OTHER, Boolean.FALSE);
// this option controls whether each trace/callbox/etc is scaled/positioned
// individually, or whether the scaling is done on all shapes at the level
// of the graphics context
// enabling this option is recommended for higher-quality output
gfx.setOption(ChromatogramGraphic.Option.USE_PER_SHAPE_TRANSFORM, Boolean.TRUE);
/* create output image */
BufferedImage bi = new BufferedImage(
gfx.getWidth(),
gfx.getHeight(),
BufferedImage.TYPE_INT_RGB);
Graphics2D g2 = bi.createGraphics();
g2.setBackground(Color.white);
g2.clearRect(0, 0, bi.getWidth(), bi.getHeight());
if (g2.getClip() == null) {
g2.setClip(new Rectangle(0, 0, bi.getWidth(), bi.getHeight()));
}
/* draw chromatogram into image */
// turn on AA for nicer output
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
// the main event
gfx.drawTo(g2);
// work-around an OS X bug where sometimes the last Shape drawn
// doesn't show up in the output
g2.draw(new java.awt.Rectangle(-10, -10, 5, 5));
/* write image out */
iw.setOutput(out);
try {
iw.write(bi);
out.close();
} catch (IOException ioe) {
System.err.println("Problem writing to " + outfile + " (" + ioe.getMessage() + ")");
System.exit(1);
}
System.exit(0);
}
}
-------------- next part --------------
The chromatogram-specific parts are:
/* create Chromatogram object */
[...]
Chromatogram c = null;
try {
c = ChromatogramFactory.create(infile);
} catch (UnsupportedChromatogramFormatException ucfe) {
System.err.println("Unsupported chromatogram format (" +
ucfe.getMessage());
System.exit(1);
} catch (IOException ioe) {
System.err.println("Problem reading from " + infile + " ("
+ ioe.getMessage() + ")");
System.exit(1);
}
This chunk uses ChromatogramFactory to create a Chromatogram object
from a File. Note that we don't have to know the format of the file
(ABI and SCF are supported).
/* create ChromatogramGraphic */
ChromatogramGraphic gfx = new ChromatogramGraphic(c);
gfx.setHeight(OUT_HEIGHT);
gfx.setHorizontalScale(OUT_HORIZ_SCALE);
// set some options that affect the output
// turn off filled-in "callboxes"
gfx.setOption(ChromatogramGraphic.Option.DRAW_CALL_A,
Boolean.FALSE);
gfx.setOption(ChromatogramGraphic.Option.DRAW_CALL_C,
Boolean.FALSE);
gfx.setOption(ChromatogramGraphic.Option.DRAW_CALL_G,
Boolean.FALSE);
gfx.setOption(ChromatogramGraphic.Option.DRAW_CALL_T,
Boolean.FALSE);
gfx.setOption(ChromatogramGraphic.Option.DRAW_CALL_OTHER,
Boolean.FALSE);
// this option controls whether each trace/callbox/etc is
scaled/positioned
// individually, or whether the scaling is done on all shapes
at the level
// of the graphics context
// enabling this option is recommended for higher-quality output
gfx.setOption(ChromatogramGraphic.Option.USE_PER_SHAPE_TRANSFORM,
Boolean.TRUE);
This chunk creates the ChromatogramGraphic object which will be used to
draw c, and sets several options that affect the output. The javadoc
for org.biojava.bio.chromatogram.graphic.ChromatogramGraphic.Option is
a detailed list of the available options, the expected parameter types,
and the default values.
/* draw chromatogram into image */
gfx.drawTo(g2);
This line actually does the drawing. In this case, the Graphics2D
object g2 was retrieved from a BufferedImage, but it just as easily
could have been the Graphics2D instance you get as a parameter to
paintComponent in a JComponent.
So that's the basics. Please ask if you have any questions.
Rhett
--
Rhett Sutphin
Research Assistant (Software)
Coordinated Laboratory for Computational Genomics
and the Center for Macular Degeneration
University of Iowa - Iowa City - Iowa - 52246
mailto:rhett-sutphin at uiowa.edu
More information about the Biojava-l
mailing list