package org.seqcode.projects.seqview.paintable; import java.awt.*; import java.util.*; import org.seqcode.genome.location.Region; import org.seqcode.gseutils.*; import org.seqcode.projects.seqview.model.RegionMapperModel; public class PerBaseScorePainter<X extends Number> extends RegionPaintable { private RegionMapperModel<X[]> model; private PerBaseScoreProperties props; /* the assumption is that maxscore > 0 and minscore < 0 */ public PerBaseScorePainter(RegionMapperModel<X[]> model, double minscore, double maxscore) { this.model = model; props = new PerBaseScoreProperties(); props.MaxScore = maxscore; props.MinScore = minscore; props.MiddleScore = 0.9; model.addEventListener(this); } public PerBaseScorePainter(RegionMapperModel<X[]> model, double minscore, double middlescore, double maxscore) { this.model = model; props = new PerBaseScoreProperties(); props.MaxScore = maxscore; props.MinScore = minscore; props.MiddleScore = middlescore; model.addEventListener(this); } public PerBaseScoreProperties getProperties () {return props;} public void cleanup() { super.cleanup(); model.removeEventListener(this); } public void removeEventListener(Listener<EventObject> l) { super.removeEventListener(l); if (!hasListeners()) { model.removeEventListener(this); } } public synchronized void eventRegistered(EventObject e) { if (e.getSource() == model && model.isReady()) { setCanPaint(true); setWantsPaint(true); notifyListeners(); } } public int getMaxVertSpace() { return 40; } public int getMinVertSpace() { return 40; } public void paintItem(Graphics2D g, int x1, int y1, int x2, int y2) { g.setColor(Color.WHITE); g.fillRect(x1,y1,x2-x1,y2-y1); if (!canPaint()) { return; } boolean usemax = props.UseMax; int w = x2 - x1; double h = y2 - y1; Region region = getRegion(); int regionstart = region.getStart(), regionend = region.getEnd(); int regionwidth = regionend - regionstart; int pixwidth = props.PixWidth; if (pixwidth < 1) { pixwidth = 1; } X[] vals = model.getResults(); for (int i = x1; i < x2; i += pixwidth) { int rstart = (int)Math.round((i - x1) * regionwidth / ((double)w)); int rend = (int)Math.round((i - x1 + pixwidth) * regionwidth / ((double)w)); if (rstart < 0) { rstart = 0;} if (rend >= vals.length) {rend = vals.length - 1;} double sum = 0; if (usemax) { sum = Double.NEGATIVE_INFINITY; for (int j = rstart; j <= rend ; j++) { sum = Math.max(vals[j].doubleValue(),sum); } } else { for (int j = rstart; j <= rend ; j++) { sum += vals[j].doubleValue(); } sum /= rend - rstart + 1; } if (sum > props.MaxScore) { sum = props.MaxScore; } else if (sum < props.MinScore) { sum = props.MinScore; } if (sum > props.MiddleScore) { g.setColor(Color.BLACK); sum = (sum - props.MiddleScore) / (props.MaxScore - props.MiddleScore); } else { g.setColor(Color.RED); sum = (props.MiddleScore - sum) / (props.MiddleScore - props.MinScore); } int fill = (int) (sum * h); g.fillRect(i,y1,pixwidth,fill); } if (props.DrawTrackLabel) { g.setColor(Color.BLUE); g.drawString(getLabel(),x1,y2); } } }