Redo StratifiedAlignmentContext to use ReadBackedPileup's stratification options.

git-svn-id: file:///humgen/gsa-scr1/gsa-engineering/svn_contents/trunk@3699 348d0f76-0448-11de-a6fe-93d51630548a
This commit is contained in:
hanna 2010-07-01 02:46:05 +00:00
parent dc4715c9c6
commit c9d5345150
12 changed files with 216 additions and 237 deletions

View File

@ -38,7 +38,7 @@ import java.util.*;
* User: ebanks * User: ebanks
* Modified: chartl (split by read group) * Modified: chartl (split by read group)
*/ */
public class StratifiedAlignmentContext<PE extends PileupElement> { public class StratifiedAlignmentContext<RBP extends ReadBackedPileup> {
// Definitions: // Definitions:
// COMPLETE = full alignment context // COMPLETE = full alignment context
@ -48,97 +48,34 @@ public class StratifiedAlignmentContext<PE extends PileupElement> {
public enum StratifiedContextType { COMPLETE, FORWARD, REVERSE } public enum StratifiedContextType { COMPLETE, FORWARD, REVERSE }
private GenomeLoc loc; private GenomeLoc loc;
private AlignmentContext[] contexts = new AlignmentContext[StratifiedContextType.values().length]; private RBP basePileup = null;
private boolean isExtended = false; // tells whether this alignment context is an extended event context
// todo -- why are you storing reads separately each time? There's a ReadBackedPileup object that's supposed to handle this
// private ArrayList<SAMRecord>[] reads = new ArrayList[StratifiedContextType.values().length];
// private ArrayList<Integer>[] offsets = new ArrayList[StratifiedContextType.values().length];
private ArrayList<PE>[] pileupElems = new ArrayList[StratifiedContextType.values().length];
// //
// accessors // accessors
// //
public GenomeLoc getLocation() { return loc; } public GenomeLoc getLocation() { return loc; }
// public ArrayList<SAMRecord> getReads(StratifiedContextType type) { return reads[type.ordinal()]; }
// public ArrayList<Integer> getOffsets(StratifiedContextType type) { return offsets[type.ordinal()]; }
public ArrayList<PE> getPileupElements(StratifiedContextType type) {
return pileupElems[type.ordinal()];
}
// public ArrayList<ExtendedEventPileupElement> getExtendedPileupElements(StratifiedContextType type) {
// if ( ! isExtended ) throw new StingException("Extended read backed pileups requested from StratifiedAlignmentContext that holds simple pileups");
//
// return (ArrayList<ExtendedEventPileupElement>)(pileupElems[type.ordinal()]);
// }
public StratifiedAlignmentContext(GenomeLoc loc) { public StratifiedAlignmentContext(GenomeLoc loc) {
this(loc,false); this(loc,null);
} }
public StratifiedAlignmentContext(GenomeLoc loc, boolean isExtended) { public StratifiedAlignmentContext(GenomeLoc loc, RBP pileup) {
this.loc = loc; this.loc = loc;
this.isExtended = isExtended; this.basePileup = pileup;
for ( int i = 0; i < StratifiedContextType.values().length; i++) {
if ( isExtended ) pileupElems[i] = new ArrayList<PE>();
else pileupElems[i] = new ArrayList<PE>();
}
} }
public AlignmentContext getContext(StratifiedContextType type) { public AlignmentContext getContext(StratifiedContextType type) {
int index = type.ordinal(); switch(type) {
if ( contexts[index] == null ) { case COMPLETE:
if ( isExtended ) { return new AlignmentContext(loc,basePileup);
contexts[index] = new AlignmentContext(loc, new ReadBackedExtendedEventPileupImpl(loc,(List<ExtendedEventPileupElement>)getPileupElements(type))); case FORWARD:
} else { return new AlignmentContext(loc,basePileup.getPositiveStrandPileup());
contexts[index] = new AlignmentContext(loc, new ReadBackedPileupImpl(loc,(List<PileupElement>)getPileupElements(type))); case REVERSE:
return new AlignmentContext(loc,basePileup.getNegativeStrandPileup());
default:
throw new StingException("Unable to get alignment context for type = " + type);
} }
} }
return contexts[index];
}
public void add(SAMRecord read, int offset) {
if ( isExtended ) throw new StingException("Can not add read/offset without event type specified to the context holding extended events");
if ( read.getReadNegativeStrandFlag() ) {
pileupElems[StratifiedContextType.REVERSE.ordinal()].add((PE)new PileupElement(read,offset));
} else {
pileupElems[StratifiedContextType.FORWARD.ordinal()].add((PE)new PileupElement(read,offset));
}
pileupElems[StratifiedContextType.COMPLETE.ordinal()].add((PE)new PileupElement(read,offset));
}
public void add(PE p) {
// if ( isExtended ) throw new StingException("Can not add simple pileup element to the context holding extended events");
SAMRecord read = p.getRead();
if ( read.getReadNegativeStrandFlag() ) {
pileupElems[StratifiedContextType.REVERSE.ordinal()].add(p);
} else {
pileupElems[StratifiedContextType.FORWARD.ordinal()].add(p);
}
pileupElems[StratifiedContextType.COMPLETE.ordinal()].add(p);
}
public void add(SAMRecord read, int offset, int length, byte [] bases) {
if ( ! isExtended ) throw new StingException("Can not add read/offset with event type specified to the context holding simple events");
if ( read.getReadNegativeStrandFlag() ) {
pileupElems[StratifiedContextType.REVERSE.ordinal()].add((PE)new ExtendedEventPileupElement(read,offset,length,bases));
} else {
pileupElems[StratifiedContextType.FORWARD.ordinal()].add((PE)new ExtendedEventPileupElement(read,offset,length,bases));
}
pileupElems[StratifiedContextType.COMPLETE.ordinal()].add((PE)new ExtendedEventPileupElement(read,offset,length,bases));
}
// public void add(ExtendedEventPileupElement p) {
// if ( ! isExtended ) throw new StingException("Can not add extended pileup element to the context holding simple events");
// SAMRecord read = p.getRead();
// if ( read.getReadNegativeStrandFlag() ) {
// pileupElems[StratifiedContextType.REVERSE.ordinal()].add(p);
// } else {
// pileupElems[StratifiedContextType.FORWARD.ordinal()].add(p);
// }
// pileupElems[StratifiedContextType.COMPLETE.ordinal()].add(p);
// }
/** /**
* Splits the given AlignmentContext into a StratifiedAlignmentContext per sample. * Splits the given AlignmentContext into a StratifiedAlignmentContext per sample.
@ -148,8 +85,8 @@ public class StratifiedAlignmentContext<PE extends PileupElement> {
* @return a Map of sample name to StratifiedAlignmentContext * @return a Map of sample name to StratifiedAlignmentContext
* *
**/ **/
public static Map<String, StratifiedAlignmentContext> splitContextBySample(ReadBackedPileup pileup) { public static <RBP extends ReadBackedPileup,PE extends PileupElement> Map<String, StratifiedAlignmentContext> splitContextBySample(RBP pileup) {
return splitContextBySample(pileup, null, null); return splitContextBySample(pileup, null);
} }
/** /**
@ -157,91 +94,30 @@ public class StratifiedAlignmentContext<PE extends PileupElement> {
* *
* @param pileup the original pileup * @param pileup the original pileup
* @param assumedSingleSample if not null, any read without a readgroup will be given this sample name * @param assumedSingleSample if not null, any read without a readgroup will be given this sample name
* @param collapseToThisSample if not null, all reads will be assigned this read group regardless of their actual read group
* *
* @return a Map of sample name to StratifiedAlignmentContext * @return a Map of sample name to StratifiedAlignmentContext
* *
**/ **/
public static Map<String, StratifiedAlignmentContext> splitContextBySample(ReadBackedPileup pileup, String assumedSingleSample, String collapseToThisSample) { public static <RBP extends ReadBackedPileup> Map<String, StratifiedAlignmentContext> splitContextBySample(RBP pileup, String assumedSingleSample) {
HashMap<String, StratifiedAlignmentContext> contexts = new HashMap<String, StratifiedAlignmentContext>();
GenomeLoc loc = pileup.getLocation(); GenomeLoc loc = pileup.getLocation();
HashMap<String, StratifiedAlignmentContext> contexts = new HashMap<String, StratifiedAlignmentContext>();
for (PileupElement p : pileup ) for(String sampleName: pileup.getSamples()) {
addToContext(contexts, p, loc, assumedSingleSample, collapseToThisSample); RBP pileupBySample = (RBP)pileup.getPileupForSample(sampleName);
if(sampleName != null)
contexts.put(sampleName,new StratifiedAlignmentContext<RBP>(loc,pileupBySample));
else {
if(assumedSingleSample == null && pileupBySample.size() > 0)
throw new StingException("Missing read group for read " + pileupBySample.iterator().next().getRead());
contexts.put(assumedSingleSample,new StratifiedAlignmentContext<RBP>(loc,pileupBySample));
}
}
return contexts; return contexts;
} }
/**
* Splits the given AlignmentContext into a StratifiedAlignmentContext per sample.
*
* @param pileup the original pileup
*
* @return a Map of sample name to StratifiedAlignmentContext
*
**/
public static Map<String, StratifiedAlignmentContext> splitContextBySample(ReadBackedExtendedEventPileup pileup) {
return splitContextBySample(pileup, null, null);
}
/**
* Splits the given AlignmentContext into a StratifiedAlignmentContext per sample.
*
* @param pileup the original pileup
* @param assumedSingleSample if not null, any read without a readgroup will be given this sample name
* @param collapseToThisSample if not null, all reads will be assigned this read group regardless of their actual read group
*
* @return a Map of sample name to StratifiedAlignmentContext
*
**/
public static Map<String, StratifiedAlignmentContext> splitContextBySample(ReadBackedExtendedEventPileup pileup, String assumedSingleSample, String collapseToThisSample) {
HashMap<String, StratifiedAlignmentContext> contexts = new HashMap<String, StratifiedAlignmentContext>();
GenomeLoc loc = pileup.getLocation();
for (PileupElement p : pileup )
addToContext(contexts, p, loc, assumedSingleSample, collapseToThisSample,true);
return contexts;
}
private static void addToContext(HashMap<String, StratifiedAlignmentContext> contexts, PileupElement p, GenomeLoc loc, String assumedSingleSample, String collapseToThisSample) {
addToContext(contexts, p, loc, assumedSingleSample, collapseToThisSample, false);
}
private static void addToContext(HashMap<String, StratifiedAlignmentContext> contexts, PileupElement p, GenomeLoc loc, String assumedSingleSample, String collapseToThisSample, boolean isExtended) {
// get the read
SAMRecord read = p.getRead();
// find the sample
String sample;
if ( collapseToThisSample != null ) {
sample = collapseToThisSample;
} else {
SAMReadGroupRecord readGroup = read.getReadGroup();
if ( readGroup == null ) {
if ( assumedSingleSample == null )
throw new StingException("Missing read group for read " + read.getReadName());
sample = assumedSingleSample;
} else {
sample = readGroup.getSample();
}
}
// create a new context object if this is the first time we're seeing a read for this sample
StratifiedAlignmentContext myContext = contexts.get(sample);
if ( myContext == null ) {
myContext = new StratifiedAlignmentContext(loc,isExtended);
contexts.put(sample, myContext);
}
// add the read to this sample's context
// note that bad bases are added to the context (for DoC calculations later)
myContext.add(p);
}
/** /**
* Splits the given AlignmentContext into a StratifiedAlignmentContext per read group. * Splits the given AlignmentContext into a StratifiedAlignmentContext per read group.
* *
@ -250,57 +126,43 @@ public class StratifiedAlignmentContext<PE extends PileupElement> {
* TODO - support for collapsing or assuming read groups if they are missing * TODO - support for collapsing or assuming read groups if they are missing
* *
**/ **/
public static Map<String,StratifiedAlignmentContext> splitContextByReadGroup(ReadBackedPileup pileup) { public static <RBP extends ReadBackedPileup> Map<String,StratifiedAlignmentContext<RBP>> splitContextByReadGroup(RBP pileup) {
HashMap<String,StratifiedAlignmentContext> contexts = new HashMap<String,StratifiedAlignmentContext>(); HashMap<String,StratifiedAlignmentContext<RBP>> contexts = new HashMap<String,StratifiedAlignmentContext<RBP>>();
for(String readGroupId: pileup.getReadGroups())
for ( PileupElement p : pileup ) { contexts.put(readGroupId,new StratifiedAlignmentContext<RBP>(pileup.getLocation(),(RBP)pileup.getPileupForReadGroup(readGroupId)));
SAMRecord read = p.getRead();
SAMReadGroupRecord readGroup = read.getReadGroup();
if ( readGroup == null ) {
throw new StingException("Missing read group for read " + read.getReadName());
}
String group = readGroup.getReadGroupId();
StratifiedAlignmentContext myContext = contexts.get(group);
if ( myContext == null ) {
myContext = new StratifiedAlignmentContext(pileup.getLocation());
contexts.put(group,myContext);
}
myContext.add(p);
}
return contexts; return contexts;
} }
public static <PE> AlignmentContext joinContexts(Collection<StratifiedAlignmentContext> contexts, StratifiedContextType type) { public static AlignmentContext joinContexts(Collection<StratifiedAlignmentContext> contexts) {
ArrayList<PE> pe = new ArrayList<PE>();
if ( contexts.size() == 0 ) // validation
throw new StingException("BUG: joinContexts requires at least one context to join"); GenomeLoc loc = contexts.iterator().next().getLocation();
boolean isExtended = contexts.iterator().next().basePileup instanceof ReadBackedExtendedEventPileup;
for(StratifiedAlignmentContext context: contexts) {
Iterator<StratifiedAlignmentContext> it = contexts.iterator(); if(!loc.equals(context.getLocation()))
StratifiedAlignmentContext context = it.next();
boolean isExtended = context.isExtended;
GenomeLoc loc = context.getLocation();
pe.addAll(context.getPileupElements(type));
while ( it.hasNext()) {
context = it.next();
if ( ! loc.equals( context.getLocation() ) )
throw new StingException("Illegal attempt to join contexts from different genomic locations"); throw new StingException("Illegal attempt to join contexts from different genomic locations");
if ( context.isExtended != isExtended ) if(isExtended != (context.basePileup instanceof ReadBackedExtendedEventPileup))
throw new StingException("Illegal attempt to join simple and extended contexts"); throw new StingException("Illegal attempt to join simple and extended contexts");
pe.addAll(context.getPileupElements(type));
} }
// dirty trick below. generics do not allow to cast pe (ArrayList<PileupElement>) directly to ArrayList<ExtendedEventPileupElement>, AlignmentContext jointContext;
// so we first cast to "? extends" wildcard, then to what we actually need. if(isExtended) {
if ( isExtended ) return new AlignmentContext(loc, new ReadBackedExtendedEventPileupImpl(loc,(List<ExtendedEventPileupElement>)pe) ); List<ExtendedEventPileupElement> pe = new ArrayList<ExtendedEventPileupElement>();
else return new AlignmentContext(loc, new ReadBackedPileupImpl(loc,(List<PileupElement>)pe)); for(StratifiedAlignmentContext context: contexts) {
for(PileupElement pileupElement: context.basePileup)
pe.add((ExtendedEventPileupElement)pileupElement);
}
jointContext = new AlignmentContext(loc, new ReadBackedExtendedEventPileupImpl(loc,pe));
}
else {
List<PileupElement> pe = new ArrayList<PileupElement>();
for(StratifiedAlignmentContext context: contexts) {
for(PileupElement pileupElement: context.basePileup)
pe.add(pileupElement);
}
jointContext = new AlignmentContext(loc, new ReadBackedPileupImpl(loc,pe));
}
return jointContext;
} }
} }

View File

@ -359,8 +359,8 @@ public class LocusIteratorByState extends LocusIterator {
// In this case, the subsequent call to next() will emit the normal pileup at the current base // In this case, the subsequent call to next() will emit the normal pileup at the current base
// and shift the position. // and shift the position.
if (readInfo.generateExtendedEvents() && hasExtendedEvents) { if (readInfo.generateExtendedEvents() && hasExtendedEvents) {
Map<String,AbstractReadBackedPileup<ReadBackedExtendedEventPileup,ExtendedEventPileupElement>> fullExtendedEventPileup = Map<String,ReadBackedExtendedEventPileupImpl> fullExtendedEventPileup =
new HashMap<String,AbstractReadBackedPileup<ReadBackedExtendedEventPileup,ExtendedEventPileupElement>>(); new HashMap<String,ReadBackedExtendedEventPileupImpl>();
SAMRecordState our1stState = readStates.getFirst(); SAMRecordState our1stState = readStates.getFirst();
// get current location on the reference and decrement it by 1: the indels we just stepped over // get current location on the reference and decrement it by 1: the indels we just stepped over
@ -422,7 +422,7 @@ public class LocusIteratorByState extends LocusIterator {
nextAlignmentContext = new AlignmentContext(loc, new ReadBackedExtendedEventPileupImpl(loc, fullExtendedEventPileup)); nextAlignmentContext = new AlignmentContext(loc, new ReadBackedExtendedEventPileupImpl(loc, fullExtendedEventPileup));
} else { } else {
GenomeLoc location = getLocation(); GenomeLoc location = getLocation();
Map<String,AbstractReadBackedPileup<ReadBackedPileup,PileupElement>> fullPileup = new HashMap<String,AbstractReadBackedPileup<ReadBackedPileup,PileupElement>>(); Map<String,ReadBackedPileupImpl> fullPileup = new HashMap<String,ReadBackedPileupImpl>();
// todo -- performance problem -- should be lazy, really // todo -- performance problem -- should be lazy, really
for(String sampleName: sampleNames) { for(String sampleName: sampleNames) {

View File

@ -52,7 +52,7 @@ public class HaplotypeScore implements InfoFieldAnnotation, StandardAnnotation {
if ( !vc.isBiallelic() || !vc.isSNP() || stratifiedContexts.size() == 0 ) // size 0 means that call was made by someone else and we have no data here if ( !vc.isBiallelic() || !vc.isSNP() || stratifiedContexts.size() == 0 ) // size 0 means that call was made by someone else and we have no data here
return null; return null;
AlignmentContext context = StratifiedAlignmentContext.joinContexts(stratifiedContexts.values(), StratifiedAlignmentContext.StratifiedContextType.COMPLETE); AlignmentContext context = StratifiedAlignmentContext.joinContexts(stratifiedContexts.values());
int contextWingSize = Math.min(((int)ref.getWindow().size() - 1)/2, MIN_CONTEXT_WING_SIZE); int contextWingSize = Math.min(((int)ref.getWindow().size() - 1)/2, MIN_CONTEXT_WING_SIZE);
int contextSize = contextWingSize * 2 + 1; int contextSize = contextWingSize * 2 + 1;

View File

@ -200,9 +200,9 @@ public class VariantAnnotator extends RodWalker<Integer, Integer> {
Map<String, StratifiedAlignmentContext> stratifiedContexts; Map<String, StratifiedAlignmentContext> stratifiedContexts;
if ( BaseUtils.simpleBaseToBaseIndex(ref.getBase()) != -1 ) { if ( BaseUtils.simpleBaseToBaseIndex(ref.getBase()) != -1 ) {
if ( ! context.hasExtendedEventPileup() ) { if ( ! context.hasExtendedEventPileup() ) {
stratifiedContexts = StratifiedAlignmentContext.splitContextBySample(context.getBasePileup(), ASSUME_SINGLE_SAMPLE, null); stratifiedContexts = StratifiedAlignmentContext.splitContextBySample(context.getBasePileup(), ASSUME_SINGLE_SAMPLE);
} else { } else {
stratifiedContexts = StratifiedAlignmentContext.splitContextBySample(context.getExtendedEventPileup(), ASSUME_SINGLE_SAMPLE, null); stratifiedContexts = StratifiedAlignmentContext.splitContextBySample(context.getExtendedEventPileup(), ASSUME_SINGLE_SAMPLE);
} }
if ( stratifiedContexts != null ) { if ( stratifiedContexts != null ) {
annotatedVCs = engine.annotateContext(tracker, ref, stratifiedContexts, vc); annotatedVCs = engine.annotateContext(tracker, ref, stratifiedContexts, vc);

View File

@ -179,7 +179,7 @@ public class UnifiedGenotyperEngine {
return null; return null;
// stratify the AlignmentContext and cut by sample // stratify the AlignmentContext and cut by sample
Map<String, StratifiedAlignmentContext> stratifiedContexts = StratifiedAlignmentContext.splitContextBySample(pileup, UAC.ASSUME_SINGLE_SAMPLE, null); Map<String, StratifiedAlignmentContext> stratifiedContexts = StratifiedAlignmentContext.splitContextBySample(pileup, UAC.ASSUME_SINGLE_SAMPLE);
if ( stratifiedContexts == null ) if ( stratifiedContexts == null )
return null; return null;
@ -206,7 +206,7 @@ public class UnifiedGenotyperEngine {
return null; return null;
// stratify the AlignmentContext and cut by sample // stratify the AlignmentContext and cut by sample
Map<String, StratifiedAlignmentContext> stratifiedContexts = StratifiedAlignmentContext.splitContextBySample(pileup, UAC.ASSUME_SINGLE_SAMPLE, null); Map<String, StratifiedAlignmentContext> stratifiedContexts = StratifiedAlignmentContext.splitContextBySample(pileup, UAC.ASSUME_SINGLE_SAMPLE);
if ( stratifiedContexts == null ) if ( stratifiedContexts == null )
return null; return null;

View File

@ -68,7 +68,7 @@ public class AlleleBalanceHistogramWalker extends LocusWalker<Map<String,Double>
} }
private HashMap<String,Double> getAlleleBalanceBySample(VCFRecord vcf, ReferenceContext ref, AlignmentContext context) { private HashMap<String,Double> getAlleleBalanceBySample(VCFRecord vcf, ReferenceContext ref, AlignmentContext context) {
Map<String, StratifiedAlignmentContext> sampleContext = StratifiedAlignmentContext.splitContextBySample(context.getBasePileup(),null,null); Map<String, StratifiedAlignmentContext> sampleContext = StratifiedAlignmentContext.splitContextBySample(context.getBasePileup(),null);
HashMap<String,Double> balances = new HashMap<String,Double>(); HashMap<String,Double> balances = new HashMap<String,Double>();
System.out.println("----- "+ref.getLocus()+" -----"); System.out.println("----- "+ref.getLocus()+" -----");
int returnedBalances = 0; int returnedBalances = 0;

View File

@ -533,11 +533,11 @@ public class MendelianViolationClassifier extends LocusWalker<MendelianViolation
return violation; return violation;
} }
private Double getAlleleProportion(Allele a, StratifiedAlignmentContext<PileupElement> context) { private Double getAlleleProportion(Allele a, StratifiedAlignmentContext context) {
int numParental = 0; int numParental = 0;
int total = 0; int total = 0;
if ( context != null ) { if ( context != null ) {
for ( PileupElement e : context.getPileupElements(StratifiedAlignmentContext.StratifiedContextType.COMPLETE)) { for ( PileupElement e : context.getContext(StratifiedAlignmentContext.StratifiedContextType.COMPLETE).getBasePileup()) {
if ( e.getQual() >= 10 && e.getMappingQual() >= 10 ) { if ( e.getQual() >= 10 && e.getMappingQual() >= 10 ) {
total++; total++;
if ( e.getBase() == a.getBases()[0]) { if ( e.getBase() == a.getBases()[0]) {

View File

@ -39,7 +39,7 @@ import net.sf.samtools.SAMRecord;
* @author mhanna * @author mhanna
* @version 0.1 * @version 0.1
*/ */
public abstract class AbstractReadBackedPileup<RBP extends ReadBackedPileup,PE extends PileupElement> implements ReadBackedPileup { public abstract class AbstractReadBackedPileup<RBP extends AbstractReadBackedPileup<RBP,PE>,PE extends PileupElement> implements ReadBackedPileup {
protected final GenomeLoc loc; protected final GenomeLoc loc;
protected final PileupElementTracker<PE> pileupElementTracker; protected final PileupElementTracker<PE> pileupElementTracker;
@ -82,7 +82,7 @@ public abstract class AbstractReadBackedPileup<RBP extends ReadBackedPileup,PE e
* pointer to pileup. Don't go changing the data in pileup. * pointer to pileup. Don't go changing the data in pileup.
* *
*/ */
public AbstractReadBackedPileup(GenomeLoc loc, List<PE> pileup ) { public AbstractReadBackedPileup(GenomeLoc loc, List<PE> pileup) {
if ( loc == null ) throw new StingException("Illegal null genomeloc in ReadBackedPileup"); if ( loc == null ) throw new StingException("Illegal null genomeloc in ReadBackedPileup");
if ( pileup == null ) throw new StingException("Illegal null pileup in ReadBackedPileup"); if ( pileup == null ) throw new StingException("Illegal null pileup in ReadBackedPileup");
@ -115,10 +115,10 @@ public abstract class AbstractReadBackedPileup<RBP extends ReadBackedPileup,PE e
calculateCachedData(); calculateCachedData();
} }
protected AbstractReadBackedPileup(GenomeLoc loc, Map<String,AbstractReadBackedPileup<RBP,PE>> pileupsBySample) { protected AbstractReadBackedPileup(GenomeLoc loc, Map<String,? extends AbstractReadBackedPileup<RBP,PE>> pileupsBySample) {
this.loc = loc; this.loc = loc;
PerSamplePileupElementTracker<PE> tracker = new PerSamplePileupElementTracker<PE>(); PerSamplePileupElementTracker<PE> tracker = new PerSamplePileupElementTracker<PE>();
for(Map.Entry<String,AbstractReadBackedPileup<RBP,PE>> pileupEntry: pileupsBySample.entrySet()) { for(Map.Entry<String,? extends AbstractReadBackedPileup<RBP,PE>> pileupEntry: pileupsBySample.entrySet()) {
tracker.addElements(pileupEntry.getKey(),pileupEntry.getValue().pileupElementTracker); tracker.addElements(pileupEntry.getKey(),pileupEntry.getValue().pileupElementTracker);
addPileupToCumulativeStats(pileupEntry.getValue()); addPileupToCumulativeStats(pileupEntry.getValue());
} }
@ -192,7 +192,7 @@ public abstract class AbstractReadBackedPileup<RBP extends ReadBackedPileup,PE e
return pileup; return pileup;
} }
protected abstract RBP createNewPileup(GenomeLoc loc, PileupElementTracker<PE> pileupElementTracker); protected abstract AbstractReadBackedPileup<RBP,PE> createNewPileup(GenomeLoc loc, PileupElementTracker<PE> pileupElementTracker);
protected abstract PE createNewPileupElement(SAMRecord read, int offset); protected abstract PE createNewPileupElement(SAMRecord read, int offset);
// -------------------------------------------------------- // --------------------------------------------------------
@ -217,10 +217,10 @@ public abstract class AbstractReadBackedPileup<RBP extends ReadBackedPileup,PE e
for(String sampleName: tracker.getSamples()) { for(String sampleName: tracker.getSamples()) {
PileupElementTracker<PE> perSampleElements = tracker.getElements(sampleName); PileupElementTracker<PE> perSampleElements = tracker.getElements(sampleName);
AbstractReadBackedPileup<RBP,PE> pileup = (AbstractReadBackedPileup<RBP,PE>)createNewPileup(loc,perSampleElements).getPileupWithoutDeletions(); AbstractReadBackedPileup<RBP,PE> pileup = createNewPileup(loc,perSampleElements).getPileupWithoutDeletions();
filteredTracker.addElements(sampleName,pileup.pileupElementTracker); filteredTracker.addElements(sampleName,pileup.pileupElementTracker);
} }
return createNewPileup(loc,filteredTracker); return (RBP)createNewPileup(loc,filteredTracker);
} }
else { else {
@ -232,7 +232,7 @@ public abstract class AbstractReadBackedPileup<RBP extends ReadBackedPileup,PE e
filteredTracker.add(p); filteredTracker.add(p);
} }
} }
return createNewPileup(loc, filteredTracker); return (RBP)createNewPileup(loc, filteredTracker);
} }
} else { } else {
return (RBP)this; return (RBP)this;
@ -255,10 +255,10 @@ public abstract class AbstractReadBackedPileup<RBP extends ReadBackedPileup,PE e
for(String sampleName: tracker.getSamples()) { for(String sampleName: tracker.getSamples()) {
PileupElementTracker<PE> perSampleElements = tracker.getElements(sampleName); PileupElementTracker<PE> perSampleElements = tracker.getElements(sampleName);
AbstractReadBackedPileup<RBP,PE> pileup = (AbstractReadBackedPileup<RBP,PE>)createNewPileup(loc,perSampleElements).getOverlappingFragmentFilteredPileup(); AbstractReadBackedPileup<RBP,PE> pileup = createNewPileup(loc,perSampleElements).getOverlappingFragmentFilteredPileup();
filteredTracker.addElements(sampleName,pileup.pileupElementTracker); filteredTracker.addElements(sampleName,pileup.pileupElementTracker);
} }
return createNewPileup(loc,filteredTracker); return (RBP)createNewPileup(loc,filteredTracker);
} }
else { else {
Map<String,PE> filteredPileup = new HashMap<String, PE>(); Map<String,PE> filteredPileup = new HashMap<String, PE>();
@ -288,7 +288,7 @@ public abstract class AbstractReadBackedPileup<RBP extends ReadBackedPileup,PE e
for(PE filteredElement: filteredPileup.values()) for(PE filteredElement: filteredPileup.values())
filteredTracker.add(filteredElement); filteredTracker.add(filteredElement);
return createNewPileup(loc,filteredTracker); return (RBP)createNewPileup(loc,filteredTracker);
} }
} }
@ -309,10 +309,10 @@ public abstract class AbstractReadBackedPileup<RBP extends ReadBackedPileup,PE e
for(String sampleName: tracker.getSamples()) { for(String sampleName: tracker.getSamples()) {
PileupElementTracker<PE> perSampleElements = tracker.getElements(sampleName); PileupElementTracker<PE> perSampleElements = tracker.getElements(sampleName);
AbstractReadBackedPileup<RBP,PE> pileup = (AbstractReadBackedPileup<RBP,PE>)createNewPileup(loc,perSampleElements).getPileupWithoutMappingQualityZeroReads(); AbstractReadBackedPileup<RBP,PE> pileup = createNewPileup(loc,perSampleElements).getPileupWithoutMappingQualityZeroReads();
filteredTracker.addElements(sampleName,pileup.pileupElementTracker); filteredTracker.addElements(sampleName,pileup.pileupElementTracker);
} }
return createNewPileup(loc,filteredTracker); return (RBP)createNewPileup(loc,filteredTracker);
} }
else { else {
@ -324,13 +324,67 @@ public abstract class AbstractReadBackedPileup<RBP extends ReadBackedPileup,PE e
filteredTracker.add(p); filteredTracker.add(p);
} }
} }
return createNewPileup(loc, filteredTracker); return (RBP)createNewPileup(loc, filteredTracker);
} }
} else { } else {
return (RBP)this; return (RBP)this;
} }
} }
public RBP getPositiveStrandPileup() {
if(pileupElementTracker instanceof PerSamplePileupElementTracker) {
PerSamplePileupElementTracker<PE> tracker = (PerSamplePileupElementTracker<PE>)pileupElementTracker;
PerSamplePileupElementTracker<PE> filteredTracker = new PerSamplePileupElementTracker<PE>();
for(String sampleName: tracker.getSamples()) {
PileupElementTracker<PE> perSampleElements = tracker.getElements(sampleName);
AbstractReadBackedPileup<RBP,PE> pileup = createNewPileup(loc,perSampleElements).getPositiveStrandPileup();
filteredTracker.addElements(sampleName,pileup.pileupElementTracker);
}
return (RBP)createNewPileup(loc,filteredTracker);
}
else {
UnifiedPileupElementTracker<PE> tracker = (UnifiedPileupElementTracker<PE>)pileupElementTracker;
UnifiedPileupElementTracker<PE> filteredTracker = new UnifiedPileupElementTracker<PE>();
for ( PE p : tracker ) {
if ( !p.getRead().getReadNegativeStrandFlag() ) {
filteredTracker.add(p);
}
}
return (RBP)createNewPileup(loc, filteredTracker);
}
}
/**
* Gets the pileup consisting of only reads on the negative strand.
* @return A read-backed pileup consisting only of reads on the negative strand.
*/
public RBP getNegativeStrandPileup() {
if(pileupElementTracker instanceof PerSamplePileupElementTracker) {
PerSamplePileupElementTracker<PE> tracker = (PerSamplePileupElementTracker<PE>)pileupElementTracker;
PerSamplePileupElementTracker<PE> filteredTracker = new PerSamplePileupElementTracker<PE>();
for(String sampleName: tracker.getSamples()) {
PileupElementTracker<PE> perSampleElements = tracker.getElements(sampleName);
AbstractReadBackedPileup<RBP,PE> pileup = createNewPileup(loc,perSampleElements).getNegativeStrandPileup();
filteredTracker.addElements(sampleName,pileup.pileupElementTracker);
}
return (RBP)createNewPileup(loc,filteredTracker);
}
else {
UnifiedPileupElementTracker<PE> tracker = (UnifiedPileupElementTracker<PE>)pileupElementTracker;
UnifiedPileupElementTracker<PE> filteredTracker = new UnifiedPileupElementTracker<PE>();
for ( PE p : tracker ) {
if ( p.getRead().getReadNegativeStrandFlag() ) {
filteredTracker.add(p);
}
}
return (RBP)createNewPileup(loc, filteredTracker);
}
}
/** Returns subset of this pileup that contains only bases with quality >= minBaseQ, coming from /** Returns subset of this pileup that contains only bases with quality >= minBaseQ, coming from
* reads with mapping qualities >= minMapQ. This method allocates and returns a new instance of ReadBackedPileup. * reads with mapping qualities >= minMapQ. This method allocates and returns a new instance of ReadBackedPileup.
* @param minBaseQ * @param minBaseQ
@ -345,11 +399,11 @@ public abstract class AbstractReadBackedPileup<RBP extends ReadBackedPileup,PE e
for(String sampleName: tracker.getSamples()) { for(String sampleName: tracker.getSamples()) {
PileupElementTracker<PE> perSampleElements = tracker.getElements(sampleName); PileupElementTracker<PE> perSampleElements = tracker.getElements(sampleName);
AbstractReadBackedPileup<RBP,PE> pileup = (AbstractReadBackedPileup<RBP,PE>)createNewPileup(loc,perSampleElements).getBaseAndMappingFilteredPileup(minBaseQ,minMapQ); AbstractReadBackedPileup<RBP,PE> pileup = createNewPileup(loc,perSampleElements).getBaseAndMappingFilteredPileup(minBaseQ,minMapQ);
filteredTracker.addElements(sampleName,pileup.pileupElementTracker); filteredTracker.addElements(sampleName,pileup.pileupElementTracker);
} }
return createNewPileup(loc,filteredTracker); return (RBP)createNewPileup(loc,filteredTracker);
} }
else { else {
UnifiedPileupElementTracker<PE> filteredTracker = new UnifiedPileupElementTracker<PE>(); UnifiedPileupElementTracker<PE> filteredTracker = new UnifiedPileupElementTracker<PE>();
@ -360,7 +414,7 @@ public abstract class AbstractReadBackedPileup<RBP extends ReadBackedPileup,PE e
} }
} }
return createNewPileup(loc, filteredTracker); return (RBP)createNewPileup(loc, filteredTracker);
} }
} }
@ -384,6 +438,31 @@ public abstract class AbstractReadBackedPileup<RBP extends ReadBackedPileup,PE e
return getBaseAndMappingFilteredPileup(-1, minMapQ); return getBaseAndMappingFilteredPileup(-1, minMapQ);
} }
/**
* Gets a list of the read groups represented in this pileup.
* @return
*/
@Override
public Collection<String> getReadGroups() {
Set<String> readGroups = new HashSet<String>();
for(PileupElement pileupElement: this)
readGroups.add(pileupElement.getRead().getReadGroup().getReadGroupId());
return readGroups;
}
/**
* Gets the pileup for a given read group. Horrendously inefficient at this point.
* @param readGroupId Identifier for the read group.
* @return A read-backed pileup containing only the reads in the given read group.
*/
@Override
public RBP getPileupForReadGroup(String readGroupId) {
UnifiedPileupElementTracker<PE> filteredTracker = new UnifiedPileupElementTracker<PE>();
for(PileupElement pileupElement: this)
filteredTracker.add((PE)pileupElement);
return (RBP)createNewPileup(loc,filteredTracker);
}
public Collection<String> getSamples() { public Collection<String> getSamples() {
if(pileupElementTracker instanceof PerSamplePileupElementTracker) { if(pileupElementTracker instanceof PerSamplePileupElementTracker) {
PerSamplePileupElementTracker<PE> tracker = (PerSamplePileupElementTracker<PE>)pileupElementTracker; PerSamplePileupElementTracker<PE> tracker = (PerSamplePileupElementTracker<PE>)pileupElementTracker;
@ -435,14 +514,14 @@ public abstract class AbstractReadBackedPileup<RBP extends ReadBackedPileup,PE e
} }
if(!filteredPileup.isEmpty()) { if(!filteredPileup.isEmpty()) {
AbstractReadBackedPileup<RBP,PE> pileup = (AbstractReadBackedPileup<RBP,PE>)createNewPileup(loc,perSampleElements); AbstractReadBackedPileup<RBP,PE> pileup = createNewPileup(loc,perSampleElements);
filteredTracker.addElements(sampleName,pileup.pileupElementTracker); filteredTracker.addElements(sampleName,pileup.pileupElementTracker);
} }
current++; current++;
} }
return createNewPileup(loc,filteredTracker); return (RBP)createNewPileup(loc,filteredTracker);
} }
else { else {
UnifiedPileupElementTracker<PE> tracker = (UnifiedPileupElementTracker<PE>)pileupElementTracker; UnifiedPileupElementTracker<PE> tracker = (UnifiedPileupElementTracker<PE>)pileupElementTracker;
@ -455,7 +534,7 @@ public abstract class AbstractReadBackedPileup<RBP extends ReadBackedPileup,PE e
filteredTracker.add(tracker.get(nextReadToKeep)); filteredTracker.add(tracker.get(nextReadToKeep));
} }
return createNewPileup(getLocation(), filteredTracker); return (RBP)createNewPileup(getLocation(), filteredTracker);
} }
} }
@ -463,7 +542,7 @@ public abstract class AbstractReadBackedPileup<RBP extends ReadBackedPileup,PE e
public RBP getPileupForSample(String sampleName) { public RBP getPileupForSample(String sampleName) {
if(pileupElementTracker instanceof PerSamplePileupElementTracker) { if(pileupElementTracker instanceof PerSamplePileupElementTracker) {
PerSamplePileupElementTracker<PE> tracker = (PerSamplePileupElementTracker<PE>)pileupElementTracker; PerSamplePileupElementTracker<PE> tracker = (PerSamplePileupElementTracker<PE>)pileupElementTracker;
return createNewPileup(loc,tracker.getElements(sampleName)); return (RBP)createNewPileup(loc,tracker.getElements(sampleName));
} }
else { else {
UnifiedPileupElementTracker<PE> filteredTracker = new UnifiedPileupElementTracker<PE>(); UnifiedPileupElementTracker<PE> filteredTracker = new UnifiedPileupElementTracker<PE>();
@ -478,7 +557,7 @@ public abstract class AbstractReadBackedPileup<RBP extends ReadBackedPileup,PE e
filteredTracker.add(p); filteredTracker.add(p);
} }
} }
return filteredTracker.size()>0 ? createNewPileup(loc,filteredTracker) : null; return filteredTracker.size()>0 ? (RBP)createNewPileup(loc,filteredTracker) : null;
} }
} }

View File

@ -68,6 +68,19 @@ public interface ReadBackedExtendedEventPileup extends ReadBackedPileup {
*/ */
public ReadBackedExtendedEventPileup getPileupWithoutMappingQualityZeroReads(); public ReadBackedExtendedEventPileup getPileupWithoutMappingQualityZeroReads();
/**
* Gets the pileup consisting of only reads on the positive strand.
* @return A read-backed pileup consisting only of reads on the positive strand.
*/
public ReadBackedExtendedEventPileup getPositiveStrandPileup();
/**
* Gets the pileup consisting of only reads on the negative strand.
* @return A read-backed pileup consisting only of reads on the negative strand.
*/
public ReadBackedExtendedEventPileup getNegativeStrandPileup();
/** Returns subset of this pileup that contains only bases with quality >= minBaseQ, coming from /** Returns subset of this pileup that contains only bases with quality >= minBaseQ, coming from
* reads with mapping qualities >= minMapQ. This method allocates and returns a new instance of ReadBackedPileup. * reads with mapping qualities >= minMapQ. This method allocates and returns a new instance of ReadBackedPileup.
* @param minBaseQ * @param minBaseQ

View File

@ -31,7 +31,7 @@ import java.util.*;
import net.sf.samtools.SAMRecord; import net.sf.samtools.SAMRecord;
public class ReadBackedExtendedEventPileupImpl extends AbstractReadBackedPileup<ReadBackedExtendedEventPileup, ExtendedEventPileupElement> implements ReadBackedExtendedEventPileup { public class ReadBackedExtendedEventPileupImpl extends AbstractReadBackedPileup<ReadBackedExtendedEventPileupImpl,ExtendedEventPileupElement> implements ReadBackedExtendedEventPileup {
private int nInsertions; private int nInsertions;
private int maxDeletionLength; // cached value of the length of the longest deletion observed at the site private int maxDeletionLength; // cached value of the length of the longest deletion observed at the site
/** /**
@ -59,7 +59,7 @@ public class ReadBackedExtendedEventPileupImpl extends AbstractReadBackedPileup<
this.nInsertions = nInsertions; this.nInsertions = nInsertions;
} }
public ReadBackedExtendedEventPileupImpl(GenomeLoc loc, Map<String,AbstractReadBackedPileup<ReadBackedExtendedEventPileup,ExtendedEventPileupElement>> pileupElementsBySample) { public ReadBackedExtendedEventPileupImpl(GenomeLoc loc, Map<String,? extends ReadBackedExtendedEventPileupImpl> pileupElementsBySample) {
super(loc,pileupElementsBySample); super(loc,pileupElementsBySample);
} }
@ -86,7 +86,7 @@ public class ReadBackedExtendedEventPileupImpl extends AbstractReadBackedPileup<
} }
@Override @Override
protected void addPileupToCumulativeStats(AbstractReadBackedPileup<ReadBackedExtendedEventPileup,ExtendedEventPileupElement> pileup) { protected void addPileupToCumulativeStats(AbstractReadBackedPileup<ReadBackedExtendedEventPileupImpl,ExtendedEventPileupElement> pileup) {
super.addPileupToCumulativeStats(pileup); super.addPileupToCumulativeStats(pileup);
ReadBackedExtendedEventPileup extendedEventPileup = ((ReadBackedExtendedEventPileup)pileup); ReadBackedExtendedEventPileup extendedEventPileup = ((ReadBackedExtendedEventPileup)pileup);
this.nInsertions += extendedEventPileup.getNumberOfInsertions(); this.nInsertions += extendedEventPileup.getNumberOfInsertions();
@ -94,7 +94,7 @@ public class ReadBackedExtendedEventPileupImpl extends AbstractReadBackedPileup<
} }
@Override @Override
protected ReadBackedExtendedEventPileup createNewPileup(GenomeLoc loc, PileupElementTracker<ExtendedEventPileupElement> tracker) { protected ReadBackedExtendedEventPileupImpl createNewPileup(GenomeLoc loc, PileupElementTracker<ExtendedEventPileupElement> tracker) {
return new ReadBackedExtendedEventPileupImpl(loc,tracker); return new ReadBackedExtendedEventPileupImpl(loc,tracker);
} }

View File

@ -66,6 +66,18 @@ public interface ReadBackedPileup extends Iterable<PileupElement> {
*/ */
public ReadBackedPileup getPileupWithoutMappingQualityZeroReads(); public ReadBackedPileup getPileupWithoutMappingQualityZeroReads();
/**
* Gets the pileup consisting of only reads on the positive strand.
* @return A read-backed pileup consisting only of reads on the positive strand.
*/
public ReadBackedPileup getPositiveStrandPileup();
/**
* Gets the pileup consisting of only reads on the negative strand.
* @return A read-backed pileup consisting only of reads on the negative strand.
*/
public ReadBackedPileup getNegativeStrandPileup();
/** Returns subset of this pileup that contains only bases with quality >= minBaseQ, coming from /** Returns subset of this pileup that contains only bases with quality >= minBaseQ, coming from
* reads with mapping qualities >= minMapQ. This method allocates and returns a new instance of ReadBackedPileup. * reads with mapping qualities >= minMapQ. This method allocates and returns a new instance of ReadBackedPileup.
* @param minBaseQ * @param minBaseQ
@ -102,6 +114,19 @@ public interface ReadBackedPileup extends Iterable<PileupElement> {
*/ */
public boolean hasPileupBeenDownsampled(); public boolean hasPileupBeenDownsampled();
/**
* Gets a collection of all the read groups represented in this pileup.
* @return A collection of all the read group ids represented in this pileup.
*/
public Collection<String> getReadGroups();
/**
* Gets all the reads associated with a given read group.
* @param readGroupId Identifier for the read group.
* @return A pileup containing only the reads in the given read group.
*/
public ReadBackedPileup getPileupForReadGroup(String readGroupId);
/** /**
* Gets a collection of all the samples stored in this pileup. * Gets a collection of all the samples stored in this pileup.
* @return Collection of samples in this pileup. * @return Collection of samples in this pileup.

View File

@ -29,7 +29,7 @@ import net.sf.samtools.SAMRecord;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
public class ReadBackedPileupImpl extends AbstractReadBackedPileup<ReadBackedPileup,PileupElement> implements ReadBackedPileup { public class ReadBackedPileupImpl extends AbstractReadBackedPileup<ReadBackedPileupImpl,PileupElement> implements ReadBackedPileup {
public ReadBackedPileupImpl(GenomeLoc loc) { public ReadBackedPileupImpl(GenomeLoc loc) {
super(loc); super(loc);
@ -47,7 +47,7 @@ public class ReadBackedPileupImpl extends AbstractReadBackedPileup<ReadBackedPil
super(loc,pileupElements); super(loc,pileupElements);
} }
public ReadBackedPileupImpl(GenomeLoc loc, Map<String,AbstractReadBackedPileup<ReadBackedPileup,PileupElement>> pileupElementsBySample) { public ReadBackedPileupImpl(GenomeLoc loc, Map<String,ReadBackedPileupImpl> pileupElementsBySample) {
super(loc,pileupElementsBySample); super(loc,pileupElementsBySample);
} }
@ -65,7 +65,7 @@ public class ReadBackedPileupImpl extends AbstractReadBackedPileup<ReadBackedPil
} }
@Override @Override
protected ReadBackedPileup createNewPileup(GenomeLoc loc, PileupElementTracker<PileupElement> tracker) { protected ReadBackedPileupImpl createNewPileup(GenomeLoc loc, PileupElementTracker<PileupElement> tracker) {
return new ReadBackedPileupImpl(loc,tracker); return new ReadBackedPileupImpl(loc,tracker);
} }