package org.seqcode.viz.metaprofile; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import org.seqcode.genome.Genome; import org.seqcode.genome.location.Point; import org.seqcode.genome.location.Region; import org.seqcode.genome.location.StrandedPoint; /** * EventProfiler profiles the occurrence of point events around a set of reference points. * * @author mahony * */ public class EventProfiler implements PointProfiler<Point, Profile>{ private Genome gen; private BinningParameters params=null; private Map<String, List<Point>> events; //events indexed by chromosome and then sorted public EventProfiler(BinningParameters bp, Genome g, List<Point> elist){ gen=g; params=bp; events = new HashMap<String, List<Point>>(); for(Point e : elist){ String currChr = e.getChrom(); if(!events.containsKey(currChr)){ events.put(currChr, new ArrayList<Point>()); } events.get(currChr).add(e); } for(String c : events.keySet()) Collections.sort(events.get(c)); } public BinningParameters getBinningParameters() { return params; } /** * execute: generate a PointProfile based on a new Point */ public Profile execute(Point a) { double[] array = new double[params.getNumBins()]; for(int i = 0; i < array.length; i++) { array[i] = 0; } int window = params.getWindowSize(); int left = window/2; int right = window-left-1; //Initialize the query region int start = Math.max(1, a.getLocation()-left); int end = Math.min(a.getLocation()+right, a.getGenome().getChromLength(a.getChrom())); Region query = new Region(gen, a.getChrom(), start, end); boolean strand = (a instanceof StrandedPoint) ? ((StrandedPoint)a).getStrand() == '+' : true; //Find the candidate events using a binary search List<Point> candidates = new ArrayList<Point>(); if(events.containsKey(a.getChrom())){ List<Point> chrEvents = events.get(a.getChrom()); for(int i=0; i<chrEvents.size(); i++){ Point p = chrEvents.get(i); if(query.contains(p)) candidates.add(p); else if(p.getLocation()>query.getEnd()) break; } } //Make the new PointProfile for(int i=query.getStart(); i<query.getEnd(); i+=params.getBinSize()){ Region curr = new Region(query.getGenome(), query.getChrom(), i, i+params.getBinSize()); for(Point p : candidates){ if(curr.contains(p)){ int offset = p.getLocation()-query.getStart(); if(!strand) { int tmp = window-offset; offset = tmp; } int bin = params.findBin(offset); array[bin]++; } } } return new PointProfile(a, params, array, (a instanceof StrandedPoint)); } public void cleanup() {} }