Skip to content
Snippets Groups Projects
LookSeqPanel.java 16.6 KiB
Newer Older
  • Learn to ignore specific revisions
  • tjc's avatar
    tjc committed
    /* LookSeqFrame.java
     *
     * created: 2009
     *
     * This file is part of Artemis
     *
     * Copyright(C) 2009  Genome Research Limited
     *
     * This program is free software; you can redistribute it and/or
     * modify it under the terms of the GNU General Public License
     * as published by the Free Software Foundation; either version 2
     * of the License, or(at your option) any later version.
     *
     * This program is distributed in the hope that it will be useful,
     * but WITHOUT ANY WARRANTY; without even the implied warranty of
     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     * GNU General Public License for more details.
     *
     * You should have received a copy of the GNU General Public License
     * along with this program; if not, write to the Free Software
     * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
     *
     */
    
    package uk.ac.sanger.artemis.components.alignment;
    
    import java.awt.Dimension;
    import java.awt.Graphics;
    
    tjc's avatar
    tjc committed
    import java.awt.GridBagConstraints;
    import java.awt.GridBagLayout;
    
    tjc's avatar
    tjc committed
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.awt.event.MouseAdapter;
    import java.awt.event.MouseEvent;
    import java.awt.event.MouseListener;
    import java.net.MalformedURLException;
    import java.net.URL;
    
    import javax.swing.ButtonGroup;
    import javax.swing.ImageIcon;
    
    tjc's avatar
    tjc committed
    import javax.swing.JCheckBox;
    
    tjc's avatar
    tjc committed
    import javax.swing.JCheckBoxMenuItem;
    import javax.swing.JFrame;
    
    tjc's avatar
    tjc committed
    import javax.swing.JLabel;
    
    tjc's avatar
    tjc committed
    import javax.swing.JMenuItem;
    
    tjc's avatar
    tjc committed
    import javax.swing.JOptionPane;
    
    tjc's avatar
    tjc committed
    import javax.swing.JPanel;
    import javax.swing.JPopupMenu;
    import javax.swing.JSeparator;
    
    tjc's avatar
    tjc committed
    import javax.swing.JTextField;
    
    tjc's avatar
    tjc committed
    
    
    tjc's avatar
    tjc committed
    import uk.ac.sanger.artemis.circular.TextFieldInt;
    
    tjc's avatar
    tjc committed
    import uk.ac.sanger.artemis.components.DisplayAdjustmentEvent;
    import uk.ac.sanger.artemis.components.DisplayAdjustmentListener;
    import uk.ac.sanger.artemis.components.FeatureDisplay;
    import uk.ac.sanger.artemis.components.SwingWorker;
    
    public class LookSeqPanel extends JPanel
                              implements DisplayAdjustmentListener
    {
      private static final long serialVersionUID = 1L;
      /** image icon */
      private ImageIcon ii;
    
    tjc's avatar
    tjc committed
      /** URL lookseq service */
    
    tjc's avatar
    tjc committed
      private String urlStr;
    
    tjc's avatar
    tjc committed
      /** the query options (appended to lookseq service url) */
    
    tjc's avatar
    tjc committed
      private String queryStr;
    
    tjc's avatar
    tjc committed
    
    
    tjc's avatar
    tjc committed
      private FeatureDisplay feature_display;
      private int lastStart = -1;
      private int lastEnd   = -1;
    
    tjc's avatar
    tjc committed
      private int drawCrossHairAt = -1;
    
    tjc's avatar
    tjc committed
      final JPopupMenu popup  = new JPopupMenu("Plot Options");
    
    tjc's avatar
    tjc committed
      private static org.apache.log4j.Logger logger4j = 
        org.apache.log4j.Logger.getLogger(LookSeqPanel.class);
    
    tjc's avatar
    tjc committed
    
      public LookSeqPanel()
      {
        super();
        setUpPopupMenu();
      }
      
      public LookSeqPanel(URL url)
      {
        super();
        ii = new ImageIcon(url);
        setUpPopupMenu();
      }
      
      public LookSeqPanel(final String urlStr, final String queryStr)
      {
        super();
        setImage(urlStr, queryStr);
        setUpPopupMenu();
      }
      
    
    tjc's avatar
    tjc committed
      /**
       * Build the popup menu.
       */
    
    tjc's avatar
    tjc committed
      private void setUpPopupMenu()
    
    tjc's avatar
    tjc committed
        JCheckBoxMenuItem optionCoverage = new JCheckBoxMenuItem("Coverage", false);
    
    tjc's avatar
    tjc committed
        optionCoverage.addActionListener(new ActionListener()
        {
          public void actionPerformed(ActionEvent e)
          {
            queryStr = queryStr.replaceFirst("view=\\w+", "view=coverage");
            setImage(urlStr, queryStr);
            revalidate();
          }
        });
        popup.add(optionCoverage);
        
    
    tjc's avatar
    tjc committed
        JCheckBoxMenuItem optionIndel = new JCheckBoxMenuItem("Paired reads", true);
    
    tjc's avatar
    tjc committed
        optionIndel.addActionListener(new ActionListener()
        {
          public void actionPerformed(ActionEvent e)
          {
            queryStr = queryStr.replaceFirst("view=\\w+", "view=indel");
            setImage(urlStr, queryStr);
            revalidate();
          }
        });
        popup.add(optionIndel);
        
    
    tjc's avatar
    tjc committed
        JCheckBoxMenuItem optionPileup = new JCheckBoxMenuItem("Pileup", false);
        optionPileup.addActionListener(new ActionListener()
        {
          public void actionPerformed(ActionEvent e)
          {
            queryStr = queryStr.replaceFirst("view=\\w+", "view=pileup");
            setImage(urlStr, queryStr);
            revalidate();
          }
        });
        popup.add(optionPileup);
        
    
    tjc's avatar
    tjc committed
        ButtonGroup group = new ButtonGroup();
        group.add(optionCoverage);
        group.add(optionIndel);
    
    tjc's avatar
    tjc committed
        group.add(optionPileup);
    
    tjc's avatar
    tjc committed
        
        popup.add(new JSeparator());
        final JCheckBoxMenuItem perfectIndel = 
          new JCheckBoxMenuItem("Show perfect paired matches", true);
        perfectIndel.addActionListener(new ActionListener()
        {
          public void actionPerformed(ActionEvent e)
          {
            setDisplayOption(perfectIndel.isSelected(), "perfect");
          }
        });
        popup.add(perfectIndel);
        
        final JCheckBoxMenuItem snps = 
          new JCheckBoxMenuItem("Show paired reads with SNPs", true);
        snps.addActionListener(new ActionListener()
        {
          public void actionPerformed(ActionEvent e)
          {
            setDisplayOption(snps.isSelected(), "snps");
          }
        });
        popup.add(snps);
        
        final JCheckBoxMenuItem inversions = 
          new JCheckBoxMenuItem("Show inversions", true);
        inversions.addActionListener(new ActionListener()
        {
          public void actionPerformed(ActionEvent e)
          {
            setDisplayOption(inversions.isSelected(), "inversions");
          }
        });
        popup.add(inversions);
        
        final JCheckBoxMenuItem single = 
    
    tjc's avatar
    tjc committed
          new JCheckBoxMenuItem("Show single reads", false);
    
    tjc's avatar
    tjc committed
        single.addActionListener(new ActionListener()
        {
          public void actionPerformed(ActionEvent e)
          {
            setDisplayOption(single.isSelected(), "single");
          }
        });
        popup.add(single);
        
        final JCheckBoxMenuItem inversions_ext = 
    
    tjc's avatar
    tjc committed
          new JCheckBoxMenuItem("Show inversions_ext", false);
    
    tjc's avatar
    tjc committed
        inversions_ext.addActionListener(new ActionListener()
        {
          public void actionPerformed(ActionEvent e)
          {
            setDisplayOption(inversions_ext.isSelected(), "inversions_ext");
          }
        });
        popup.add(inversions_ext);
        
        final JCheckBoxMenuItem pairlinks = 
          new JCheckBoxMenuItem("Show link pairs", true);
        pairlinks.addActionListener(new ActionListener()
        {
          public void actionPerformed(ActionEvent e)
          {
    
    tjc's avatar
    tjc committed
            setDisplayOption(pairlinks.isSelected(), "pairlinks");
    
    tjc's avatar
    tjc committed
          }
        });
        popup.add(pairlinks);
        
        final JCheckBoxMenuItem potsnps = 
          new JCheckBoxMenuItem("Show known SNPs", true);
        potsnps.addActionListener(new ActionListener()
        {
          public void actionPerformed(ActionEvent e)
          {
    
    tjc's avatar
    tjc committed
            setDisplayOption(potsnps.isSelected(), "potsnps");
    
    tjc's avatar
    tjc committed
          }
        });
        popup.add(potsnps);
        
        final JCheckBoxMenuItem uniqueness = 
          new JCheckBoxMenuItem("Show uniqueness", true);
        uniqueness.addActionListener(new ActionListener()
        {
          public void actionPerformed(ActionEvent e)
          {
            setDisplayOption(inversions_ext.isSelected(), "uniqueness");
          }
        });
        popup.add(uniqueness);
    
    tjc's avatar
    tjc committed
        popup.add(new JSeparator());
    
    tjc's avatar
    tjc committed
        
    
    tjc's avatar
    tjc committed
        final JMenuItem setIndelMaxSize = new JMenuItem("Maximum InDel Size...");
        setIndelMaxSize.addActionListener(new ActionListener()
        {
          public void actionPerformed(ActionEvent e)
          {
            setMaxIndelSize();
          }
        });
        popup.add(setIndelMaxSize);
    
    tjc's avatar
    tjc committed
        addMouseListener(mouseListener);
      }
    
      public void setImage(final String urlStr, final String queryStr)
      {
        this.urlStr = urlStr;
        this.queryStr = queryStr;
        
        try
        {
          ii = new ImageIcon(new URL(urlStr+queryStr));
          setPreferredSize(new Dimension(ii.getIconWidth(),
              ii.getIconHeight()));
    
          logger4j.debug("LookSeq URL    :: "+urlStr+queryStr);
          logger4j.debug("Proxy Settings :: "+System.getProperty("http.proxyHost")+":"+
                                              System.getProperty("http.proxyPort"));
    
    tjc's avatar
    tjc committed
        }
        catch (MalformedURLException e)
        {
          e.printStackTrace();
        }
      }
      
      /**
      * Override the paintComponent
      */
      public void paintComponent(Graphics g)
      {
        super.paintComponent(g);
        if(ii != null)
          ii.paintIcon(this,g,0,0);
        
    
    tjc's avatar
    tjc committed
        if(drawCrossHairAt > -1)
          drawCrossHair(g);
    
    tjc's avatar
    tjc committed
      }
      
    
    tjc's avatar
    tjc committed
      private void drawCrossHair(Graphics g)
    
    tjc's avatar
    tjc committed
      {
    
    tjc's avatar
    tjc committed
        int xpos = (int) ((((float)drawCrossHairAt/(lastEnd-lastStart)))*getWidth());
        g.drawLine(xpos, 0, xpos, getHeight());
        g.drawString(Integer.toString(drawCrossHairAt+lastStart), xpos+1, 10);
      }
      
    
    tjc's avatar
    tjc committed
      /**
       * Set the maximum size.
       */
      private void setMaxIndelSize()
      {
        JPanel panel = new JPanel(new GridBagLayout());
        GridBagConstraints c = new GridBagConstraints();
       
        String maxdist = getText(queryStr,"maxdist=");
        c.gridx = 0;
        c.gridy = 0;
        panel.add(new JLabel("Set maximum indel size"), c);
        
        TextFieldInt maxIndel = new TextFieldInt();
        maxIndel.setColumns(10);
        c.gridx = 1;
        c.anchor = GridBagConstraints.WEST;
        panel.add(maxIndel, c);
        
        JCheckBox defaultValue = new JCheckBox("use default"); 
        c.gridy = 1;
        panel.add(defaultValue, c);
        
        if(maxdist == null)
          defaultValue.setSelected(true);
        else
        {
          defaultValue.setSelected(false);
          maxIndel.setValue(Integer.parseInt(maxdist));
        }
        
        String window_options[] = { "Set", "Cancel" };
        int select = JOptionPane.showOptionDialog(null, 
            panel, "Lookseq Options", JOptionPane.DEFAULT_OPTION,
            JOptionPane.QUESTION_MESSAGE, null, window_options,
            window_options[0]);
    
        if(select == 1)
          return;
        if(defaultValue.isSelected())
          queryStr = queryStr.replaceFirst(
              "&maxdist=\\w+", "");
        else
        {
          if(queryStr.indexOf("maxdist=") > -1)
            queryStr = queryStr.replaceFirst(
                "&maxdist=\\w+", "&maxdist="+maxIndel.getText().trim());
          else
            queryStr = queryStr.concat("&maxdist="+maxIndel.getText().trim());
        }
        
        setImage(urlStr, queryStr);
        repaint();
        revalidate();
      }
      
      /**
       * Called when the display is changed.
       */
    
    tjc's avatar
    tjc committed
      public void displayAdjustmentValueChanged(final DisplayAdjustmentEvent event)
      {   
    
    tjc's avatar
    tjc committed
        SwingWorker worker = new SwingWorker()
        {
          public Object construct()
          {
    
    tjc's avatar
    tjc committed
            if(lastStart == event.getStart() && lastEnd == event.getEnd())
              return null;
            try
            {
              Thread.currentThread().sleep(500);
            }
            catch (InterruptedException e)
            {
              e.printStackTrace();
            }
            
            if(event.getStart() != ((FeatureDisplay)event.getSource()).getForwardBaseAtLeftEdge())
              return null;
          
            lastStart = event.getStart();
            lastEnd   = event.getEnd();
    
    tjc's avatar
    tjc committed
            setDisplay(lastStart, lastEnd, event);
    
    tjc's avatar
    tjc committed
            return null;
          }
        };
        worker.start();
      }
      
    
    tjc's avatar
    tjc committed
      /**
       * Set the start and end base positions to display.
       * @param start
       * @param end
       * @param event
       */
      public void setDisplay(int start,
                             int end,
                             DisplayAdjustmentEvent event)
      {
        queryStr = queryStr.replaceFirst("from=\\d+", "from="+Integer.toString(start));
        queryStr = queryStr.replaceFirst("to=\\d+", "to="+Integer.toString(end));    
    
        if(feature_display != null)
        {
          int width = feature_display.getSize().width;
          
          int possible_last_base =
            (int)(feature_display.getForwardBaseAtLeftEdge() + 
                  feature_display.getMaxVisibleBases());
          
          // scale the image when scrolled passed the sequence length
          if(possible_last_base > end)
            width = (int)(width * (float)((float)(end-start)/
                                          (float)(possible_last_base-start)));
          
          queryStr = queryStr.replaceFirst("width=\\d+", "width="+Integer.toString(width));
        }
        
        setImage(urlStr, queryStr);
        drawCrossHairAt = -1;
        repaint();
        if(event == null || 
           event.getType() == DisplayAdjustmentEvent.SCALE_ADJUST_EVENT)
          revalidate();
      }
      
      /**
       * Utility for changing display options.
       * @param selected
       * @param option
       */
    
    tjc's avatar
    tjc committed
      private void setDisplayOption(boolean selected, String option)
      {
        if(selected)
          queryStr = queryStr.replaceFirst("display=", "display=\\|"+option);
        else
          queryStr = queryStr.replaceAll("\\|"+option, "");
        
        setImage(urlStr, queryStr);
        repaint();
        revalidate();
      }
      
    
    tjc's avatar
    tjc committed
      /**
       * Get the base position from the pixel position on the panel
       * @param position
       * @return
       */
    
    tjc's avatar
    tjc committed
      private int getBasePositionAt(int position)
      {
        return (int) ((((float)position)/getWidth())*(lastEnd-lastStart));
      }
      
    
    tjc's avatar
    tjc committed
      final MouseListener mouseListener = new MouseAdapter()
      {
        /**
         *  Listen for mouse press events.
         **/
        public void mousePressed(MouseEvent event)
        {
    
    tjc's avatar
    tjc committed
          if(event.isPopupTrigger())
            popup.show(LookSeqPanel.this, event.getX(), event.getY());
          else if(event.getClickCount() == 1 && 
                  event.getButton() == MouseEvent.BUTTON1)
          {
            drawCrossHairAt = getBasePositionAt(event.getX());
            repaint();
          }
          else if(event.getClickCount() == 2)
          {
            drawCrossHairAt = -1;
            repaint();
          }
    
    tjc's avatar
    tjc committed
        }
      };
    
    tjc's avatar
    tjc committed
    
      public void setFeatureDisplay(FeatureDisplay feature_display)
      {
        this.feature_display = feature_display;
      }
      
    
    tjc's avatar
    tjc committed
      /**
       * Show Lookseq options
       */
    
    tjc's avatar
    tjc committed
      public void showOptions()
      {
        final JPanel optionsPanel = new JPanel(new GridBagLayout());
        GridBagConstraints c = new GridBagConstraints();
        final JTextField urlStrField = new JTextField(urlStr);
        c.gridy = 0;
        c.gridx = 0;
        c.anchor = GridBagConstraints.EAST;
        optionsPanel.add(new JLabel("Server:"), c);
        c.gridx = 1;
        c.anchor = GridBagConstraints.WEST;
        optionsPanel.add(urlStrField, c);
        
        String sampleStr = getText(queryStr,"chr=");
        final JTextField sampleField = new JTextField(sampleStr,40);
        c.gridy = 1;
        c.gridx = 0;
        c.anchor = GridBagConstraints.EAST;
        optionsPanel.add(new JLabel("Sample:"), c);
        c.gridx = 1;
        c.anchor = GridBagConstraints.WEST;
        optionsPanel.add(sampleField, c);
        
        String laneStr = getText(queryStr,"lane=");
        final JTextField laneField = new JTextField(laneStr,40);
        c.gridy = 2;
        c.gridx = 0;
        c.anchor = GridBagConstraints.EAST;
        optionsPanel.add(new JLabel("Lane:"), c);
        c.gridx = 1;
        c.anchor = GridBagConstraints.WEST;
        optionsPanel.add(laneField, c);
        
    
        
        
        String proxyHost = "";
        if(System.getProperty("http.proxyHost") != null)
          proxyHost = System.getProperty("http.proxyHost");
        
        final JTextField proxyHostField = new JTextField(proxyHost,40);
        c.gridy = 3;
        c.gridx = 0;
        c.anchor = GridBagConstraints.EAST;
        optionsPanel.add(new JLabel("Proxy Host:"), c);
        c.gridx = 1;
        c.anchor = GridBagConstraints.WEST;
        optionsPanel.add(proxyHostField, c);
        
        
        String proxyPort = "";
        if(System.getProperty("http.proxyPort") != null)
          proxyPort = System.getProperty("http.proxyPort");
        
        final JTextField proxyPortField = new JTextField(proxyPort,40);
        c.gridy = 4;
        c.gridx = 0;
        c.anchor = GridBagConstraints.EAST;
        optionsPanel.add(new JLabel("Proxy Port:"), c);
        c.gridx = 1;
        c.anchor = GridBagConstraints.WEST;
        optionsPanel.add(proxyPortField, c);
        
        
    
    tjc's avatar
    tjc committed
        String window_options[] = { "Display" };
        int select = JOptionPane.showOptionDialog(null, 
            optionsPanel,
            "Lookseq Options", JOptionPane.DEFAULT_OPTION,
            JOptionPane.QUESTION_MESSAGE, null, window_options,
            window_options[0]);
        
    
        if(!proxyHostField.getText().trim().equals(""))
        {
          System.getProperties().put("http.proxyHost", proxyHostField.getText().trim());
          System.getProperties().put("http.proxyPort", proxyPortField.getText().trim());
    
    tjc's avatar
    tjc committed
          System.getProperties().put("proxySet","true");
    
    tjc's avatar
    tjc committed
        urlStr = urlStrField.getText().trim();
        queryStr = queryStr.replaceFirst(
    
    tjc's avatar
    tjc committed
            "chr=[^&]+", "chr="+sampleField.getText().trim());
    
    tjc's avatar
    tjc committed
        
        queryStr = queryStr.replaceFirst(
    
    tjc's avatar
    tjc committed
            "lane=[^&]+", "lane="+laneField.getText().trim());
    
    tjc's avatar
    tjc committed
      }
      
    
    tjc's avatar
    tjc committed
      /**
       * Return the value of a sub-string in a string
       * @param str
       * @param subStr
       * @return
       */
    
    tjc's avatar
    tjc committed
      private String getText(String str, String subStr)
      {
        int beginIndex = str.indexOf(subStr);
        if(beginIndex == -1)
          return null;
        
        int endIndex = str.indexOf("&", beginIndex);
        if(endIndex == -1)
          endIndex = str.length();
        return str.substring(beginIndex+subStr.length(), endIndex);
      }
      
      public String getQueryStr()
      {
        return queryStr;
      }
    
    tjc's avatar
    tjc committed
      
      public static void main(String args[])
      {
        String urlStr = "http://www.sanger.ac.uk/cgi-bin/teams/team112/lookseq/get_data.pl?";
        String queryStr = "from=157682&to=479328&chr=MAL1&output=image&width=1024&lane=sample_2a&view=indel&display=|perfect|snps|inversions|pairlinks|potsnps|uniqueness|&debug=0";
        LookSeqPanel lookseq = new LookSeqPanel(urlStr, queryStr);
        
        JFrame f = new JFrame();
        f.getContentPane().add(lookseq);
        f.pack();
        f.setVisible(true);
      }
    }