Skip to content
Snippets Groups Projects
BamView.java 70.9 KiB
Newer Older
  • Learn to ignore specific revisions
  • tjc's avatar
    tjc committed
          return scrollBar.getValue();
    
    tjc's avatar
    tjc committed
      }
      
      /**
       * Set the panel size based on the number of bases visible
       * and repaint.
       * @param nbasesInView
       */
    
    tjc's avatar
    tjc committed
      private void setZoomLevel(final int nbasesInView)
      {
    
    tjc's avatar
    tjc committed
        int startValue = getBaseAtStartOfView();
    
    tjc's avatar
    tjc committed
        this.nbasesInView = nbasesInView;
    
    tjc's avatar
    tjc committed
        float pixPerBase = getPixPerBaseByWidth(); 
    
    tjc's avatar
    tjc committed
    
    
        if(pixPerBase*1.08f >= ALIGNMENT_PIX_PER_BASE)
    
    tjc's avatar
    tjc committed
        {
          pixPerBase = ALIGNMENT_PIX_PER_BASE;
    
          this.nbasesInView = (int)(mainPanel.getWidth()/pixPerBase);
    
    tjc's avatar
    tjc committed
          jspView.getVerticalScrollBar().setValue(0);
    
          
          if(ruler == null)
            ruler = new Ruler();
    
    tjc's avatar
    tjc committed
          jspView.setColumnHeaderView(ruler);
          showBaseAlignment = true;
    
          baseQualityColour.setEnabled(true);
    
          markInsertions.setEnabled(true);
    
    tjc's avatar
    tjc committed
        }
        else if(jspView != null)
        {
          jspView.setColumnHeaderView(null);
    
    tjc's avatar
    tjc committed
          
          if(!isStrandStackView)
            jspView.getVerticalScrollBar().setValue(
                jspView.getVerticalScrollBar().getMaximum());
    
    tjc's avatar
    tjc committed
          showBaseAlignment = false;
    
          baseQualityColour.setEnabled(false);
    
          markInsertions.setEnabled(false);
    
    tjc's avatar
    tjc committed
        }
        
    
    tjc's avatar
    tjc committed
        if(scrollBar != null)
    
    tjc's avatar
    tjc committed
          scrollBar.setValues(startValue, nbasesInView, 1, 
                 getMaxBasesInPanel(getSequenceLength()));
    
          scrollBar.setUnitIncrement(nbasesInView/20);
    
          scrollBar.setBlockIncrement(nbasesInView);
    
    tjc's avatar
    tjc committed
      }
    
    tjc's avatar
    tjc committed
    
    
    tjc's avatar
    tjc committed
      /**
    
       * Set the start and end base positions to display.
       * @param start
       * @param end
       * @param event
    
    tjc's avatar
    tjc committed
       */
    
      public void setDisplay(int start,
                             int end,
                             DisplayAdjustmentEvent event)
    
    tjc's avatar
    tjc committed
      {
    
        this.startBase = start;
        this.endBase   = end;
    
    tjc's avatar
    tjc committed
        this.nbasesInView = end-start+1;
    
        lastMousePoint = null;
    
    tjc's avatar
    tjc committed
        float pixPerBase;
        if(jspView.getViewport().getViewRect().width > 0)
    
    tjc's avatar
    tjc committed
          pixPerBase = getPixPerBaseByWidth();
    
    tjc's avatar
    tjc committed
        else
        {
          if(feature_display == null)
            pixPerBase = 1000.f/(float)(end-start+1);
          else
            pixPerBase = feature_display.getWidth()/(float)(end-start+1);
        }
    
    
        if(pixPerBase*1.08f >= ALIGNMENT_PIX_PER_BASE)
    
    tjc's avatar
    tjc committed
        {
    
    tjc's avatar
    tjc committed
          pixPerBase = ALIGNMENT_PIX_PER_BASE;
    
    tjc's avatar
    tjc committed
          jspView.getVerticalScrollBar().setValue(0);
    
    tjc's avatar
    tjc committed
          jspView.setColumnHeaderView(ruler);
    
          showBaseAlignment = true;
    
          baseQualityColour.setEnabled(true);
    
          markInsertions.setEnabled(true);
    
    tjc's avatar
    tjc committed
        }
    
    tjc's avatar
    tjc committed
        else if(jspView != null)
    
    tjc's avatar
    tjc committed
        {
    
    tjc's avatar
    tjc committed
          jspView.setColumnHeaderView(null);
    
          showBaseAlignment = false;
    
          baseQualityColour.setEnabled(false);
    
          markInsertions.setEnabled(false);
    
    tjc's avatar
    tjc committed
        }
    
    tjc's avatar
    tjc committed
        Dimension d = new Dimension();
    
    tjc's avatar
    tjc committed
        d.setSize(nbasesInView*pixPerBase, maxHeight);
    
    tjc's avatar
    tjc committed
        setPreferredSize(d);
    
    tjc's avatar
    tjc committed
        if(event == null)
        {
          this.startBase = -1;
          this.endBase   = -1;
        }
    
    tjc's avatar
    tjc committed
      /**
       * Return an Artemis entry from a file 
       * @param entryFileName
       * @param entryGroup
       * @return
       * @throws NoSequenceException
       */
      private Entry getEntry(final String entryFileName, final EntryGroup entryGroup) 
                       throws NoSequenceException
      {
        final Document entry_document = DocumentFactory.makeDocument(entryFileName);
        final EntryInformation artemis_entry_information =
          Options.getArtemisEntryInformation();
        
    
        //System.out.println(entryFileName);
    
    tjc's avatar
    tjc committed
        final uk.ac.sanger.artemis.io.Entry new_embl_entry =
          EntryFileDialog.getEntryFromFile(null, entry_document,
                                           artemis_entry_information,
                                           false);
    
        if(new_embl_entry == null)  // the read failed
          return null;
    
        Entry entry = null;
        try
        {
          if(entryGroup.getSequenceEntry() != null)
            bases = entryGroup.getSequenceEntry().getBases();
    
    tjc's avatar
    tjc committed
          
    
    tjc's avatar
    tjc committed
          if(bases == null)
    
    tjc's avatar
    tjc committed
          {
    
    tjc's avatar
    tjc committed
            entry = new Entry(new_embl_entry);
    
    tjc's avatar
    tjc committed
            bases = entry.getBases();
          }
    
    tjc's avatar
    tjc committed
          else
            entry = new Entry(bases,new_embl_entry);
          
          entryGroup.add(entry);
        } 
        catch(OutOfRangeException e) 
        {
          new MessageDialog(null, "read failed: one of the features in " +
              entryFileName + " has an out of range " +
                            "location: " + e.getMessage());
        }
        return entry;
      }
    
      
      private boolean isShowScale()
      {
        return showScale;
      }
    
      public void setShowScale(boolean showScale)
      {
        this.showScale = showScale;
      }
      
      public JScrollPane getJspView()
      {
        return jspView;
      }
      
      public void setBases(Bases bases)
      {
        this.bases = bases;
      }
      
      /**
       * Remove JScrollPane border
       */
      public void removeBorder()
      {
        Border empty = new EmptyBorder(0,0,0,0);
        jspView.setBorder(empty);
      }
      
      /**
       *  Handle a mouse drag event on the drawing canvas.
       **/
    
    tjc's avatar
    tjc committed
      private void handleCanvasMouseDrag(final MouseEvent event)
    
        if(event.getButton() == MouseEvent.BUTTON3 || bases == null) 
    
        if(event.getClickCount() > 1)
        {
          getSelection().clear();
          repaint();
          return;  
        }
        
    
        highlightRange(event, 
            MouseEvent.BUTTON1_DOWN_MASK & MouseEvent.BUTTON2_DOWN_MASK);
      }
      
      /**
       * 
       * @param event
       * @param onmask
       */
      private void highlightRange(MouseEvent event, int onmask)
      {
    
    tjc's avatar
    tjc committed
        int seqLength = getSequenceLength();
    
    tjc's avatar
    tjc committed
        float pixPerBase = getPixPerBaseByWidth();
    
    tjc's avatar
    tjc committed
        int start = (int) ( ( (event.getPoint().getX())/pixPerBase) + getBaseAtStartOfView() );
    
        if(start < 1)
          start = 1;
        if(start > seqLength)
          start = seqLength;
    
        if (dragStart < 0 && (event.getModifiersEx() & onmask) == onmask)
          dragStart = start;
        else if((event.getModifiersEx() & onmask) != onmask)
          dragStart = -1;
        
    
        MarkerRange drag_range;
        try
    
          if(dragStart < 0)
            drag_range = new MarkerRange (bases.getForwardStrand(), start, start);
          else
            drag_range = new MarkerRange (bases.getForwardStrand(), dragStart, start);
    
          getSelection().setMarkerRange(drag_range);
          repaint();
    
        catch (OutOfRangeException e)
    
          e.printStackTrace();
    
        }
      }
      
      private Selection getSelection()
      {
        return selection;
      }
      
    
    tjc's avatar
    tjc committed
      protected List<SAMRecord> getReadsInView()
    
    tjc's avatar
    tjc committed
        return readsInView;
      }
      
    
    tjc's avatar
    tjc committed
      protected int getBasesInView()
      {
        return nbasesInView;
      }
      
    
    tjc's avatar
    tjc committed
      /**
       * Artemis event notification
       */
    
      public void displayAdjustmentValueChanged(final DisplayAdjustmentEvent event)
    
      {
        if(!asynchronous)
        {
          // if not asynchronous
          displayAdjustmentWork(event);
          return;
        }
        
    
        SwingWorker worker = new SwingWorker()
    
    tjc's avatar
    tjc committed
        {
    
          public Object construct()
          {
            try
            {
              Thread.sleep(500);
            }
            catch (InterruptedException e)
            {
              e.printStackTrace();
            }
            
            if(event.getStart() != ((FeatureDisplay)event.getSource()).getForwardBaseAtLeftEdge())
            {
    
              waitingFrame.showWaiting("waiting...", mainPanel);
    
            displayAdjustmentWork(event);
    
            waitingFrame.setVisible(false);
    
            return null;
          }
        };
        worker.start();
    
      /**
       * Carry out the display agjustment event action.
       * @param event
       */
      private void displayAdjustmentWork(final DisplayAdjustmentEvent event)
      {
        if(event.getType() == DisplayAdjustmentEvent.SCALE_ADJUST_EVENT)
        {
          laststart = -1;
          lastend = -1;
          BamView.this.startBase = event.getStart();
          BamView.this.endBase   = event.getEnd();
    
          int width = feature_display.getMaxVisibleBases();
          setZoomLevel(width);
          repaint();
        }
        else
        {
          setDisplay(event.getStart(), 
            event.getStart()+feature_display.getMaxVisibleBases(), event);
          repaint();
        }
      }
      
    
    tjc's avatar
    tjc committed
      public void selectionChanged(SelectionChangeEvent event)
      {
        repaint();
    
    tjc's avatar
    tjc committed
      private class Ruler extends JPanel
    
    tjc's avatar
    tjc committed
      {
    
    tjc's avatar
    tjc committed
        private static final long serialVersionUID = 1L;
    
    tjc's avatar
    tjc committed
        int start;
        int end;
    
    tjc's avatar
    tjc committed
    
    
    tjc's avatar
    tjc committed
        public Ruler()
        {
          super();
    
          setPreferredSize(new Dimension(mainPanel.getWidth(), 15));
    
    tjc's avatar
    tjc committed
          setBackground(Color.white);
          setFont(getFont().deriveFont(11.f));
        }
    
    tjc's avatar
    tjc committed
    
    
    tjc's avatar
    tjc committed
        public void paintComponent(Graphics g)
        {
          super.paintComponent(g);
          Graphics2D g2 = (Graphics2D)g;
          drawBaseScale(g2, start, end, 12);
        }
    
    tjc's avatar
    tjc committed
    
        private void drawBaseScale(Graphics2D g2, int start, int end, int ypos)
        {
          int startMark = (((int)(start/10))*10)+1;
    
    
          if(end > getSequenceLength())
            end = getSequenceLength();
          
    
    tjc's avatar
    tjc committed
          for(int i=startMark; i<end; i+=10)
          {
    
    tjc's avatar
    tjc committed
            int xpos = (i-start)*ALIGNMENT_PIX_PER_BASE;
    
    tjc's avatar
    tjc committed
            g2.drawString(Integer.toString(i), xpos, ypos);
            
            xpos+=(ALIGNMENT_PIX_PER_BASE/2);
            g2.drawLine(xpos, ypos+1, xpos, ypos+5);
          }
        }
    
    tjc's avatar
    tjc committed
      }
      
    
      /**
      * Popup menu listener
      */
      class PopupListener extends MouseAdapter
      {
    
        public void mouseClicked(MouseEvent e)
        {
    
          if(e.isPopupTrigger() ||
             e.getButton() == MouseEvent.BUTTON3)
            return;
          
    
          
          if(e.getClickCount() > 1)
            getSelection().clear(); 
          else if(e.getButton() == MouseEvent.BUTTON1)
            highlightSAMRecord = mouseOverSAMRecord;
    
          else
            highlightRange(e, MouseEvent.BUTTON2_DOWN_MASK);
    
        }
        
        public void mousePressed(MouseEvent e)
        {
          maybeShowPopup(e);
        }
    
        public void mouseReleased(MouseEvent e)
        {
    
          maybeShowPopup(e);
        }
    
        private void maybeShowPopup(MouseEvent e)
        {
          if(e.isPopupTrigger())
    
    tjc's avatar
    tjc committed
          {
            if(popup == null)
            {
              popup = new JPopupMenu();
    
              createMenus(popup);
    
    tjc's avatar
    tjc committed
            }
    
            
            if(gotoMateMenuItem != null)
              popup.remove(gotoMateMenuItem);
            
            if( mouseOverSAMRecord != null && 
                mouseOverSAMRecord.getReadPairedFlag() &&
               !mouseOverSAMRecord.getMateUnmappedFlag() )
            {
              final SAMRecord thisSAMRecord = mouseOverSAMRecord;
              gotoMateMenuItem = new JMenuItem("Go to mate of : "+
                  thisSAMRecord.getReadName());
              gotoMateMenuItem.addActionListener(new ActionListener()
              {
    			public void actionPerformed(ActionEvent e) 
    			{
    			  String name = thisSAMRecord.getMateReferenceName();
    			  if(name.equals("="))
    			    name = thisSAMRecord.getReferenceName();
    			  int offset = getSequenceOffset(name);
    			  if(feature_display != null)
    			    feature_display.makeBaseVisible(
    			        thisSAMRecord.getMateAlignmentStart()+offset);
    			  else
    			    scrollBar.setValue(
    			        thisSAMRecord.getMateAlignmentStart()+offset-
    			        (nbasesInView/2));
    			  
    			  highlightSAMRecord = thisSAMRecord; 
    			}  
              });
              popup.add(gotoMateMenuItem);
            }
    
            popup.show(e.getComponent(),
                    e.getX(), e.getY());
    
    tjc's avatar
    tjc committed
          }
    
      
      class PairedRead
      {
        SAMRecord sam1;
        SAMRecord sam2;
      }
    
    tjc's avatar
    tjc committed
      public static void main(String[] args)
      {
    
    tjc's avatar
    tjc committed
        String reference = null;
    
        if(args.length == 0)
        {
          FileSelectionPanel fileSelection = new FileSelectionPanel();
          fileSelection.showPanel();
          bam = fileSelection.getBamFile();
          reference = fileSelection.getReferenceFile();
          if(reference == null || reference.equals(""))
            reference = null;
        }
        else
          bam = args[0];
        int nbasesInView = 1000;
    
    
    tjc's avatar
    tjc committed
        for(int i=0;i<args.length; i++)
        {
          if(args[i].equals("-a"))
            bam = args[++i];
          else if(args[i].equals("-r"))
            reference = args[++i];
          else if(args[i].equals("-v"))
            nbasesInView = Integer.parseInt(args[++i]);
          else if(args[i].equals("-s"))
            System.setProperty("samtoolDir", args[++i]);
          else if(args[i].startsWith("-h"))
          { 
            System.out.println("-h\t show help");
            
            System.out.println("-a\t BAM/SAM file to display");
            System.out.println("-r\t reference file (optional)");
            System.out.println("-v\t number of bases to display in the view (optional)");
    
            /*System.out.println("-s\t samtool directory");*/
    
    tjc's avatar
    tjc committed
    
            System.exit(0);
          }
        }
    
    
        final BamView view = new BamView(bam, reference, nbasesInView);
    
        JFrame frame = new JFrame("BamView");
    
    tjc's avatar
    tjc committed
        
    
        // translucent
        //frame.getRootPane().putClientProperty("Window.alpha", new Float(0.9f));
    
    
    tjc's avatar
    tjc committed
        frame.addWindowFocusListener(new WindowFocusListener()
        {
          public void windowGainedFocus(WindowEvent e)
          {
            view.requestFocus();
          }
          public void windowLostFocus(WindowEvent e){}
        });
        
    
    tjc's avatar
    tjc committed
        view.addJamToPanel((JPanel)frame.getContentPane(), frame, false, null);
    
    tjc's avatar
    tjc committed
        frame.pack();
    
    tjc's avatar
    tjc committed
        view.jspView.getVerticalScrollBar().setValue(
            view.jspView.getVerticalScrollBar().getMaximum());
    
        frame.setVisible(true);
    
    tjc's avatar
    tjc committed
      }
    
    tjc's avatar
    tjc committed
    }