简体   繁体   中英

How to number basecalls on chromatogram?

I've created an image of a chromatogram (of a dna sequence).

How would I go about putting a number over each basecall?

I can get the pixel length of the picture and the number of bases. If I divide these, I would get the average distance between basecalls, which would offer a good approximation of where each basecall would go.

How would I put numbers (1 - [number of bases]) along the top of the picture?

Here is a picture of the GUI and what the program looks like:

https://drive.google.com/file/d/0B5nGPfKaY21KVFVsaE9XSHJmWG8/view?usp=sharing

Here is the source code:

[When the getChrom button is pressed, the method renderTrace is executed, rendering the trace.]

public class TraceRender extends javax.swing.JFrame {
public TraceRender() {
    initComponents();
}

/**
 * This method is called from within the constructor to initialize the form.
 * WARNING: Do NOT modify this code. The content of this method is always
 * regenerated by the Form Editor.
 */
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">                          
private void initComponents() {

    fileChooser = new javax.swing.JFileChooser();
    textarea = new javax.swing.JTextField();
    getChrom = new javax.swing.JButton();
    ScrollPane = new javax.swing.JScrollPane();
    Label = new javax.swing.JLabel();
    text = new javax.swing.JTextField();
    Menu = new javax.swing.JMenuBar();
    File = new javax.swing.JMenu();
    Open = new javax.swing.JMenuItem();
    Exit = new javax.swing.JMenuItem();
    Edit = new javax.swing.JMenu();
    Documentation = new javax.swing.JMenu();
    Help = new javax.swing.JMenu();

    fileChooser.setDialogTitle("This is my open dialog");
    fileChooser.setFileFilter(new myCustomFilter());

    setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

    textarea.setEditable(false);
    textarea.setText("ABSOLUTE PATH");

    getChrom.setText("Execute");
    getChrom.addActionListener(new java.awt.event.ActionListener() {
        public void actionPerformed(java.awt.event.ActionEvent evt) {
            getChromActionPerformed(evt);
        }
    });

    Label.setText("[AVI]-Error.noImageLoaded");
    ScrollPane.setViewportView(Label);

    text.setText("nothing");

    File.setText("FILE");

    Open.setText("Get File");
    Open.addActionListener(new java.awt.event.ActionListener() {
        public void actionPerformed(java.awt.event.ActionEvent evt) {
            OpenActionPerformed(evt);
        }
    });
    File.add(Open);

    Exit.setText("Close Program");
    Exit.addActionListener(new java.awt.event.ActionListener() {
        public void actionPerformed(java.awt.event.ActionEvent evt) {
            ExitActionPerformed(evt);
        }
    });
    File.add(Exit);

    Menu.add(File);

    Edit.setText("EDIT");
    Menu.add(Edit);

    Documentation.setText("DOCUMENTATION");
    Menu.add(Documentation);

    Help.setText("HELP");
    Menu.add(Help);

    setJMenuBar(Menu);

    javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
    getContentPane().setLayout(layout);
    layout.setHorizontalGroup(
        layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
        .addGroup(layout.createSequentialGroup()
            .addContainerGap()
            .addComponent(textarea, javax.swing.GroupLayout.PREFERRED_SIZE, 1005, javax.swing.GroupLayout.PREFERRED_SIZE)
            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 79, Short.MAX_VALUE)
            .addComponent(getChrom, javax.swing.GroupLayout.PREFERRED_SIZE, 291, javax.swing.GroupLayout.PREFERRED_SIZE)
            .addGap(49, 49, 49))
        .addComponent(ScrollPane, javax.swing.GroupLayout.Alignment.TRAILING)
        .addGroup(layout.createSequentialGroup()
            .addGap(33, 33, 33)
            .addComponent(text, javax.swing.GroupLayout.PREFERRED_SIZE, 630, javax.swing.GroupLayout.PREFERRED_SIZE)
            .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
    );
    layout.setVerticalGroup(
        layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
        .addGroup(layout.createSequentialGroup()
            .addContainerGap()
            .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                .addComponent(textarea, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addComponent(getChrom))
            .addGap(48, 48, 48)
            .addComponent(ScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 265, javax.swing.GroupLayout.PREFERRED_SIZE)
            .addGap(53, 53, 53)
            .addComponent(text, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
            .addContainerGap(113, Short.MAX_VALUE))
    );

    pack();
}// </editor-fold>                        

private void OpenActionPerformed(java.awt.event.ActionEvent evt) {                                     
    // TODO add your handling code here:

    int returnVal = fileChooser.showOpenDialog(this);
    if (returnVal == JFileChooser.APPROVE_OPTION) {
        File file = fileChooser.getSelectedFile();
        textarea.setText(String.valueOf(file.getAbsolutePath()));
    } else {
        System.out.println("File access cancelled by user.");
    }

}                                    

private void ExitActionPerformed(java.awt.event.ActionEvent evt) {                                     
    // TODO add your handling code here:
    System.exit(0);
}                                    

private void getChromActionPerformed(java.awt.event.ActionEvent evt) {                                         
    try {
        // TODO add your handling code here:
        renderTrace();
    } catch (IOException | UnsupportedChromatogramFormatException ex) {
        Logger.getLogger(TraceRender.class.getName()).log(Level.SEVERE, null, ex);
    }
}                                        

private void renderTrace() throws IOException, UnsupportedChromatogramFormatException {
    ABIFChromatogram abiChrom = new ABIFChromatogram();

    File abi = new File(textarea.getText());

    ABITrace abiTrace = new ABITrace(abi);
    ABIFParser abiParse = new ABIFParser(abi);
    ChromatogramFactory chromFactory = new ChromatogramFactory();

    Chromatogram chrom = ChromatogramFactory.create(abi);

    ChromatogramGraphic gfx = new ChromatogramGraphic(chrom);

    gfx.setHeight(240);
    gfx.setHorizontalScale(2.0f);
    // 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.TRUE);
    gfx.setOption(ChromatogramGraphic.Option.DRAW_CALL_SEPARATORS,
            Boolean.TRUE);

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

    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()));
    }
    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));

    text.setText(String.valueOf(gfx.getWidth()));
    ImageIcon ii = new ImageIcon(bi);
    Label.setIcon(ii);
    /*
    try {
        ImageIO.write(bi, "png", new File("gfx-image.png"));
    } catch (IOException ex) {
        ex.printStackTrace();
    }
    */


}

/**
 * @param args the command line arguments
 */
public static void main(String args[]) {
    /* Set the Nimbus look and feel */
    //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
    /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
     * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html 
     */
    try {
        for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
            if ("Nimbus".equals(info.getName())) {
                javax.swing.UIManager.setLookAndFeel(info.getClassName());
                break;
            }
        }
    } catch (ClassNotFoundException ex) {
        java.util.logging.Logger.getLogger(TraceRender.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
    } catch (InstantiationException ex) {
        java.util.logging.Logger.getLogger(TraceRender.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
    } catch (IllegalAccessException ex) {
        java.util.logging.Logger.getLogger(TraceRender.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
    } catch (javax.swing.UnsupportedLookAndFeelException ex) {
        java.util.logging.Logger.getLogger(TraceRender.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
    }
    //</editor-fold>

    /* Create and display the form */
    java.awt.EventQueue.invokeLater(new Runnable() {
        public void run() {
            new TraceRender().setVisible(true);
        }
    });
}

class myCustomFilter extends javax.swing.filechooser.FileFilter {

    @Override
    public boolean accept(File file) {
        // Allow only directories, or files with ".txt" extension
        return file.isDirectory() || file.getAbsolutePath().endsWith(".ab1");
    }

    @Override
    public String getDescription() {
        // This description will be displayed in the dialog,
        // hard-coded = ugly, should be done via I18N
        return "ABIF Files (*.ab1)";
    }
}


// Variables declaration - do not modify                     
private javax.swing.JMenu Documentation;
private javax.swing.JMenu Edit;
private javax.swing.JMenuItem Exit;
private javax.swing.JMenu File;
private javax.swing.JMenu Help;
private javax.swing.JLabel Label;
private javax.swing.JMenuBar Menu;
private javax.swing.JMenuItem Open;
private javax.swing.JScrollPane ScrollPane;
private javax.swing.JFileChooser fileChooser;
private javax.swing.JButton getChrom;
private javax.swing.JTextField text;
private javax.swing.JTextField textarea;
// End of variables declaration                   
}

In my testings, this worked (assuming that the integer argument that getCallboxBounds() takes is the index, not the number to be displayed):

g.setColor(Color.BLACK);
for (int i = 9; i < sequenceLength; i += 10) {
    String str = String.valueOf(i + 1);
    g.drawString(str,
            getCallboxBounds(i).getX()
                    + (getCallboxBounds(i).getWidth() - g.getFontMetrics().stringWidth(str)) / 2,
            g.getFontMetrics().getHeight());
}

If you want to display every number (not just the ones where % 10 == 0 ), then change

for (int i = 9; i < sequenceLength; i += 10) {

to

for (int i = 0; i < sequenceLength; i++) {

I hope it also works for you.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM