Skip to content
Snippets Groups Projects
BamView.java 135 KiB
Newer Older
          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 sam, 
                                         final SAMRecord mate, 
                                         final FileViewer viewer, 
                                         final List<String> bamList)
    if(bamList.size() > 1 && sam.getAttribute("FL") != null)
      int bamIdx = (Integer)sam.getAttribute("FL");
      if(bamIdx < bamList.size())
        viewer.appendString("File                  "+bamList.get(bamIdx)+"\n\n", Level.INFO);
    viewer.appendString("Read Name             "+sam.getReadName()+"\n", Level.INFO);
    viewer.appendString("Coordinates           "+sam.getAlignmentStart()+".."+
                                                 sam.getAlignmentEnd()+"\n", Level.DEBUG);
tcarver's avatar
tcarver committed
    if(sam.getReadGroup() != null)
      viewer.appendString("Read Group            "+sam.getReadGroup().getId()+"\n", Level.DEBUG);
    viewer.appendString("Length                "+sam.getReadLength()+"\n", Level.DEBUG);
    viewer.appendString("Reference Name        "+sam.getReferenceName()+"\n", Level.DEBUG);
    viewer.appendString("Inferred Size         "+sam.getInferredInsertSize()+"\n", Level.DEBUG);
    viewer.appendString("Mapping Quality       "+sam.getMappingQuality()+"\n", Level.DEBUG);
    viewer.appendString("Cigar String          "+sam.getCigarString()+"\n", Level.DEBUG);
    viewer.appendString("Strand                "+
        (sam.getReadNegativeStrandFlag() ? "-\n\n" : "+\n\n"), Level.DEBUG);
    if(sam.getReadPairedFlag())
      if(mate != null)
        viewer.appendString("Mate Coordinates      "+mate.getAlignmentStart()+".."+
                                                     mate.getAlignmentEnd()+"\n", Level.DEBUG);
        viewer.appendString("Mate Length           "+mate.getReadLength()+"\n", Level.DEBUG);
        viewer.appendString("Mate Reference Name   "+mate.getReferenceName()+"\n", Level.DEBUG);
        viewer.appendString("Mate Inferred Size    "+mate.getInferredInsertSize()+"\n", Level.DEBUG);
        viewer.appendString("Mate Mapping Quality  "+mate.getMappingQuality()+"\n", Level.DEBUG);
        viewer.appendString("Mate Cigar String     "+mate.getCigarString()+"\n", Level.DEBUG);
        viewer.appendString("Mate Start Coordinate "+sam.getMateAlignmentStart()+"\n", Level.DEBUG);
        viewer.appendString("Mate Reference Name   "+sam.getMateReferenceName()+"\n", Level.DEBUG);
      viewer.appendString("Mate Strand           "+
          (sam.getMateNegativeStrandFlag() ? "-" : "+"), Level.DEBUG);

    viewer.appendString("\n\nFlags:", Level.INFO);
    viewer.appendString("\nDuplicate Read    "+
        (sam.getDuplicateReadFlag() ? "yes" : "no"), Level.DEBUG);
    viewer.appendString("\nRead Paired       "+
        (sam.getReadPairedFlag() ? "yes" : "no"), Level.DEBUG);
    if(sam.getReadPairedFlag())
      viewer.appendString("\nFirst of Pair     "+
        (sam.getFirstOfPairFlag() ? "yes" : "no"), Level.DEBUG);
      viewer.appendString("\nMate Unmapped     "+
        (sam.getMateUnmappedFlag() ? "yes" : "no"), Level.DEBUG);  
      viewer.appendString("\nProper Pair       "+
        (sam.getProperPairFlag() ? "yes" : "no"), Level.DEBUG);
    viewer.appendString("\nRead Fails Vendor\nQuality Check     "+
        (sam.getReadFailsVendorQualityCheckFlag() ? "yes" : "no"), Level.DEBUG);
    viewer.appendString("\nRead Unmapped     "+
        (sam.getReadUnmappedFlag() ? "yes" : "no"), Level.DEBUG);
    if(sam.getReadPairedFlag())
      viewer.appendString("\nSecond Of Pair    "+
        (sam.getSecondOfPairFlag() ? "yes" : "no"), Level.DEBUG);
    viewer.appendString("\n\nRead Bases:\n", Level.INFO);
    wrapReadBases(sam, viewer);
    if(sam.getReadPairedFlag() && mate != null)
    {
      viewer.appendString("\nMate Read Bases:\n", Level.INFO);
      wrapReadBases(mate, viewer);
    }
  }
  
  private static void wrapReadBases(final SAMRecord sam, 
                             final FileViewer viewer)
  {
    final String seq = new String(sam.getReadBases());
    final 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();
      viewer.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
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)
    {
tcarver's avatar
tcarver committed
      logger4j.warn("WARN: BamView.getMate() :: "+e.getMessage());
      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);
      
      final ButtonGroup group = new ButtonGroup();
      group.add(useAllBams);
      group.add(useGroup);

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

      final JCheckBox cbOpposite = new JCheckBox("Assume reads on opposite strand", false);
      cbOpposite.setToolTipText("for cDNA experiments when the reads are on the opposite strand");
      c.gridy++;
      gridPanel.add(cbOpposite, 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(), cbOpposite.isSelected(), 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]);
      else if(args[i].equals("-s"))
        System.setProperty("samtoolDir", args[++i]);
tjc's avatar
tjc committed
      else if(args[i].equals("-c"))
        chr = args[++i].trim();
      else if(args[i].equals("-b"))
        base = Integer.parseInt(args[++i].trim());
      else if(args[i].equals("-v"))
        vw = args[++i].trim();
      else if(args[i].equals("-o"))
        orientation = true;
      else if(args[i].equals("-pc"))
        covPlot = true;
      else if(args[i].equals("-ps"))
        snpPlot = true;
tjc's avatar
tjc committed
      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)");
tjc's avatar
tjc committed
        System.out.println("-n\t number of bases to display in the view (optional)");
        System.out.println("-c\t chromosome name (optional)");
        System.out.println("-v\t view (optional - IS (inferred size), S (stack, default), PS (paired stack), ST (strand), C (coverage))");
        System.out.println("-b\t base position (optional)");
        System.out.println("-o\t show orientation (optional)");
        System.out.println("-pc\t plot coverage (optional)");
        System.out.println("-ps\t plot SNP (optional and only with -r)");
tjc's avatar
tjc committed
        System.exit(0);
      }
    }

tjc's avatar
tjc committed
    final BamView view = new BamView(bam, reference, nbasesInView, null, null,
        (JPanel)frame.getContentPane(), frame);
tjc's avatar
tjc committed
    frame.setTitle("BamView v"+view.getVersion());
tjc's avatar
tjc committed
    
tjc's avatar
tjc committed
    if(chr != null)
      view.combo.setSelectedItem(chr);
    if(vw != null)
    {
      if(vw.equalsIgnoreCase("IS"))
        view.cbIsizeStackView.setSelected(true);
      if(vw.equalsIgnoreCase("PS"))
        view.cbPairedStackView.setSelected(true);
      if(vw.equalsIgnoreCase("ST"))
        view.cbStrandStackView.setSelected(true);
      if(vw.equalsIgnoreCase("C"))
        view.cbCoverageView.setSelected(true);
    }
    if(base > 0)
      view.scrollBar.setValue(base);
    if(orientation)
      view.isOrientation = true;
    if(covPlot)
    {
      view.isCoverage = true;
      view.coveragePanel.setVisible(true);
    }
    if(snpPlot)
    {
      view.isSNPplot = true;
      view.snpPanel.setVisible(true);
    }

    // translucent
    //frame.getRootPane().putClientProperty("Window.alpha", new Float(0.9f));
    /*frame.addWindowFocusListener(new WindowFocusListener()
tjc's avatar
tjc committed
    {
      public void windowGainedFocus(WindowEvent e)
      {
        view.requestFocus();
      }
      public void windowLostFocus(WindowEvent e){}
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
  }
}