
htsjdk.samtools.sra.SRALazyRecord Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of htsjdk Show documentation
Show all versions of htsjdk Show documentation
A Java API for high-throughput sequencing data (HTS) formats
/*===========================================================================
*
* PUBLIC DOMAIN NOTICE
* National Center for Biotechnology Information
*
* This software/database is a "United States Government Work" under the
* terms of the United States Copyright Act. It was written as part of
* the author's official duties as a United States Government employee and
* thus cannot be copyrighted. This software/database is freely available
* to the public for use. The National Library of Medicine and the U.S.
* Government have not placed any restriction on its use or reproduction.
*
* Although all reasonable efforts have been taken to ensure the accuracy
* and reliability of the software and data, the NLM and the U.S.
* Government do not and cannot warrant the performance or results that
* may be obtained by using this software or data. The NLM and the U.S.
* Government disclaim all warranties, express or implied, including
* warranties of performance, merchantability or fitness for any particular
* purpose.
*
* Please cite the author in any work or product based on this material.
*
* ===========================================================================
*
*/
package htsjdk.samtools.sra;
import gov.nih.nlm.ncbi.ngs.NGS;
import htsjdk.samtools.*;
import htsjdk.samtools.util.Log;
import ngs.ReadCollection;
import ngs.AlignmentIterator;
import ngs.Alignment;
import ngs.ReadIterator;
import ngs.Read;
import ngs.Fragment;
import ngs.ErrorMsg;
import java.util.EnumSet;
import java.util.Set;
import java.util.Map;
import java.util.HashMap;
import java.util.List;
/**
* Extends SAMRecord so that any of the fields will be loaded only when needed.
* Since SRA is a column oriented database, it is very inefficient to load all the fields at once.
* However, loading only set of actually needed fields will be even faster than in row oriented databases.
*
* Because of that we are providing lazy loading of fields, flags and attributes.
*
* Created by andrii.nikitiuk on 8/25/15.
*/
public class SRALazyRecord extends SAMRecord {
private static final Log log = Log.getInstance(SRALazyRecord.class);
private SRAAccession accession;
private boolean isAligned;
private transient ReadCollection run;
private transient Alignment alignmentIterator;
private transient Read unalignmentIterator;
private String sraReadId;
private String sraAlignmentId;
private int unalignedReadFragmentIndex = -1;
private Set initializedFields = EnumSet.noneOf(LazyField.class);
private Set initializedFlags = EnumSet.noneOf(LazyFlag.class);
private Set initializedAttributes = EnumSet.noneOf(LazyAttribute.class);
private enum LazyField {
ALIGNMENT_START {
@Override
public void loadValue(SRALazyRecord self) {
self.getAlignmentStart();
}
},
MAPPING_QUALITY {
@Override
public void loadValue(SRALazyRecord self) {
self.getMappingQuality();
}
},
REFERENCE_NAME {
@Override
public void loadValue(SRALazyRecord self) {
self.getReferenceName();
}
},
CIGAR_STRING {
@Override
public void loadValue(SRALazyRecord self) {
self.getCigarString();
}
},
BASES {
@Override
public void loadValue(SRALazyRecord self) {
self.getReadBases();
}
},
QUALS {
@Override
public void loadValue(SRALazyRecord self) {
self.getBaseQualities();
}
},
MATE_ALIGNMENT_START {
@Override
public void loadValue(SRALazyRecord self) {
self.getMateAlignmentStart();
}
},
MATE_REFERENCE_NAME {
@Override
public void loadValue(SRALazyRecord self) {
self.getMateReferenceName();
}
},
INFERRED_INSERT_SIZE {
@Override
public void loadValue(SRALazyRecord self) {
self.getInferredInsertSize();
}
};
public abstract void loadValue(SRALazyRecord self);
}
private enum LazyFlag {
READ_NEGATIVE_STRAND(true) {
@Override
public boolean getFlag(SRALazyRecord self) {
return self.getReadNegativeStrandFlag();
}
},
READ_PAIRED(true) {
@Override
public boolean getFlag(SRALazyRecord self) {
return self.getReadPairedFlag();
}
},
PROPER_PAIR(false) {
@Override
public boolean getFlag(SRALazyRecord self) {
return self.getProperPairFlag();
}
},
SECONDARY_ALIGNMENT(true) {
@Override
public boolean getFlag(SRALazyRecord self) {
return self.isSecondaryAlignment();
}
},
MATE_NEGATIVE_STRAND(false) {
@Override
public boolean getFlag(SRALazyRecord self) {
return self.getMateNegativeStrandFlag();
}
},
MATE_UNMAPPED(false) {
@Override
public boolean getFlag(SRALazyRecord self) {
return self.getMateUnmappedFlag();
}
},
FIRST_OF_PAIR(false) {
@Override
public boolean getFlag(SRALazyRecord self) {
return self.getFirstOfPairFlag();
}
},
SECOND_OF_PAIR(false) {
@Override
public boolean getFlag(SRALazyRecord self) {
return self.getSecondOfPairFlag();
}
};
private final boolean canCallOnNotPaired;
LazyFlag(final boolean canCallOnNotPaired) {
this.canCallOnNotPaired = canCallOnNotPaired;
}
public boolean canCallOnNotPaired() { return canCallOnNotPaired; }
public abstract boolean getFlag(SRALazyRecord self);
}
private enum LazyAttribute {
RG {
@Override
public String getAttribute(SRALazyRecord self) {
return self.getAttributeGroupNameImpl();
}
};
public abstract String getAttribute(SRALazyRecord self);
}
private static Map lazyAttributeTags;
static
{
lazyAttributeTags = new HashMap();
lazyAttributeTags.put(SAMTag.RG.getBinaryTag(), LazyAttribute.RG);
}
public SRALazyRecord(final SAMFileHeader header, SRAAccession accession, ReadCollection run, AlignmentIterator alignmentIterator, String readId, String alignmentId) {
this(header, accession, readId, alignmentId);
this.run = run;
this.alignmentIterator = alignmentIterator;
}
public SRALazyRecord(final SAMFileHeader header, SRAAccession accession, ReadCollection run, ReadIterator unalignmentIterator, String readId, int unalignedReadFragmentIndex) {
this(header, accession, readId, unalignedReadFragmentIndex);
this.run = run;
this.unalignmentIterator = unalignmentIterator;
}
protected SRALazyRecord(final SAMFileHeader header, SRAAccession accession, String readId, String alignmentId) {
this(header, accession, readId, true);
this.sraAlignmentId = alignmentId;
}
protected SRALazyRecord(final SAMFileHeader header, SRAAccession accession, String readId, int unalignedReadFragmentIndex) {
this(header, accession, readId, false);
this.unalignedReadFragmentIndex = unalignedReadFragmentIndex;
}
private SRALazyRecord(final SAMFileHeader header, SRAAccession accession, String readId, boolean isAligned) {
super(header);
this.accession = accession;
this.isAligned = isAligned;
this.sraReadId = readId;
setReadName(readId);
setReadUnmappedFlag(!isAligned);
}
/**
* Is being called when original NGS iterator is being moved to the next object.
* Later, if any of uninitialized fields is requested, either Read object or Alignment has to be retrieved from
* ReadCollection
*/
public void detachFromIterator() {
alignmentIterator = null;
unalignmentIterator = null;
}
// ===== fields =====
@Override
public int getAlignmentStart() {
if (!initializedFields.contains(LazyField.ALIGNMENT_START)) {
setAlignmentStart(getAlignmentStartImpl());
}
return super.getAlignmentStart();
}
@Override
public void setAlignmentStart(final int value) {
if (!initializedFields.contains(LazyField.ALIGNMENT_START)) {
initializedFields.add(LazyField.ALIGNMENT_START);
}
super.setAlignmentStart(value);
}
@Override
public int getMappingQuality() {
if (!initializedFields.contains(LazyField.MAPPING_QUALITY)) {
setMappingQuality(getMappingQualityImpl());
}
return super.getMappingQuality();
}
@Override
public void setMappingQuality(final int value) {
if (!initializedFields.contains(LazyField.MAPPING_QUALITY)) {
initializedFields.add(LazyField.MAPPING_QUALITY);
}
super.setMappingQuality(value);
}
@Override
public String getReferenceName() {
if (!initializedFields.contains(LazyField.REFERENCE_NAME)) {
setReferenceName(getReferenceNameImpl());
}
return super.getReferenceName();
}
@Override
public void setReferenceName(final String value) {
if (!initializedFields.contains(LazyField.REFERENCE_NAME)) {
initializedFields.add(LazyField.REFERENCE_NAME);
}
super.setReferenceName(value);
}
@Override
public Integer getReferenceIndex() {
if (!initializedFields.contains(LazyField.REFERENCE_NAME)) {
setReferenceName(getReferenceNameImpl());
}
return super.getReferenceIndex();
}
@Override
public void setReferenceIndex(final int value) {
if (!initializedFields.contains(LazyField.REFERENCE_NAME)) {
initializedFields.add(LazyField.REFERENCE_NAME);
}
super.setReferenceIndex(value);
}
@Override
public String getCigarString() {
if (!initializedFields.contains(LazyField.CIGAR_STRING)) {
setCigarString(getCigarStringImpl());
}
return super.getCigarString();
}
@Override
public void setCigarString(final String value) {
if (!initializedFields.contains(LazyField.CIGAR_STRING)) {
initializedFields.add(LazyField.CIGAR_STRING);
}
super.setCigarString(value);
}
@Override
public Cigar getCigar() {
if (!initializedFields.contains(LazyField.CIGAR_STRING)) {
setCigarString(getCigarStringImpl());
}
return super.getCigar();
}
@Override
public void setCigar(final Cigar value) {
if (!initializedFields.contains(LazyField.CIGAR_STRING)) {
initializedFields.add(LazyField.CIGAR_STRING);
}
super.setCigar(value);
}
@Override
public byte[] getReadBases() {
if (!initializedFields.contains(LazyField.BASES)) {
setReadBases(getReadBasesImpl());
}
return super.getReadBases();
}
@Override
public void setReadBases(final byte[] value) {
if (!initializedFields.contains(LazyField.BASES)) {
initializedFields.add(LazyField.BASES);
}
super.setReadBases(value);
}
@Override
public byte[] getBaseQualities() {
if (!initializedFields.contains(LazyField.QUALS)) {
setBaseQualities(getBaseQualitiesImpl());
}
return super.getBaseQualities();
}
@Override
public void setBaseQualities(final byte[] value) {
if (!initializedFields.contains(LazyField.QUALS)) {
initializedFields.add(LazyField.QUALS);
}
super.setBaseQualities(value);
}
@Override
public int getMateAlignmentStart() {
if (!initializedFields.contains(LazyField.MATE_ALIGNMENT_START)) {
setMateAlignmentStart(getMateAlignmentStartImpl());
}
return super.getMateAlignmentStart();
}
@Override
public void setMateAlignmentStart(final int value) {
if (!initializedFields.contains(LazyField.MATE_ALIGNMENT_START)) {
initializedFields.add(LazyField.MATE_ALIGNMENT_START);
}
super.setMateAlignmentStart(value);
}
@Override
public String getMateReferenceName() {
if (!initializedFields.contains(LazyField.MATE_REFERENCE_NAME)) {
setMateReferenceName(getMateReferenceNameImpl());
}
return super.getMateReferenceName();
}
@Override
public void setMateReferenceName(final String value) {
if (!initializedFields.contains(LazyField.MATE_REFERENCE_NAME)) {
initializedFields.add(LazyField.MATE_REFERENCE_NAME);
}
super.setMateReferenceName(value);
}
@Override
public Integer getMateReferenceIndex() {
if (!initializedFields.contains(LazyField.MATE_REFERENCE_NAME)) {
setMateReferenceName(getMateReferenceNameImpl());
}
return super.getMateReferenceIndex();
}
@Override
public void setMateReferenceIndex(final int value) {
if (!initializedFields.contains(LazyField.MATE_REFERENCE_NAME)) {
initializedFields.add(LazyField.MATE_REFERENCE_NAME);
}
super.setMateReferenceIndex(value);
}
@Override
public int getInferredInsertSize() {
if (!initializedFields.contains(LazyField.INFERRED_INSERT_SIZE)) {
setInferredInsertSize(getInferredInsertSizeImpl());
}
return super.getInferredInsertSize();
}
@Override
public void setInferredInsertSize(final int value) {
if (!initializedFields.contains(LazyField.INFERRED_INSERT_SIZE)) {
initializedFields.add(LazyField.INFERRED_INSERT_SIZE);
}
super.setInferredInsertSize(value);
}
// ===== flags =====
@Override
public int getFlags() {
for (LazyFlag flag : LazyFlag.values()) {
if (initializedFlags.contains(flag)) {
continue;
}
if (flag.canCallOnNotPaired() || getReadPairedFlag()) {
flag.getFlag(this);
}
}
return super.getFlags();
}
@Override
public void setFlags(final int value) {
for (LazyFlag flag : LazyFlag.values()) {
if (!initializedFlags.contains(flag)) {
initializedFlags.add(flag);
}
}
super.setFlags(value);
}
@Override
public boolean getReadNegativeStrandFlag() {
if (!initializedFlags.contains(LazyFlag.READ_NEGATIVE_STRAND)) {
setReadNegativeStrandFlag(getReadNegativeStrandFlagImpl());
}
return super.getReadNegativeStrandFlag();
}
@Override
public void setReadNegativeStrandFlag(final boolean flag) {
if (!initializedFlags.contains(LazyFlag.READ_NEGATIVE_STRAND)) {
initializedFlags.add(LazyFlag.READ_NEGATIVE_STRAND);
}
super.setReadNegativeStrandFlag(flag);
}
@Override
public boolean getReadPairedFlag() {
if (!initializedFlags.contains(LazyFlag.READ_PAIRED)) {
setReadPairedFlag(getReadPairedFlagImpl());
}
return super.getReadPairedFlag();
}
@Override
public void setReadPairedFlag(final boolean flag) {
if (!initializedFlags.contains(LazyFlag.READ_PAIRED)) {
initializedFlags.add(LazyFlag.READ_PAIRED);
}
super.setReadPairedFlag(flag);
}
@Override
public boolean getProperPairFlag() {
if (!initializedFlags.contains(LazyFlag.PROPER_PAIR)) {
setProperPairFlag(getProperPairFlagImpl());
}
return super.getProperPairFlag();
}
@Override
public void setProperPairFlag(final boolean flag) {
if (!initializedFlags.contains(LazyFlag.PROPER_PAIR)) {
initializedFlags.add(LazyFlag.PROPER_PAIR);
}
super.setProperPairFlag(flag);
}
@Override
public boolean isSecondaryAlignment() {
if (!initializedFlags.contains(LazyFlag.SECONDARY_ALIGNMENT)) {
setSecondaryAlignment(getSecondaryAlignmentFlagImpl());
}
return super.isSecondaryAlignment();
}
@Override
public void setSecondaryAlignment(final boolean flag) {
if (!initializedFlags.contains(LazyFlag.SECONDARY_ALIGNMENT)) {
initializedFlags.add(LazyFlag.SECONDARY_ALIGNMENT);
}
super.setSecondaryAlignment(flag);
}
@Override
public boolean getMateNegativeStrandFlag() {
if (!initializedFlags.contains(LazyFlag.MATE_NEGATIVE_STRAND)) {
setMateNegativeStrandFlag(getMateNegativeStrandFlagImpl());
}
return super.getMateNegativeStrandFlag();
}
@Override
public void setMateNegativeStrandFlag(final boolean flag) {
if (!initializedFlags.contains(LazyFlag.MATE_NEGATIVE_STRAND)) {
initializedFlags.add(LazyFlag.MATE_NEGATIVE_STRAND);
}
super.setMateNegativeStrandFlag(flag);
}
@Override
public boolean getMateUnmappedFlag() {
if (!initializedFlags.contains(LazyFlag.MATE_UNMAPPED)) {
setMateUnmappedFlag(getMateUnmappedFlagImpl());
}
return super.getMateUnmappedFlag();
}
@Override
public void setMateUnmappedFlag(final boolean flag) {
if (!initializedFlags.contains(LazyFlag.MATE_UNMAPPED)) {
initializedFlags.add(LazyFlag.MATE_UNMAPPED);
}
super.setMateUnmappedFlag(flag);
}
@Override
public boolean getFirstOfPairFlag() {
if (!initializedFlags.contains(LazyFlag.FIRST_OF_PAIR)) {
setFirstOfPairFlag(getFirstOfPairFlagImpl());
}
return super.getFirstOfPairFlag();
}
@Override
public void setFirstOfPairFlag(final boolean flag) {
if (!initializedFlags.contains(LazyFlag.FIRST_OF_PAIR)) {
initializedFlags.add(LazyFlag.FIRST_OF_PAIR);
}
super.setFirstOfPairFlag(flag);
}
@Override
public boolean getSecondOfPairFlag() {
if (!initializedFlags.contains(LazyFlag.SECOND_OF_PAIR)) {
setSecondOfPairFlag(getSecondOfPairFlagImpl());
}
return super.getSecondOfPairFlag();
}
@Override
public void setSecondOfPairFlag(final boolean flag) {
if (!initializedFlags.contains(LazyFlag.SECOND_OF_PAIR)) {
initializedFlags.add(LazyFlag.SECOND_OF_PAIR);
}
super.setSecondOfPairFlag(flag);
}
// ===== attributes =====
@Override
public Object getAttribute(final short tag) {
LazyAttribute attr = lazyAttributeTags.get(tag);
if (attr != null) {
if (!initializedAttributes.contains(attr)) {
setAttribute(tag, attr.getAttribute(this));
}
}
return super.getAttribute(tag);
}
@Override
public void setAttribute(final short tag, final Object value) {
LazyAttribute attr = lazyAttributeTags.get(tag);
if (attr != null && !initializedAttributes.contains(attr)) {
initializedAttributes.add(attr);
}
super.setAttribute(tag, value);
}
@Override
protected void setAttribute(final short tag, final Object value, final boolean isUnsignedArray) {
LazyAttribute attr = lazyAttributeTags.get(tag);
if (attr != null && !initializedAttributes.contains(attr)) {
initializedAttributes.add(attr);
}
super.setAttribute(tag, value, isUnsignedArray);
}
@Override
public void clearAttributes() {
for (LazyAttribute lazyAttribute : LazyAttribute.values()) {
if (!initializedAttributes.contains(lazyAttribute)) {
initializedAttributes.add(lazyAttribute);
}
}
super.clearAttributes();
}
@Override
protected void setAttributes(final SAMBinaryTagAndValue attributes) {
for (LazyAttribute lazyAttribute : LazyAttribute.values()) {
if (!initializedAttributes.contains(lazyAttribute)) {
initializedAttributes.add(lazyAttribute);
}
}
super.setAttributes(attributes);
}
@Override
protected SAMBinaryTagAndValue getBinaryAttributes() {
for (Map.Entry info : lazyAttributeTags.entrySet()) {
if (!initializedAttributes.contains(info.getValue())) {
getAttribute(info.getKey());
}
}
return super.getBinaryAttributes();
}
@Override
public boolean isUnsignedArrayAttribute(final String tag) {
Short binaryTag = SAMTag.makeBinaryTag(tag);
LazyAttribute attr = lazyAttributeTags.get(binaryTag);
if (attr != null && !initializedAttributes.contains(attr)) {
getAttribute(binaryTag);
}
return super.isUnsignedArrayAttribute(tag);
}
// ===== misc ====
/**
* For records equality, we should only compare read id, reference and position on the reference.
* Since read id is a constructor parameter, we only need to make sure that reference info is loaded.
* @param o other
* @return comparison result
*/
@Override
public boolean equals(final Object o) {
if (o instanceof SRALazyRecord) {
SRALazyRecord otherRecord = (SRALazyRecord)o;
otherRecord.getReferenceIndex();
otherRecord.getAlignmentStart();
}
getReferenceIndex();
getAlignmentStart();
return super.equals(o);
}
/**
* The same approach as with 'equals' method. We only load reference and position.
*/
@Override
public int hashCode() {
getReferenceIndex();
getAlignmentStart();
return super.hashCode();
}
/**
* Performs a deep copy of the SAMRecord and detaches a copy from NGS iterator
* @return new object
* @throws CloneNotSupportedException
*/
@Override
public Object clone() throws CloneNotSupportedException {
SRALazyRecord newObject = (SRALazyRecord)super.clone();
newObject.initializedFields = EnumSet.copyOf(this.initializedFields);
newObject.initializedFlags = EnumSet.copyOf(this.initializedFlags);
newObject.initializedAttributes = EnumSet.copyOf(this.initializedAttributes);
newObject.detachFromIterator();
return newObject;
}
@Override
public String format() {
if (!initializedAttributes.contains(LazyAttribute.RG)) {
getAttribute("RG");
}
return super.format();
}
@Override
public List isValid(final boolean firstOnly) {
loadFields();
getFlags();
getBinaryAttributes();
return super.isValid(firstOnly);
}
// =============================== Implementation ========================================
private ReadCollection getReadCollection() {
if (run != null) {
return run;
}
log.debug("Recovering SRA read collection. Accession: " + accession);
try {
return run = NGS.openReadCollection(accession.toString());
} catch (ErrorMsg e) {
throw new RuntimeException(e);
}
}
private Alignment getCurrentAlignment() throws ErrorMsg {
if (!isAligned) {
throw new RuntimeException("Should be called for aligned records only");
}
if (alignmentIterator == null) {
log.debug("Recovering SAM record after detaching from iterator. Alignment id: " + sraAlignmentId);
if (sraAlignmentId == null) {
throw new RuntimeException("Cannot recover SAM object after detaching from iterator: no alignment id");
}
alignmentIterator = getReadCollection().getAlignment(sraAlignmentId);
}
return alignmentIterator;
}
private Read getCurrentUnalignedRead() throws ErrorMsg {
if (isAligned) {
throw new RuntimeException("Should be called for unaligned records only");
}
if (unalignmentIterator == null) {
log.debug("Recovering SAM record after detaching from iterator. Read id: " + sraReadId + ", fragment index: " + unalignedReadFragmentIndex);
if (sraReadId == null) {
throw new RuntimeException("Cannot recover SAM object after detaching from iterator: no read id");
}
Read read = getReadCollection().getRead(sraReadId);
for (int i = 0; i < unalignedReadFragmentIndex + 1; i++) {
read.nextFragment();
}
unalignmentIterator = read;
}
return unalignmentIterator;
}
// ===== fields =====
private void loadFields() {
for (LazyField field : LazyField.values()) {
if (initializedFields.contains(field)) {
continue;
}
field.loadValue(this);
}
}
private int getAlignmentStartImpl() {
try {
if (isAligned) {
return (int) getCurrentAlignment().getAlignmentPosition() + 1;
}
} catch (ErrorMsg e) {
throw new RuntimeException(e);
}
return SAMRecord.NO_ALIGNMENT_START;
}
private int getMappingQualityImpl() {
try {
if (isAligned) {
return getCurrentAlignment().getMappingQuality();
}
} catch (ErrorMsg e) {
throw new RuntimeException(e);
}
return SAMRecord.NO_MAPPING_QUALITY;
}
private String getReferenceNameImpl() {
try {
if (isAligned) {
return getCurrentAlignment().getReferenceSpec();
}
} catch (ErrorMsg e) {
throw new RuntimeException(e);
}
return SAMRecord.NO_ALIGNMENT_REFERENCE_NAME;
}
private String getCigarStringImpl() {
try {
if (isAligned) {
return getCurrentAlignment().getShortCigar(false);
}
} catch (ErrorMsg e) {
throw new RuntimeException(e);
}
return SAMRecord.NO_ALIGNMENT_CIGAR;
}
private byte[] getReadBasesImpl() {
try {
if (isAligned) {
return getCurrentAlignment().getAlignedFragmentBases().getBytes();
} else {
return getCurrentUnalignedRead().getFragmentBases().getBytes();
}
} catch (ErrorMsg e) {
throw new RuntimeException(e);
}
}
private byte[] getBaseQualitiesImpl() {
try {
Fragment fragment;
if (isAligned) {
fragment = getCurrentAlignment();
} else {
fragment = getCurrentUnalignedRead();
}
// quals are being taken from PRIMARY_ALIGNMENT.SAM_QUALITY column which reverse automatically them if needed
return SAMUtils.fastqToPhred(fragment.getFragmentQualities());
} catch (ErrorMsg e) {
throw new RuntimeException(e);
}
}
private int getMateAlignmentStartImpl() {
try {
if (isAligned && getReadPairedFlag() && !getMateUnmappedFlag()) {
Alignment mate = getCurrentAlignment().getMateAlignment();
return (int) mate.getAlignmentPosition() + 1;
}
} catch (ErrorMsg e) {
throw new RuntimeException(e);
}
return SAMRecord.NO_ALIGNMENT_START;
}
private String getMateReferenceNameImpl() {
try {
if (isAligned && getReadPairedFlag() && !getMateUnmappedFlag()) {
return getCurrentAlignment().getMateReferenceSpec();
}
} catch (ErrorMsg e) {
throw new RuntimeException(e);
}
return SAMRecord.NO_ALIGNMENT_REFERENCE_NAME;
}
private int getInferredInsertSizeImpl() {
try {
if (isAligned) {
return (int) getCurrentAlignment().getTemplateLength();
}
} catch (ErrorMsg e) {
throw new RuntimeException(e);
}
return 0;
}
// ===== flags =====
private boolean getReadNegativeStrandFlagImpl() {
try {
if (isAligned) {
return getCurrentAlignment().getIsReversedOrientation();
}
} catch (ErrorMsg e) {
throw new RuntimeException(e);
}
return false;
}
private boolean getReadPairedFlagImpl() {
try {
if (isAligned) {
return getCurrentAlignment().isPaired();
} else {
return getCurrentUnalignedRead().getNumFragments() > 1;
}
} catch (ErrorMsg e) {
throw new RuntimeException(e);
}
}
private boolean getProperPairFlagImpl() {
return isAligned && getReadPairedFlag() && !getMateUnmappedFlag();
}
private boolean getSecondaryAlignmentFlagImpl() {
try {
if (isAligned) {
return getCurrentAlignment().getAlignmentCategory() == Alignment.secondaryAlignment;
}
} catch (ErrorMsg e) {
throw new RuntimeException(e);
}
return false;
}
private boolean getMateNegativeStrandFlagImpl() {
try {
if (isAligned && getReadPairedFlag() && !getMateUnmappedFlag()) {
Alignment mate = getCurrentAlignment().getMateAlignment();
return mate.getIsReversedOrientation();
}
} catch (ErrorMsg e) {
throw new RuntimeException(e);
}
return false;
}
private boolean getMateUnmappedFlagImpl() {
try {
if (isAligned) {
return !getCurrentAlignment().hasMate();
} else {
Read unalignedRead = getCurrentUnalignedRead();
int numFragments = unalignedRead.getNumFragments();
int nextFragmentIdx = unalignedReadFragmentIndex + 1;
if (nextFragmentIdx == numFragments) {
nextFragmentIdx = 0;
}
return unalignedRead.fragmentIsAligned(nextFragmentIdx);
}
} catch (ErrorMsg e) {
throw new RuntimeException(e);
}
}
private boolean getFirstOfPairFlagImpl() {
if (!getReadPairedFlag()) {
return false;
}
try {
if (isAligned) {
String fragmentId = getCurrentAlignment().getFragmentId();
if (!fragmentId.contains(".FA")) {
throw new RuntimeException("Invalid fragment id: " + fragmentId);
}
return fragmentId.contains(".FA0.");
} else {
return unalignedReadFragmentIndex == 0;
}
} catch (ErrorMsg e) {
throw new RuntimeException(e);
}
}
private boolean getSecondOfPairFlagImpl() {
if (!getReadPairedFlag()) {
return false;
}
try {
if (isAligned) {
String fragmentId = getCurrentAlignment().getFragmentId();
if (!fragmentId.contains(".FA")) {
throw new RuntimeException("Invalid fragment id: " + fragmentId);
}
return !fragmentId.contains(".FA0.");
} else {
return unalignedReadFragmentIndex != 0;
}
} catch (ErrorMsg e) {
throw new RuntimeException(e);
}
}
// ===== attributes =====
private String getAttributeGroupNameImpl() {
try {
String readGroupName;
if (isAligned) {
readGroupName = getCurrentAlignment().getReadGroup();
} else {
readGroupName = getCurrentUnalignedRead().getReadGroup();
}
if (!readGroupName.isEmpty()) {
return readGroupName;
}
return getReadCollection().getName();
} catch (ErrorMsg e) {
throw new RuntimeException(e);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy