Skip to content
Snippets Groups Projects
BamView.java 123 KiB
Newer Older
  • Learn to ignore specific revisions
  • tjc's avatar
    tjc committed
              {
                int basePosition = Integer.parseInt(baseText.getText());
                scrollBar.setValue(basePosition);
              }
              catch (NumberFormatException nfe)
              {
                JOptionPane.showMessageDialog(BamView.this,
                    "Expecting a base number!", "Number Format",
                    JOptionPane.WARNING_MESSAGE);
              }
            }
          });
          topPanel.add(goTo);
          topPanel.add(baseText);
    
          JButton zoomIn = new JButton("-");
    
          zoomIn.setToolTipText("Zoom out (up arrow)");
    
    tjc's avatar
    tjc committed
          Insets ins = new Insets(1,1,1,1);
          zoomIn.setMargin(ins);
          zoomIn.addActionListener(new ActionListener()
          {
            public void actionPerformed(ActionEvent e)
            {
              setZoomLevel((int) (BamView.this.nbasesInView * 1.1));
            }
          });
          topPanel.add(zoomIn);
    
          JButton zoomOut = new JButton("+");
    
          zoomOut.setToolTipText("Zoom in (down arrow)");
    
    tjc's avatar
    tjc committed
          zoomOut.setMargin(ins);
          zoomOut.addActionListener(new ActionListener()
          {
            public void actionPerformed(ActionEvent e)
            {
              if (showBaseAlignment)
                return;
              setZoomLevel((int) (BamView.this.nbasesInView * .9));
            }
          });
          topPanel.add(zoomOut);
        }
        
        topPanel.add(buttonAutoHide);
    
        
        if(feature_display != null)
        {
          JButton close = new JButton("Close");
          topPanel.add(close);
          close.addActionListener(new ActionListener()
          {
            public void actionPerformed(ActionEvent e)
            {
              final JPanel containerPanel = (JPanel) mainPanel.getParent();
              feature_display.removeDisplayAdjustmentListener(BamView.this);
              feature_display.getSelection().removeSelectionChangeListener(BamView.this);
              containerPanel.remove(mainPanel);
              
              if(containerPanel.getComponentCount() > 0)
                containerPanel.revalidate();
              else
              {
                if(entry_edit != null)
                  entry_edit.setNGDivider();
                else
                  containerPanel.setVisible(false);
              }
            }
          });
        }
    
    tjc's avatar
    tjc committed
        return topPanel;
      }
      
    
      public void setVisible(boolean visible)
      {
        super.setVisible(visible);
        mainPanel.setVisible(visible);
    
    tjc's avatar
    tjc committed
      }
      
    
    tjc's avatar
    tjc committed
      private void setViewportMidPoint()
      {
        Point p = jspView.getViewport().getLocation();
        p.y = (getHeight() - jspView.getViewport().getViewRect().height)/2;
        jspView.getViewport().setViewPosition(p);
      }
      
    
      private void setViewportBtm()
      {
        jspView.getVerticalScrollBar().setValue(
            jspView.getVerticalScrollBar().getMaximum());
      }
      
    
    tjc's avatar
    tjc committed
      protected int getBaseAtStartOfView()
    
    tjc's avatar
    tjc committed
      {
    
    tjc's avatar
    tjc committed
        if(feature_display != null)
          return feature_display.getForwardBaseAtLeftEdge();
        else
          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(isBaseAlignmentView(pixPerBase))
    
    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)
        {
    
          if(!cbCoverageView.isSelected() && !cbCoverageStrandView.isSelected() && nbasesInView >= MAX_BASES)
    
          {
            cbLastSelected = getSelectedCheckBoxMenuItem();
            cbCoverageView.setSelected(true);
    
            coverageView.setPlotByStrand(false);
    
          else if((cbCoverageView.isSelected() || cbCoverageStrandView.isSelected()) && nbasesInView < MAX_BASES && cbLastSelected != null)
    
          {
            cbLastSelected.setSelected(true);
            cbLastSelected = null;
          }
          
    
    tjc's avatar
    tjc committed
          jspView.setColumnHeaderView(null);
    
    tjc's avatar
    tjc committed
          
    
          if(!isStrandStackView())
    
            setViewportBtm();
    
    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);
        }
    
    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()
      {
    
    tjc's avatar
    tjc committed
        return (feature_display == null ? true : false);
    
      }
    
      public JScrollPane getJspView()
      {
        return jspView;
      }
      
      /**
       *  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
       */
    
      protected 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();
    
      /**
       * Get the colour for the given read given to it by the coverage plot.
       * @param samRecord
       * @return
       */
    
      private Color getColourByCoverageColour(BamViewRecord samRecord)
    
        if(bamList.size()>1)
    
          fileIndex = samRecord.bamIndex;
    
        return getColourByCoverageColour(fileIndex); 
      }
      
    
      private Color getColourByCoverageColour(final short fileIndex)
    
      {
        LineAttributes lines[] = CoveragePanel.getLineAttributes(bamList.size());
    
        return lines[fileIndex].getLineColour(); 
      }
    
    
      protected int getMaxBases()
      {
        return MAX_BASES;
      }
      
      protected void setMaxBases(int max)
      {
        MAX_BASES = max;
      }
      
      private boolean isStackView()
      {
        return cbStackView.isSelected();  
      }
      
      private boolean isPairedStackView()
      {
        return cbPairedStackView.isSelected();
      }
      
      private boolean isStrandStackView()
      {
        return cbStrandStackView.isSelected();
      }
      
      private boolean isCoverageView(float pixPerBase)
      {
        if(isBaseAlignmentView(pixPerBase))
          return false;
    
        return cbCoverageView.isSelected() || cbCoverageStrandView.isSelected();
    
      }
      
      private boolean isIsizeStackView()
      {
        return cbIsizeStackView.isSelected();
      }
      
      private boolean isBaseAlignmentView(float pixPerBase)
      {
        if(pixPerBase*1.08f >= ALIGNMENT_PIX_PER_BASE)
          return true;
        return false;
      }
      
      private JCheckBoxMenuItem getSelectedCheckBoxMenuItem()
      {
        if(isStackView())
          return cbStackView;
        if(isPairedStackView())
          return cbPairedStackView;
        if(isStrandStackView())
          return cbStrandStackView;
        if(isIsizeStackView())
          return cbIsizeStackView;
    
        if(cbCoverageView.isSelected())
          return cbCoverageView;
        return cbCoverageStrandView;
    
      protected Selection getSelection()
    
      protected List<BamViewRecord> getReadsInView()
    
    tjc's avatar
    tjc committed
        return readsInView;
      }
      
    
    tjc's avatar
    tjc committed
      protected int getBasesInView()
      {
        return nbasesInView;
      }
      
    
      protected void setHighlightSAMRecord(BamViewRecord highlightSAMRecord)
    
    tcarver's avatar
    tcarver committed
      {
        this.highlightSAMRecord = highlightSAMRecord;
      }
      
    
      protected BamViewRecord getHighlightSAMRecord()
    
    tcarver's avatar
    tcarver committed
      {
        return highlightSAMRecord;
      }
      
    
    tcarver's avatar
    tcarver committed
      protected FeatureDisplay getFeatureDisplay()
      {
        return feature_display;
      }
      
    
      /**
       * @return the combo
       */
      public SequenceComboBox getCombo()
      {
        return combo;
      }
      
    
    tjc's avatar
    tjc committed
      private String getVersion()
      {
        final ClassLoader cl = this.getClass().getClassLoader();
        try
        {
          String line;
          InputStream in = cl.getResourceAsStream("etc/versions");
          BufferedReader reader = new BufferedReader(new InputStreamReader(in));
          while((line = reader.readLine()) != null)
          {
            if(line.startsWith("BamView"))
              return line.substring( "BamView".length() ).trim();
          }
          reader.close();
          in.close();
        }
        catch (Exception ex)
        {
        }
        return null;
      }
      
    
    tjc's avatar
    tjc committed
      /**
       * Artemis event notification
       */
    
      public void displayAdjustmentValueChanged(final DisplayAdjustmentEvent event)
    
        if(event.getType() == DisplayAdjustmentEvent.REV_COMP_EVENT &&
           event.isRevCompDisplay())
          JOptionPane.showMessageDialog(this, 
              "Flipping the display is not supported by BamView.", "Warning", 
              JOptionPane.WARNING_MESSAGE);
    
    
        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;
    
    tjc's avatar
    tjc committed
    
    
          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;
    
        protected int start;
        protected int end;
        protected String refSeq;
    
    tjc's avatar
    tjc committed
    
    
    tjc's avatar
    tjc committed
        public Ruler()
        {
          super();
    
          setPreferredSize(new Dimension(mainPanel.getWidth(), 26));
    
    tjc's avatar
    tjc committed
          setBackground(Color.white);
        }
    
    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();
    
    
          for(int i=startMark; i<end; i+=20)
    
    tjc's avatar
    tjc committed
          {
    
    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);
    
    tjc's avatar
    tjc committed
            
    
          for(int i=startMark; i<end; i+=10)
          {
            int xpos = (i-start)*ALIGNMENT_PIX_PER_BASE;
    
    tjc's avatar
    tjc committed
            xpos+=(ALIGNMENT_PIX_PER_BASE/2);
            g2.drawLine(xpos, ypos+1, xpos, ypos+5);
          }
    
          
          if(refSeq != null)
          {
            ypos+=15;
            g2.setColor(LIGHT_GREY);
            g2.fillRect(0, ypos-11, getWidth(), 11);
    
            g2.translate(0, 16);
            drawSelectionRange(g2, ALIGNMENT_PIX_PER_BASE, start, end, Color.yellow);
            g2.translate(0, -16);
            g2.setColor(Color.black);
            g2.drawString(refSeq, 0, ypos-2);
          }
    
    tjc's avatar
    tjc committed
        }
    
    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(showDetails != null)
              popup.remove(showDetails);
    
                mouseOverSAMRecord.sam.getReadPairedFlag() &&
               !mouseOverSAMRecord.sam.getMateUnmappedFlag() )
    
              final BamViewRecord thisSAMRecord = mouseOverSAMRecord;
    
              gotoMateMenuItem = new JMenuItem("Go to mate of : "+
    
                  thisSAMRecord.sam.getReadName());
    
              gotoMateMenuItem.addActionListener(new ActionListener()
              {
    			public void actionPerformed(ActionEvent e) 
    			{
    
    			  String name = thisSAMRecord.sam.getMateReferenceName();
    
    			    name = thisSAMRecord.sam.getReferenceName();
    
    			  int offset = getSequenceOffset(name);
    			  if(feature_display != null)
    			    feature_display.makeBaseVisible(
    
    			        thisSAMRecord.sam.getMateAlignmentStart()+offset);
    
    			        thisSAMRecord.sam.getMateAlignmentStart()+offset-
    
    			        (nbasesInView/2));
    			  
    			  highlightSAMRecord = thisSAMRecord; 
    			}  
              });
              popup.add(gotoMateMenuItem);
    
              final BamViewRecord thisSAMRecord = mouseOverSAMRecord;
    
              showDetails = new JMenuItem("Show details of : "+
    
                  thisSAMRecord.sam.getReadName());
    
              showDetails.addActionListener(new ActionListener()
              {
                public void actionPerformed(ActionEvent e) 
                {
    
                  openFileViewer(thisSAMRecord.sam, getMate(thisSAMRecord), bamList);
    
    tcarver's avatar
    tcarver committed
                }
    
            popup.show(e.getComponent(),
                    e.getX(), e.getY());
    
    tjc's avatar
    tjc committed
          }
    
      protected static void openFileViewer(SAMRecord readRecord, SAMRecord mateRecord, List<String> bamList)
    
    tcarver's avatar
    tcarver committed
      {
        FileViewer viewDetail = new FileViewer(readRecord.getReadName(), true, false, false);
    
        appendToDetailView(readRecord, mateRecord, viewDetail, bamList);
    
      private static void appendToDetailView(final SAMRecord thisSAMRecord, 
                                             final SAMRecord thisSAMRecordMate, 
                                             final FileViewer viewDetail, 
                                             final List<String> bamList)
    
        if(bamList.size() > 1 && thisSAMRecord.getAttribute("FL") != null)
        {
          int bamIndex = (Integer)thisSAMRecord.getAttribute("FL");
          if(bamIndex < bamList.size())
            viewDetail.appendString("File                  "+bamList.get(bamIndex)+"\n\n", Level.INFO);
        }
        
    
        viewDetail.appendString("Read Name             "+thisSAMRecord.getReadName()+"\n", Level.INFO);
        viewDetail.appendString("Coordinates           "+thisSAMRecord.getAlignmentStart()+".."+
                                                         thisSAMRecord.getAlignmentEnd()+"\n", Level.DEBUG);
        viewDetail.appendString("Length                "+thisSAMRecord.getReadLength()+"\n", Level.DEBUG);
        viewDetail.appendString("Reference Name        "+thisSAMRecord.getReferenceName()+"\n", Level.DEBUG);
        viewDetail.appendString("Inferred Size         "+thisSAMRecord.getInferredInsertSize()+"\n", Level.DEBUG);
    
    tjc's avatar
    tjc committed
        viewDetail.appendString("Mapping Quality       "+thisSAMRecord.getMappingQuality()+"\n", Level.DEBUG);
    
        viewDetail.appendString("Cigar String          "+thisSAMRecord.getCigarString()+"\n", Level.DEBUG);
        viewDetail.appendString("Strand                "+
            (thisSAMRecord.getReadNegativeStrandFlag() ? "-\n\n" : "+\n\n"), Level.DEBUG);
        
    
    tcarver's avatar
    tcarver committed
        if(thisSAMRecord.getReadPairedFlag() && !thisSAMRecord.getMateUnmappedFlag())
    
        {     
          if(thisSAMRecordMate != null)
          {
            viewDetail.appendString("Mate Coordinates      "+thisSAMRecordMate.getAlignmentStart()+".."+
                thisSAMRecordMate.getAlignmentEnd()+"\n", Level.DEBUG);
            viewDetail.appendString("Mate Length           "+thisSAMRecordMate.getReadLength()+"\n", Level.DEBUG);
            viewDetail.appendString("Mate Reference Name   "+thisSAMRecordMate.getReferenceName()+"\n", Level.DEBUG);
            viewDetail.appendString("Mate Inferred Size    "+thisSAMRecordMate.getInferredInsertSize()+"\n", Level.DEBUG);
            viewDetail.appendString("Mate Mapping Quality  "+thisSAMRecordMate.getMappingQuality()+"\n", Level.DEBUG);
            viewDetail.appendString("Mate Cigar String     "+thisSAMRecordMate.getCigarString()+"\n", Level.DEBUG);
          }
          else
          {
            viewDetail.appendString("Mate Start Coordinate "+thisSAMRecord.getMateAlignmentStart()+"\n", Level.DEBUG);
            viewDetail.appendString("Mate Reference Name   "+thisSAMRecord.getMateReferenceName()+"\n", Level.DEBUG);
          }
          viewDetail.appendString("Mate Strand           "+
              (thisSAMRecord.getMateNegativeStrandFlag() ? "-" : "+"), Level.DEBUG);
    
          viewDetail.appendString("Mate Unmapped ", Level.DEBUG);
    
        }
        
        viewDetail.appendString("\n\nFlags:", Level.INFO);
        viewDetail.appendString("\nDuplicate Read    "+
            (thisSAMRecord.getDuplicateReadFlag() ? "yes" : "no"), Level.DEBUG);
    
    tjc's avatar
    tjc committed
        
        viewDetail.appendString("\nRead Paired       "+
            (thisSAMRecord.getReadPairedFlag() ? "yes" : "no"), Level.DEBUG);
        if(thisSAMRecord.getReadPairedFlag())
        {
          viewDetail.appendString("\nFirst of Pair     "+
    
            (thisSAMRecord.getFirstOfPairFlag() ? "yes" : "no"), Level.DEBUG);
    
    tjc's avatar
    tjc committed
          viewDetail.appendString("\nMate Unmapped     "+
    
            (thisSAMRecord.getMateUnmappedFlag() ? "yes" : "no"), Level.DEBUG);  
    
    tjc's avatar
    tjc committed
          viewDetail.appendString("\nProper Pair       "+
    
            (thisSAMRecord.getProperPairFlag() ? "yes" : "no"), Level.DEBUG);
    
        viewDetail.appendString("\nRead Fails Vendor\nQuality Check     "+
            (thisSAMRecord.getReadFailsVendorQualityCheckFlag() ? "yes" : "no"), Level.DEBUG);
        viewDetail.appendString("\nRead Unmapped     "+
            (thisSAMRecord.getReadUnmappedFlag() ? "yes" : "no"), Level.DEBUG);
    
    tjc's avatar
    tjc committed
        
        if(thisSAMRecord.getReadPairedFlag())
          viewDetail.appendString("\nSecond Of Pair    "+
    
            (thisSAMRecord.getSecondOfPairFlag() ? "yes" : "no"), Level.DEBUG);
    
        
        viewDetail.appendString("\n\nRead Bases:\n", Level.INFO);
    
        
        // wrap the read bases
        String seq = new String(thisSAMRecord.getReadBases());
        int MAX_SEQ_LINE_LENGTH = 100;
        for(int i=0; i<=seq.length(); i+=MAX_SEQ_LINE_LENGTH)
        {
          int iend = i+MAX_SEQ_LINE_LENGTH;
          if(iend > seq.length())
        	iend = seq.length();
          viewDetail.appendString(seq.substring(i, iend)+"\n", Level.DEBUG);
        }
    
      /**
       * Query for the mate of a read
       * @param mate
       * @return
       */
    
      protected SAMRecord getMate(BamViewRecord thisSAMRecord)
    
        if(!thisSAMRecord.sam.getReadPairedFlag() ||  // read is not paired in sequencing
            thisSAMRecord.sam.getMateUnmappedFlag())
    
    tcarver's avatar
    tcarver committed
          return null;
        
    
        SAMRecord mate = null;
        try
        {
    
          short fileIndex = 0;
          if(bamList.size()>1 && thisSAMRecord.bamIndex > 0)
            fileIndex = thisSAMRecord.bamIndex;
    
          String bam = bamList.get(fileIndex);  
          final SAMFileReader inputSam = getSAMFileReader(bam);
    
          mate = inputSam.queryMate(thisSAMRecord.sam);
    
        }
        catch (Exception e)
        {
          e.printStackTrace();
        }
        return mate;
      }
      
    
    tjc's avatar
    tjc committed
      protected SAMRecordPredicate getSamRecordFlagPredicate()
    
      {
        return samRecordFlagPredicate;
      }
    
      protected void setSamRecordFlagPredicate(
    
    tjc's avatar
    tjc committed
          SAMRecordPredicate samRecordFlagPredicate)
    
      {
        laststart = -1;
        lastend = -1;
        this.samRecordFlagPredicate = samRecordFlagPredicate;
      }
    
    tjc's avatar
    tjc committed
      protected SAMRecordMapQPredicate getSamRecordMapQPredicate()
      {
        return samRecordMapQPredicate;
      }
    
      protected void setSamRecordMapQPredicate(
          SAMRecordMapQPredicate samRecordMapQPredicate)
      {
        laststart = -1;
        lastend = -1;
        this.samRecordMapQPredicate = samRecordMapQPredicate;
      }
      
    
      /**
       * @return the concatSequences
       */
      protected boolean isConcatSequences()
      {
        return concatSequences;
      }
    
    
        BamViewRecord sam1;
        BamViewRecord sam2;
    
      }
      
      class CreateFeatures
      {
        CreateFeatures(final GroupBamFrame groupsFrame)
        {
          final TextFieldInt threshold = new TextFieldInt();
          final TextFieldInt minSize = new TextFieldInt();
          final TextFieldInt minBams = new TextFieldInt();
          
          threshold.setValue(6);
          minSize.setValue(6);
          minBams.setValue( (groupsFrame.getNumberOfGroups() == 1 ?
              bamList.size() : groupsFrame.getMaximumBamsInGroup()) );
          
          final JPanel gridPanel = new JPanel(new GridBagLayout());
          GridBagConstraints c = new GridBagConstraints();
          c.anchor = GridBagConstraints.WEST;
          c.fill = GridBagConstraints.HORIZONTAL;
          c.gridx = 0;
          c.gridy = 0;
          
          gridPanel.add(new JLabel("Minimum number of reads:"), c);
          c.gridy++;
          gridPanel.add(threshold, c);
          
          c.gridy++;
          gridPanel.add(new JSeparator(), c);
          c.gridy++;
          gridPanel.add(new JLabel("Minimum number of BAMs for reads to be present in:"), c);
          c.gridy++;
          gridPanel.add(minBams, c);
          
          JRadioButton useAllBams = new JRadioButton("out of all BAMs", (groupsFrame.getNumberOfGroups() == 1));
          JRadioButton useGroup = new JRadioButton("within a group", (groupsFrame.getNumberOfGroups() != 1));
          
          if(groupsFrame.getNumberOfGroups() == 1)
            useGroup.setEnabled(false);
          
          ButtonGroup group = new ButtonGroup();
          group.add(useAllBams);
          group.add(useGroup);
    
          Box xBox = Box.createHorizontalBox();
          xBox.add(useAllBams);
          xBox.add(useGroup);
          xBox.add(Box.createHorizontalGlue());
          c.gridy++;
          gridPanel.add(xBox, c);
          
          c.gridy++;
          gridPanel.add(new JSeparator(), c);
          c.gridy++;
          gridPanel.add(new JLabel("Minimum feature size:"), c);
          c.gridy++;
          gridPanel.add(minSize, c);
    
          int status =
              JOptionPane.showConfirmDialog(feature_display, gridPanel, 
                  "Options", JOptionPane.OK_CANCEL_OPTION);
          if(status == JOptionPane.CANCEL_OPTION)
            return;
          
          if(!useGroup.isSelected() && minBams.getValue() > bamList.size())
          {
            status =
                JOptionPane.showConfirmDialog(feature_display, 
                    "The minimum number of BAMs setting can not be\n"+
                    "greater than the total number of BAM files.\n"+
                    "Set this to the number of BAMs (i.e. "+bamList.size()+").",
                    "Options", JOptionPane.OK_CANCEL_OPTION);
            if(status == JOptionPane.CANCEL_OPTION)
              return;
            minBams.setValue(bamList.size());
          }
          else if(useGroup.isSelected() && minBams.getValue() > groupsFrame.getMaximumBamsInGroup())
          {
            status =
                JOptionPane.showConfirmDialog(feature_display, 
                    "Minimum number of BAMs setting can not be greater than\n"+
                    "the total number of BAM files found in any of the groups.\n"+
                    "Set this to the greatest number of BAM files in any\n"+
                    "group (i.e. "+groupsFrame.getMaximumBamsInGroup()+").",
                    "Options", JOptionPane.OK_CANCEL_OPTION);
            if(status == JOptionPane.CANCEL_OPTION)
              return;
            minBams.setValue(groupsFrame.getMaximumBamsInGroup());
          }
    
          new MappedReads((String)combo.getSelectedItem(),BamView.this, samFileReaderHash,
              seqNames, offsetLengths, concatSequences, seqLengths, 
              (useGroup.isSelected() ? groupsFrame : null),
              threshold.getValue(), minSize.getValue(), minBams.getValue(), true);
        }
      }
    
    tjc's avatar
    tjc committed
      public static void main(String[] args)
      {
    
    tjc's avatar
    tjc committed
        BamFrame frame = new BamFrame();
    
    tjc's avatar
    tjc committed
        if(args.length == 0 && BamFrame.isMac())
        {
          try
          {
            Thread.sleep(1000);
          }
          catch (InterruptedException e1) {}
    
    tjc's avatar
    tjc committed
          if(frame.getBamFile() != null)
    
    tjc's avatar
    tjc committed
            args = new String[]{ frame.getBamFile() };
        }
    
    tjc's avatar
    tjc committed
          
        List<String> bam = new Vector<String>();
    
    tjc's avatar
    tjc committed
        String reference = null;
    
        if(args.length == 0 || args[0].equals("NEW-BAMVIEW"))
    
    tjc's avatar
    tjc committed
          System.setProperty("default_directory", System.getProperty("user.dir"));
    
          FileSelectionDialog fileSelection = new FileSelectionDialog(
              null, true, "BamView", "BAM");
    
    tcarver's avatar
    tcarver committed
          bam = fileSelection.getFiles(BAM_SUFFIX); 
    
          reference = fileSelection.getReferenceFile();
          if(reference == null || reference.equals(""))
            reference = null;
    
    tjc's avatar
    tjc committed
          
          if(bam == null || bam.size() < 1)
    
            if(args.length > 0 && args[0].equals("NEW-BAMVIEW"))
              return;
    
            System.err.println("No files found.");
    
    tjc's avatar
    tjc committed
            System.exit(0);
    
        else if(!args[0].startsWith("-"))
        {
          for(int i=0; i< args.length; i++)
            bam.add(args[i]);
        }
    
        int nbasesInView = 2000;
    
    tjc's avatar
    tjc committed
        String chr = null;
        String vw  = null;
        boolean orientation = false;
        boolean covPlot     = false;
        boolean snpPlot     = false;
        int base = 0;
        
    
    tjc's avatar
    tjc committed
        for(int i=0;i<args.length; i++)
        {
          if(args[i].equals("-a"))
    
          {
            while(i < args.length-1 && !args[++i].startsWith("-"))
    
            {
              String filename = args[i];
              if(FileSelectionDialog.isListOfFiles(filename))
                bam.addAll(FileSelectionDialog.getListOfFiles(filename));
              else
                bam.add(filename);
            }
    
    tjc's avatar
    tjc committed
          else if(args[i].equals("-r"))
            reference = args[++i];
    
    tjc's avatar
    tjc committed
          else if(args[i].equals("-n"))
    
    tjc's avatar
    tjc committed
            nbasesInView = Integer.parseInt(args[++i]);