@Test(dataProvider = "LIBSTest")
  public void testLIBS(LIBSTest params) {
    final int locus = 44367788;

    SAMRecord read =
        ArtificialSAMUtils.createArtificialRead(header, "read", 0, locus, params.readLength);
    read.setReadBases(Utils.dupBytes((byte) 'A', params.readLength));
    read.setBaseQualities(Utils.dupBytes((byte) '@', params.readLength));
    read.setCigarString(params.cigar);

    // create the iterator by state with the fake reads and fake records
    li = makeLTBS(Arrays.asList(read), createTestReadProperties());
    final LIBS_position tester = new LIBS_position(read);

    while (li.hasNext()) {
      AlignmentContext alignmentContext = li.next();
      ReadBackedPileup p = alignmentContext.getBasePileup();
      Assert.assertTrue(p.getNumberOfElements() == 1);
      PileupElement pe = p.iterator().next();

      tester.stepForwardOnGenome();

      Assert.assertEquals(pe.isBeforeDeletedBase(), tester.isBeforeDeletedBase);
      Assert.assertEquals(pe.isBeforeDeletionStart(), tester.isBeforeDeletionStart);
      Assert.assertEquals(pe.isAfterDeletedBase(), tester.isAfterDeletedBase);
      Assert.assertEquals(pe.isAfterDeletionEnd(), tester.isAfterDeletionEnd);
      Assert.assertEquals(pe.isBeforeInsertion(), tester.isBeforeInsertion);
      Assert.assertEquals(pe.isAfterInsertion(), tester.isAfterInsertion);
      Assert.assertEquals(pe.isNextToSoftClip(), tester.isNextToSoftClip);
      Assert.assertEquals(pe.getOffset(), tester.getCurrentReadOffset());
    }
  }
  @Test
  public void testWholeIndelReadInIsolation() {
    final int firstLocus = 44367789;

    // create a test version of the Reads object
    ReadProperties readAttributes = createTestReadProperties();

    SAMRecord indelOnlyRead =
        ArtificialSAMUtils.createArtificialRead(header, "indelOnly", 0, firstLocus, 76);
    indelOnlyRead.setReadBases(Utils.dupBytes((byte) 'A', 76));
    indelOnlyRead.setBaseQualities(Utils.dupBytes((byte) '@', 76));
    indelOnlyRead.setCigarString("76I");

    List<SAMRecord> reads = Arrays.asList(indelOnlyRead);

    // create the iterator by state with the fake reads and fake records
    li = makeLTBS(reads, readAttributes);

    // Traditionally, reads that end with indels bleed into the pileup at the following locus.
    // Verify that the next pileup contains this read
    // and considers it to be an indel-containing read.
    Assert.assertTrue(
        li.hasNext(),
        "Should have found a whole-indel read in the normal base pileup without extended events enabled");
    AlignmentContext alignmentContext = li.next();
    Assert.assertEquals(
        alignmentContext.getLocation().getStart(),
        firstLocus,
        "Base pileup is at incorrect location.");
    ReadBackedPileup basePileup = alignmentContext.getBasePileup();
    Assert.assertEquals(basePileup.getReads().size(), 1, "Pileup is of incorrect size");
    Assert.assertSame(basePileup.getReads().get(0), indelOnlyRead, "Read in pileup is incorrect");
  }
Esempio n. 3
0
 /**
  * Basic positive and negative tests for the PolyANoiseFilter
  *
  * @param sequence The sequence to be tested
  * @param expectedResult The expected result (true is the sequence should match the filter,
  *     otherwise false)
  */
 @Test(dataProvider = "data")
 public void testSolexaNoiseFilter(
     final String testName, final String sequence, final boolean expectedResult) {
   builder.addUnmappedFragment("testfrag");
   final SAMRecord record = builder.iterator().next();
   record.setReadString(sequence);
   Assert.assertEquals(filter.filterOut(record), expectedResult, testName);
 }
Esempio n. 4
0
 public void addAlignment(SAMRecord samRecord) {
   final SAMReaderID id = toolkit.getReaderIDForRead(samRecord);
   String rg = samRecord.getStringAttribute("RG");
   if (rg != null) {
     String rg_orig = toolkit.getReadsDataSource().getOriginalReadGroupId(rg);
     samRecord.setAttribute("RG", rg_orig);
   }
   addAlignment(samRecord, id);
 }
Esempio n. 5
0
 public MyIterator(SAMRecord record) {
   this.record = record;
   if (record.getReadUnmappedFlag()) throw new IllegalArgumentException("unmapped read");
   this.readPos0 = 0;
   this.genomePos1 = record.getAlignmentStart();
   this._next_genomePos1 = this.genomePos1;
   this._next_readPos0 = this.readPos0;
   if (this.genomePos1 < 1) throw new IllegalArgumentException("record");
   this.cigar = record.getCigar();
 }
  public SAMRecord poll() {
    if (drain) return doPoll();

    SAMRecord head = delegateQueue.peek();
    if (head == null) return null;

    if (maxAlignmentStart - head.getAlignmentStart() < minAlignmentDelay) return null;

    return doPoll();
  }
  @Test
  public void onePerChromosome() {
    StingSAMIterator iter = ArtificialSAMUtils.mappedReadIterator(1, 100, 1);
    int count = 0;
    while (iter.hasNext()) {
      SAMRecord rec = iter.next();

      assertEquals(Integer.valueOf(count), rec.getReferenceIndex());
      count++;
    }
    assertEquals(count, 100 * 1);
  }
  @Override
  public boolean passesFilter(SAMRecord bsRead) {

    // passes filter if read is not mapped
    if (bsRead.getReadUnmappedFlag()) return true;

    // if valid mapping orientation not required
    // read passes filter
    if (this.getFilterValue() == false) return true;

    // else return true if read has valid BS mapping orientation
    return bsRead.getCharacterAttribute("BO") == 'V';
  }
Esempio n. 9
0
File: Align.java Progetto: nh13/SRMA
  private static void clearAttributes(
      SAMRecord rec, List<String> optFieldTags, List<Object> optFieldValues) {
    ListIterator<String> iter = saveTags.listIterator();

    while (iter.hasNext()) {
      String tag = iter.next();
      Object attr = rec.getAttribute(tag);
      if (null != attr) {
        optFieldTags.add(tag);
        optFieldValues.add(attr);
      }
    }
    rec.clearAttributes();
  }
Esempio n. 10
0
    public void set(MouseEvent e, SAMRecord sr) {
      if (sr == null) return;
      StringBuffer text = new StringBuffer();
      text.append("<html>");

      if (sr != null) {
        text.append(
            MessageManager.getString("shortreadtrack.name") + " " + sr.getReadName() + "<br/>");
        text.append(
            MessageManager.getString("shortreadtrack.len") + " " + sr.getReadLength() + "<br/>");
        text.append(
            MessageManager.getString("shortreadtrack.cigar") + " " + sr.getCigarString() + "<br/>");
        text.append(
            MessageManager.getString("shortreadtrack.sequence")
                + " "
                + rerun(sr.getReadString())
                + "<br/>");
        text.append(
            MessageManager.getString("shortreadtrack.paired")
                + " "
                + sr.getReadPairedFlag()
                + "<br/>");
        if (sr.getReadPairedFlag()) {
          if (!sr.getMateUnmappedFlag())
            text.append(
                MessageManager.getString("shortreadtrack.mate")
                    + " "
                    + sr.getMateReferenceName()
                    + ":"
                    + sr.getMateAlignmentStart()
                    + "<br/>");
          else text.append(MessageManager.getString("shortreadtrack.mate_missing") + "<br/>");
          text.append(
              MessageManager.getString("shortreadtrack.second") + " " + sr.getFirstOfPairFlag());
        }
        // text.append("<br/>");
      }
      text.append("</html>");
      if (!text.toString().equals(floater.getText())) {
        floater.setText(text.toString());
        this.pack();
      }
      setLocation(e.getXOnScreen() + 5, e.getYOnScreen() + 5);

      if (!isVisible()) {
        setVisible(true);
      }
    }
    public void acceptRecord(final SAMRecordAndReference args) {
      final SAMRecord rec = args.getSamRecord();
      final ReferenceSequence ref = args.getReferenceSequence();

      if (rec.getReadPairedFlag()) {
        if (rec.getFirstOfPairFlag()) {
          firstOfPairCollector.addRecord(rec, ref);
        } else {
          secondOfPairCollector.addRecord(rec, ref);
        }

        pairCollector.addRecord(rec, ref);
      } else {
        unpairedCollector.addRecord(rec, ref);
      }
    }
Esempio n. 12
0
 /**
  * Get the best aligned read, chosen randomly from the pile of best alignments.
  *
  * @param read Read to align.
  * @param newHeader New header to apply to this SAM file. Can be null, but if so, read header must
  *     be valid.
  * @return Read with injected alignment data.
  */
 @Override
 public SAMRecord align(final SAMRecord read, final SAMFileHeader newHeader) {
   if (bwtFiles.autogenerated)
     throw new UnsupportedOperationException(
         "Cannot create target alignment; source contig was generated ad-hoc and is not reliable");
   return Alignment.convertToRead(getBestAlignment(read.getReadBases()), read, newHeader);
 }
Esempio n. 13
0
  /**
   * Finds the adaptor boundary around the read and returns the first base inside the adaptor that
   * is closest to the read boundary. If the read is in the positive strand, this is the first base
   * after the end of the fragment (Picard calls it 'insert'), if the read is in the negative
   * strand, this is the first base before the beginning of the fragment.
   *
   * <p>There are two cases we need to treat here:
   *
   * <p>1) Our read is in the reverse strand :
   *
   * <p><----------------------| * |--------------------->
   *
   * <p>in these cases, the adaptor boundary is at the mate start (minus one)
   *
   * <p>2) Our read is in the forward strand :
   *
   * <p>|----------------------> * <----------------------|
   *
   * <p>in these cases the adaptor boundary is at the start of the read plus the inferred insert
   * size (plus one)
   *
   * @param read the read being tested for the adaptor boundary
   * @return the reference coordinate for the adaptor boundary (effectively the first base IN the
   *     adaptor, closest to the read. NULL if the read is unmapped or the mate is mapped to another
   *     contig.
   */
  public static Integer getAdaptorBoundary(final SAMRecord read) {
    final int MAXIMUM_ADAPTOR_LENGTH = 8;
    final int insertSize =
        Math.abs(
            read
                .getInferredInsertSize()); // the inferred insert size can be negative if the mate
                                           // is mapped before the read (so we take the absolute
                                           // value)

    if (insertSize == 0
        || read
            .getReadUnmappedFlag()) // no adaptors in reads with mates in another chromosome or
                                    // unmapped pairs
    return null;

    Integer
        adaptorBoundary; // the reference coordinate for the adaptor boundary (effectively the first
                         // base IN the adaptor, closest to the read)
    if (read.getReadNegativeStrandFlag())
      adaptorBoundary = read.getMateAlignmentStart() - 1; // case 1 (see header)
    else adaptorBoundary = read.getAlignmentStart() + insertSize + 1; // case 2 (see header)

    if ((adaptorBoundary < read.getAlignmentStart() - MAXIMUM_ADAPTOR_LENGTH)
        || (adaptorBoundary > read.getAlignmentEnd() + MAXIMUM_ADAPTOR_LENGTH))
      adaptorBoundary =
          null; // we are being conservative by not allowing the adaptor boundary to go beyond what
                // we belive is the maximum size of an adaptor

    return adaptorBoundary;
  }
Esempio n. 14
0
File: Align.java Progetto: nh13/SRMA
  private static void resetAttributes(
      SAMRecord rec, List<String> optFieldTags, List<Object> optFieldValues) {
    ListIterator<String> iterTags = optFieldTags.listIterator();
    ListIterator<Object> iterValues = optFieldValues.listIterator();

    while (iterTags.hasNext()) {
      rec.setAttribute(iterTags.next(), iterValues.next());
    }
  }
Esempio n. 15
0
  /**
   * checks if the read has a platform tag in the readgroup equal to 'name'. Assumes that 'name' is
   * upper-cased.
   *
   * @param read the read to test
   * @param name the upper-cased platform name to test
   * @return whether or not name == PL tag in the read group of read
   */
  public static boolean isPlatformRead(SAMRecord read, String name) {

    SAMReadGroupRecord readGroup = read.getReadGroup();
    if (readGroup != null) {
      Object readPlatformAttr = readGroup.getAttribute("PL");
      if (readPlatformAttr != null) return readPlatformAttr.toString().toUpperCase().contains(name);
    }
    return false;
  }
      public void addRecord(final SAMRecord record, final ReferenceSequence ref) {
        if (record.isSecondaryOrSupplementary()) {
          // only want 1 count per read so skip non primary alignments
          return;
        }

        collectReadData(record, ref);
        collectQualityData(record, ref);
      }
Esempio n. 17
0
  protected int doWork() {
    IoUtil.assertFileIsReadable(INPUT);
    IoUtil.assertFileIsWritable(OUTPUT);

    final SAMFileReader in = new SAMFileReader(INPUT);

    // create the read group we'll be using
    final SAMReadGroupRecord rg = new SAMReadGroupRecord(RGID);
    rg.setLibrary(RGLB);
    rg.setPlatform(RGPL);
    rg.setSample(RGSM);
    rg.setPlatformUnit(RGPU);
    if (RGCN != null) rg.setSequencingCenter(RGCN);
    if (RGDS != null) rg.setDescription(RGDS);
    if (RGDT != null) rg.setRunDate(RGDT);

    log.info(
        String.format(
            "Created read group ID=%s PL=%s LB=%s SM=%s%n",
            rg.getId(), rg.getPlatform(), rg.getLibrary(), rg.getSample()));

    // create the new header and output file
    final SAMFileHeader inHeader = in.getFileHeader();
    final SAMFileHeader outHeader = inHeader.clone();
    outHeader.setReadGroups(Arrays.asList(rg));
    if (SORT_ORDER != null) outHeader.setSortOrder(SORT_ORDER);

    final SAMFileWriter outWriter =
        new SAMFileWriterFactory()
            .makeSAMOrBAMWriter(
                outHeader, outHeader.getSortOrder() == inHeader.getSortOrder(), OUTPUT);

    final ProgressLogger progress = new ProgressLogger(log);
    for (final SAMRecord read : in) {
      read.setAttribute(SAMTag.RG.name(), RGID);
      outWriter.addAlignment(read);
      progress.record(read);
    }

    // cleanup
    in.close();
    outWriter.close();
    return 0;
  }
        /**
         * The sorting by alignment start is not stable. Therefore we use an integere value here,
         * which is incremented for each record added/
         *
         * @param o1
         * @param o2
         * @return
         */
        @Override
        public int compare(SAMRecord o1, SAMRecord o2) {

          int result = o1.getAlignmentStart() - o2.getAlignmentStart();
          if (result != 0) return result;

          int c1 = (Integer) o1.getAttribute("X~");
          int c2 = (Integer) o2.getAttribute("X~");
          return c1 - c2;

          // result = o1.getReadLength() - o2.getReadLength();
          // if (result != 0)
          // return result;
          //
          // result = o1.getReadString().compareTo(o2.getReadString());
          // if (result != 0)
          // return result;
          //
          // result = o1.getReadName().compareTo(o2.getReadName());
          // return result;

        }
Esempio n. 19
0
  @Test
  public void basicUnmappedIteratorTest() {
    StingSAMIterator iter = ArtificialSAMUtils.mappedAndUnmappedReadIterator(1, 100, 100, 1000);
    int count = 0;
    for (int x = 0; x < (100 * 100); x++) {
      if (!iter.hasNext()) {
        fail("we didn't get the expected number of reads");
      }
      SAMRecord rec = iter.next();
      assertTrue(rec.getReferenceIndex() >= 0);
      count++;
    }
    assertEquals(100 * 100, count);

    // now we should have 1000 unmapped reads
    count = 0;
    while (iter.hasNext()) {
      SAMRecord rec = iter.next();
      assertTrue(rec.getReferenceIndex() < 0);
      count++;
    }
    assertEquals(count, 1000);
  }
  /**
   * Test to make sure that reads supporting only an indel (example cigar string: 76I) are
   * represented properly
   */
  @Test
  public void testWholeIndelReadRepresentedTest() {
    final int firstLocus = 44367788, secondLocus = firstLocus + 1;

    SAMRecord read1 = ArtificialSAMUtils.createArtificialRead(header, "read1", 0, secondLocus, 1);
    read1.setReadBases(Utils.dupBytes((byte) 'A', 1));
    read1.setBaseQualities(Utils.dupBytes((byte) '@', 1));
    read1.setCigarString("1I");

    List<SAMRecord> reads = Arrays.asList(read1);

    // create the iterator by state with the fake reads and fake records
    li = makeLTBS(reads, createTestReadProperties());

    while (li.hasNext()) {
      AlignmentContext alignmentContext = li.next();
      ReadBackedPileup p = alignmentContext.getBasePileup();
      Assert.assertTrue(p.getNumberOfElements() == 1);
      PileupElement pe = p.iterator().next();
      Assert.assertTrue(pe.isBeforeInsertion());
      Assert.assertFalse(pe.isAfterInsertion());
      Assert.assertEquals(pe.getEventBases(), "A");
    }

    SAMRecord read2 = ArtificialSAMUtils.createArtificialRead(header, "read2", 0, secondLocus, 10);
    read2.setReadBases(Utils.dupBytes((byte) 'A', 10));
    read2.setBaseQualities(Utils.dupBytes((byte) '@', 10));
    read2.setCigarString("10I");

    reads = Arrays.asList(read2);

    // create the iterator by state with the fake reads and fake records
    li = makeLTBS(reads, createTestReadProperties());

    while (li.hasNext()) {
      AlignmentContext alignmentContext = li.next();
      ReadBackedPileup p = alignmentContext.getBasePileup();
      Assert.assertTrue(p.getNumberOfElements() == 1);
      PileupElement pe = p.iterator().next();
      Assert.assertTrue(pe.isBeforeInsertion());
      Assert.assertFalse(pe.isAfterInsertion());
      Assert.assertEquals(pe.getEventBases(), "AAAAAAAAAA");
    }
  }
Esempio n. 21
0
File: Align.java Progetto: nh13/SRMA
  private static void removeMateInfo(SAMRecord rec) {
    if (rec.getReadPairedFlag()) {
      // Remove all information of its mate

      // flag
      rec.setProperPairFlag(false); // not paired any more
      rec.setMateUnmappedFlag(false);
      rec.setMateNegativeStrandFlag(false);

      // entries
      rec.setMateReferenceIndex(SAMRecord.NO_ALIGNMENT_REFERENCE_INDEX);
      rec.setMateAlignmentStart(0);
      rec.setInferredInsertSize(0);

      // TODO: remove tags and values that are mate pair inclined.
    }
  }
Esempio n. 22
0
  /**
   * Get a iterator of aligned reads, batched by mapping quality.
   *
   * @param read Read to align.
   * @param newHeader Optional new header to use when aligning the read. If present, it must be
   *     null.
   * @return Iterator to alignments.
   */
  @Override
  public Iterable<SAMRecord[]> alignAll(final SAMRecord read, final SAMFileHeader newHeader) {
    if (bwtFiles.autogenerated)
      throw new UnsupportedOperationException(
          "Cannot create target alignment; source contig was generated ad-hoc and is not reliable");
    final Iterable<Alignment[]> alignments = getAllAlignments(read.getReadBases());
    return new Iterable<SAMRecord[]>() {
      public Iterator<SAMRecord[]> iterator() {
        final Iterator<Alignment[]> alignmentIterator = alignments.iterator();
        return new Iterator<SAMRecord[]>() {
          /**
           * Whether all alignments have been seen based on the current position.
           *
           * @return True if any more alignments are pending. False otherwise.
           */
          public boolean hasNext() {
            return alignmentIterator.hasNext();
          }

          /**
           * Return the next cross-section of alignments, based on mapping quality.
           *
           * @return Array of the next set of alignments of a given mapping quality.
           */
          public SAMRecord[] next() {
            Alignment[] alignmentsOfQuality = alignmentIterator.next();
            SAMRecord[] reads = new SAMRecord[alignmentsOfQuality.length];
            for (int i = 0; i < alignmentsOfQuality.length; i++) {
              reads[i] = Alignment.convertToRead(alignmentsOfQuality[i], read, newHeader);
            }
            return reads;
          }

          /** Unsupported. */
          public void remove() {
            throw new UnsupportedOperationException("Cannot remove from an alignment iterator");
          }
        };
      }
    };
  }
  @Test
  public void testIndelsInRegularPileup() {
    final byte[] bases = new byte[] {'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A'};
    final byte[] indelBases =
        new byte[] {'A', 'A', 'A', 'A', 'C', 'T', 'A', 'A', 'A', 'A', 'A', 'A'};

    // create a test version of the Reads object
    ReadProperties readAttributes = createTestReadProperties();

    SAMRecord before = ArtificialSAMUtils.createArtificialRead(header, "before", 0, 1, 10);
    before.setReadBases(bases);
    before.setBaseQualities(new byte[] {20, 20, 20, 20, 20, 20, 20, 20, 20, 20});
    before.setCigarString("10M");

    SAMRecord during = ArtificialSAMUtils.createArtificialRead(header, "during", 0, 2, 10);
    during.setReadBases(indelBases);
    during.setBaseQualities(new byte[] {20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20});
    during.setCigarString("4M2I6M");

    SAMRecord after = ArtificialSAMUtils.createArtificialRead(header, "after", 0, 3, 10);
    after.setReadBases(bases);
    after.setBaseQualities(new byte[] {20, 20, 20, 20, 20, 20, 20, 20, 20, 20});
    after.setCigarString("10M");

    List<SAMRecord> reads = Arrays.asList(before, during, after);

    // create the iterator by state with the fake reads and fake records
    li = makeLTBS(reads, readAttributes);

    boolean foundIndel = false;
    while (li.hasNext()) {
      AlignmentContext context = li.next();
      ReadBackedPileup pileup = context.getBasePileup().getBaseFilteredPileup(10);
      for (PileupElement p : pileup) {
        if (p.isBeforeInsertion()) {
          foundIndel = true;
          Assert.assertEquals(p.getEventLength(), 2, "Wrong event length");
          Assert.assertEquals(p.getEventBases(), "CT", "Inserted bases are incorrect");
          break;
        }
      }
    }

    Assert.assertTrue(foundIndel, "Indel in pileup not found");
  }
  @Test
  public void testXandEQOperators() {
    final byte[] bases1 = new byte[] {'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A'};
    final byte[] bases2 = new byte[] {'A', 'A', 'A', 'C', 'A', 'A', 'A', 'A', 'A', 'C'};

    // create a test version of the Reads object
    ReadProperties readAttributes = createTestReadProperties();

    SAMRecord r1 = ArtificialSAMUtils.createArtificialRead(header, "r1", 0, 1, 10);
    r1.setReadBases(bases1);
    r1.setBaseQualities(new byte[] {20, 20, 20, 20, 20, 20, 20, 20, 20, 20});
    r1.setCigarString("10M");

    SAMRecord r2 = ArtificialSAMUtils.createArtificialRead(header, "r2", 0, 1, 10);
    r2.setReadBases(bases2);
    r2.setBaseQualities(new byte[] {20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20});
    r2.setCigarString("3=1X5=1X");

    SAMRecord r3 = ArtificialSAMUtils.createArtificialRead(header, "r3", 0, 1, 10);
    r3.setReadBases(bases2);
    r3.setBaseQualities(new byte[] {20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20});
    r3.setCigarString("3=1X5M1X");

    SAMRecord r4 = ArtificialSAMUtils.createArtificialRead(header, "r4", 0, 1, 10);
    r4.setReadBases(bases2);
    r4.setBaseQualities(new byte[] {20, 20, 20, 20, 20, 20, 20, 20, 20, 20});
    r4.setCigarString("10M");

    List<SAMRecord> reads = Arrays.asList(r1, r2, r3, r4);

    // create the iterator by state with the fake reads and fake records
    li = makeLTBS(reads, readAttributes);

    while (li.hasNext()) {
      AlignmentContext context = li.next();
      ReadBackedPileup pileup = context.getBasePileup();
      Assert.assertEquals(pileup.depthOfCoverage(), 4);
    }
  }
  /** Steps forward on the genome. Returns false when done reading the read, true otherwise. */
  public boolean stepForwardOnGenome() {
    if (currentOperatorIndex == numOperators) return false;

    CigarElement curElement = read.getCigar().getCigarElement(currentOperatorIndex);
    if (currentPositionOnOperator >= curElement.getLength()) {
      if (++currentOperatorIndex == numOperators) return false;

      curElement = read.getCigar().getCigarElement(currentOperatorIndex);
      currentPositionOnOperator = 0;
    }

    switch (curElement.getOperator()) {
      case I: // insertion w.r.t. the reference
        if (!sawMop) break;
      case S: // soft clip
        currentReadOffset += curElement.getLength();
      case H: // hard clip
      case P: // padding
        currentOperatorIndex++;
        return stepForwardOnGenome();

      case D: // deletion w.r.t. the reference
      case N: // reference skip (looks and gets processed just like a "deletion", just different
        // logical meaning)
        currentPositionOnOperator++;
        break;

      case M:
      case EQ:
      case X:
        sawMop = true;
        currentReadOffset++;
        currentPositionOnOperator++;
        break;
      default:
        throw new IllegalStateException("No support for cigar op: " + curElement.getOperator());
    }

    final boolean isFirstOp = currentOperatorIndex == 0;
    final boolean isLastOp = currentOperatorIndex == numOperators - 1;
    final boolean isFirstBaseOfOp = currentPositionOnOperator == 1;
    final boolean isLastBaseOfOp = currentPositionOnOperator == curElement.getLength();

    isBeforeDeletionStart =
        isBeforeOp(
            read.getCigar(), currentOperatorIndex, CigarOperator.D, isLastOp, isLastBaseOfOp);
    isBeforeDeletedBase =
        isBeforeDeletionStart || (!isLastBaseOfOp && curElement.getOperator() == CigarOperator.D);
    isAfterDeletionEnd =
        isAfterOp(
            read.getCigar(), currentOperatorIndex, CigarOperator.D, isFirstOp, isFirstBaseOfOp);
    isAfterDeletedBase =
        isAfterDeletionEnd || (!isFirstBaseOfOp && curElement.getOperator() == CigarOperator.D);
    isBeforeInsertion =
        isBeforeOp(read.getCigar(), currentOperatorIndex, CigarOperator.I, isLastOp, isLastBaseOfOp)
            || (!sawMop && curElement.getOperator() == CigarOperator.I);
    isAfterInsertion =
        isAfterOp(
            read.getCigar(), currentOperatorIndex, CigarOperator.I, isFirstOp, isFirstBaseOfOp);
    isNextToSoftClip =
        isBeforeOp(read.getCigar(), currentOperatorIndex, CigarOperator.S, isLastOp, isLastBaseOfOp)
            || isAfterOp(
                read.getCigar(), currentOperatorIndex, CigarOperator.S, isFirstOp, isFirstBaseOfOp);

    return true;
  }
 public LIBS_position(final SAMRecord read) {
   this.read = read;
   numOperators = read.getCigar().numCigarElements();
 }
 public void add(SAMRecord record) {
   record.setAttribute("X~", counter++);
   delegateQueue.add(record);
   maxAlignmentStart = Math.max(maxAlignmentStart, record.getAlignmentStart());
 }
  /**
   * Test to make sure that reads supporting only an indel (example cigar string: 76I) do not
   * negatively influence the ordering of the pileup.
   */
  @Test
  public void testWholeIndelRead() {
    final int firstLocus = 44367788, secondLocus = firstLocus + 1;

    SAMRecord leadingRead =
        ArtificialSAMUtils.createArtificialRead(header, "leading", 0, firstLocus, 76);
    leadingRead.setReadBases(Utils.dupBytes((byte) 'A', 76));
    leadingRead.setBaseQualities(Utils.dupBytes((byte) '@', 76));
    leadingRead.setCigarString("1M75I");

    SAMRecord indelOnlyRead =
        ArtificialSAMUtils.createArtificialRead(header, "indelOnly", 0, secondLocus, 76);
    indelOnlyRead.setReadBases(Utils.dupBytes((byte) 'A', 76));
    indelOnlyRead.setBaseQualities(Utils.dupBytes((byte) '@', 76));
    indelOnlyRead.setCigarString("76I");

    SAMRecord fullMatchAfterIndel =
        ArtificialSAMUtils.createArtificialRead(header, "fullMatch", 0, secondLocus, 76);
    fullMatchAfterIndel.setReadBases(Utils.dupBytes((byte) 'A', 76));
    fullMatchAfterIndel.setBaseQualities(Utils.dupBytes((byte) '@', 76));
    fullMatchAfterIndel.setCigarString("75I1M");

    List<SAMRecord> reads = Arrays.asList(leadingRead, indelOnlyRead, fullMatchAfterIndel);

    // create the iterator by state with the fake reads and fake records
    li = makeLTBS(reads, createTestReadProperties());
    int currentLocus = firstLocus;
    int numAlignmentContextsFound = 0;

    while (li.hasNext()) {
      AlignmentContext alignmentContext = li.next();
      Assert.assertEquals(
          alignmentContext.getLocation().getStart(),
          currentLocus,
          "Current locus returned by alignment context is incorrect");

      if (currentLocus == firstLocus) {
        List<GATKSAMRecord> readsAtLocus = alignmentContext.getBasePileup().getReads();
        Assert.assertEquals(
            readsAtLocus.size(), 1, "Wrong number of reads at locus " + currentLocus);
        Assert.assertSame(
            readsAtLocus.get(0),
            leadingRead,
            "leadingRead absent from pileup at locus " + currentLocus);
      } else if (currentLocus == secondLocus) {
        List<GATKSAMRecord> readsAtLocus = alignmentContext.getBasePileup().getReads();
        Assert.assertEquals(
            readsAtLocus.size(), 2, "Wrong number of reads at locus " + currentLocus);
        Assert.assertSame(
            readsAtLocus.get(0),
            indelOnlyRead,
            "indelOnlyRead absent from pileup at locus " + currentLocus);
        Assert.assertSame(
            readsAtLocus.get(1),
            fullMatchAfterIndel,
            "fullMatchAfterIndel absent from pileup at locus " + currentLocus);
      }

      currentLocus++;
      numAlignmentContextsFound++;
    }

    Assert.assertEquals(
        numAlignmentContextsFound, 2, "Found incorrect number of alignment contexts");
  }
 private SAMRecord doPoll() {
   SAMRecord record = delegateQueue.poll();
   if (record == null) return null;
   record.setAttribute("X~", null);
   return record;
 }
 public void dump() {
   while (!delegateQueue.isEmpty()) {
     SAMRecord r = doPoll();
     System.out.println(r.getAlignmentStart() + "\t" + r.getReadName());
   }
 }