package org.seqcode.viz.metaprofile; import java.util.*; import org.seqcode.data.seqdata.*; import org.seqcode.deepseq.StrandedBaseCount; import org.seqcode.deepseq.experiments.ControlledExperiment; import org.seqcode.deepseq.experiments.ExperimentManager; import org.seqcode.genome.Genome; import org.seqcode.genome.GenomeConfig; import org.seqcode.genome.location.Point; import org.seqcode.genome.location.Region; import org.seqcode.genome.location.StrandedPoint; import org.seqcode.genome.sequence.SequenceGenerator; import org.seqcode.genome.sequence.SequenceUtils; /** * Stranded5PrimeProfiler profiles the occurrence of sequencing reads around points * * @author: tdanford * Date: Aug 19, 2008 */ public class Stranded5PrimeProfiler implements PointProfiler<Point,PointProfile> { private Genome genome; private ExperimentManager manager=null; private BinningParameters params; private char strand; private char base='.'; //Only plot tags that have this base at baseRelPosition private int baseRelPosition=0; //Only plot tags that have this base at baseRelPosition private SequenceGenerator seqgen=null; private int fivePrimeShift = 0; public Stranded5PrimeProfiler(GenomeConfig genConfig, BinningParameters ps, ExperimentManager man, char strand, int fivePrimeShift, char base, int baseRelPosition) { genome = genConfig.getGenome(); manager = man; params = ps; this.strand = strand; this.base = base; this.baseRelPosition = baseRelPosition; this.fivePrimeShift=fivePrimeShift; if(base != '.'){ seqgen = genConfig.getSequenceGenerator(); } } public BinningParameters getBinningParameters() { return params; } public PointProfile execute(Point a) { int window = params.getWindowSize(); int upstream = window/2; int downstream = window-upstream-1; char pointStrand = '+'; if(a instanceof StrandedPoint) pointStrand = ((StrandedPoint)a).getStrand(); boolean wantPosStrandReads = this.strand=='+'; if(pointStrand == '-') wantPosStrandReads = !wantPosStrandReads; char wantedStrand = wantPosStrandReads?'+':'-'; int start = pointStrand == '+' ? Math.max(1, a.getLocation()-upstream) : Math.max(1, a.getLocation()-downstream); int end = pointStrand == '+' ? Math.min(a.getLocation()+downstream, a.getGenome().getChromLength(a.getChrom())) : Math.min(a.getLocation()+upstream, a.getGenome().getChromLength(a.getChrom())); Region query = new Region(a.getGenome(), a.getChrom(), start, end); int ext = 200; Region extQuery = new Region(a.getGenome(), a.getChrom(), start-ext>0 ? start-ext : 1, end+ext < a.getGenome().getChromLength(a.getChrom()) ? end+ext : a.getGenome().getChromLength(a.getChrom()) ); //Get sequence if required char [] seq=null; if(seqgen!=null) seq = seqgen.execute(extQuery).toCharArray(); //Populate the tag density double[] array = new double[params.getNumBins()]; for(int i = 0; i < array.length; i++) { array[i] = 0; } for(ControlledExperiment expt : manager.getReplicates()){ List<StrandedBaseCount> sbcs = expt.getSignal().getBases(extQuery); for(StrandedBaseCount sbc : sbcs){ if(base=='.' || (seq!=null && getBaseAtPosition(sbc, baseRelPosition, extQuery, seq)==base)){ SeqHit hit = new SeqHit(genome, a.getChrom(), sbc); if (this.strand=='.' || hit.getStrand()==wantedStrand){ //only count one strand if (start<=hit.getFivePrime() && end>=hit.getFivePrime()){ int hitPos = hit.getStrand()=='+' ? hit.getFivePrime()+fivePrimeShift : hit.getFivePrime()-fivePrimeShift; int hit5Prime = hitPos-start; if(pointStrand=='-') hit5Prime = end-hitPos; array[params.findBin(hit5Prime)]+=hit.getWeight(); } } } } } return new PointProfile(a, params, array, (a instanceof StrandedPoint)); } private char getBaseAtPosition(StrandedBaseCount a, int position, Region queryReg, char[] seq){ char b = '.'; int wantedPos = a.getStrand()=='+' ? a.getCoordinate()+position : a.getCoordinate()-position; if(wantedPos>=queryReg.getStart() && wantedPos<queryReg.getEnd()){ b = a.getStrand()=='+' ? seq[wantedPos-queryReg.getStart()] : SequenceUtils.complementChar(seq[wantedPos-queryReg.getStart()]); } return b; } public void cleanup(){ } }