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/ ).

/*
 *                    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 [EMAIL PROTECTED] ChromatogramFactory} and 
 * [EMAIL PROTECTED] 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);
    }
}


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:[EMAIL PROTECTED]
_______________________________________________
Biojava-l mailing list  -  [EMAIL PROTECTED]
http://biojava.org/mailman/listinfo/biojava-l

Reply via email to