@Override public boolean nextKeyValue() { long virtPos; while ((virtPos = bci.getFilePointer()) < virtualEnd || (keepReadPairsTogether && readPair && !lastOfPair)) { final SAMRecord r = codec.decode(); if (r == null) return false; // Since we're reading from a BAMRecordCodec directly we have to set the // validation stringency ourselves. if (this.stringency != null) r.setValidationStringency(this.stringency); readPair = r.getReadPairedFlag(); if (readPair) { boolean first = r.getFirstOfPairFlag(), second = r.getSecondOfPairFlag(); // According to the SAM spec (section 1.4) it is possible for pairs to have // multiple segments (i.e. more than two), in which case both `first` and // `second` will be true. boolean firstOfPair = first && !second; lastOfPair = !first && second; // ignore any template that is not first in a pair right at the start of a split // since it will have been returned in the previous split if (virtPos == virtualStart && keepReadPairsTogether && !firstOfPair) { continue; } } if (!overlaps(r)) { continue; } key.set(getKey(r)); record.set(r); return true; } return false; }
@Test public void testWithIndividualReadBarcodes() { final AbstractMarkDuplicatesCommandLineProgramTester tester = getTester(); final String readNameOne = "RUNID:1:1:15993:13361"; final String readNameTwo = "RUNID:2:2:15993:13362"; final String readNameThree = "RUNID:3:3:15993:13362"; // first two reads have the same barcode (all three), third read has a different barcode for the // second end tester.addMatePair( readNameOne, 2, 41212324, 41212310, false, false, false, false, "33S35M", "19S49M", true, true, false, false, false, DEFAULT_BASE_QUALITY); tester.addMatePair( readNameTwo, 2, 41212324, 41212310, false, false, true, true, "33S35M", "19S49M", true, true, false, false, false, DEFAULT_BASE_QUALITY); // same barcode as the first tester.addMatePair( readNameThree, 2, 41212324, 41212310, false, false, false, false, "33S35M", "19S49M", true, true, false, false, false, DEFAULT_BASE_QUALITY); final String barcodeTag = "BC"; final String readOneBarcodeTag = "BX"; // want the same tag as the second end, since this is allowed final String readTwoBarcodeTag = "BX"; for (final SAMRecord record : new IterableAdapter<SAMRecord>(tester.getRecordIterator())) { record.setAttribute(barcodeTag, "Barcode1"); // same barcode if (record.getFirstOfPairFlag()) { // always the same value for the first end record.setAttribute(readOneBarcodeTag, "readOne1"); } else { // second end if (record.getReadName().equals(readNameOne) || record.getReadName().equals(readNameTwo)) { record.setAttribute(readTwoBarcodeTag, "readTwo1"); } else if (record.getReadName().equals(readNameThree)) { record.setAttribute(readTwoBarcodeTag, "readTwo2"); } } } tester.addArg("BARCODE_TAG=" + barcodeTag); tester.addArg("READ_ONE_BARCODE_TAG=" + readOneBarcodeTag); tester.addArg("READ_TWO_BARCODE_TAG=" + readTwoBarcodeTag); tester.runTest(); }