/* * The MIT License (MIT) * * Copyright (c) 2007-2015 Broad Institute * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ package org.broad.igv.methyl; import org.broad.igv.Globals; import org.broad.igv.bbfile.BBFileReader; import org.broad.igv.feature.genome.Genome; import org.broad.igv.renderer.DataRange; import org.broad.igv.renderer.GraphicUtils; import org.broad.igv.renderer.PointsRenderer; import org.broad.igv.renderer.Renderer; import org.broad.igv.track.AbstractTrack; import org.broad.igv.track.RenderContext; import org.broad.igv.ui.panel.ReferenceFrame; import org.broad.igv.util.LongRunningTask; import org.broad.igv.util.ResourceLocator; import java.awt.*; import java.io.IOException; import java.util.ArrayList; import java.util.Collections; import java.util.Iterator; import java.util.List; /** * Experimental class for specific dataset. * <p/> * if(locator.getPath().contains("RRBS_cpgMethylation") || locator.getPath().contains("")) { * * @author Jim Robinson * @date 4/19/12 */ public class MethylTrack extends AbstractTrack { public static final int FIVE_MB = 5000000; public static final int FIFTY_MB = 50000000; private MethylDataSource dataSource; private Range loadedRange; private Renderer renderer; private int resolutionThreshold; private boolean loading = false; public MethylTrack(ResourceLocator dataResourceLocator, BBFileReader reader, Genome genome) throws IOException { super(dataResourceLocator); setHeight(60); renderer = new PointsRenderer(); boolean isWGBS; if (reader.getAutoSql() != null && reader.getAutoSql().startsWith("table BisulfiteSeq")) { resolutionThreshold = FIVE_MB / 1000; dataSource = new CachingMethylSource(new BBMethylDataSource(reader, BBMethylDataSource.Type.USC, genome), resolutionThreshold); //dataSource = new BBMethylDataSource(reader, BBMethylDataSource.Type.USC, genome); } else { isWGBS = dataResourceLocator.getPath().contains("BiSeq_cpgMethylation"); resolutionThreshold = (isWGBS ? FIVE_MB : FIFTY_MB) / 1000; dataSource = new CachingMethylSource(new BBMethylDataSource(reader, BBMethylDataSource.Type.ZILLER, genome), resolutionThreshold); //dataSource = new BBMethylDataSource(reader, BBMethylDataSource.Type.USC, genome); } loadedRange = new Range("", -1, -1, Collections.<MethylScore>emptyList()); setDataRange(new DataRange(0, 100)); } @Override public boolean isReadyToPaint(ReferenceFrame frame) { if (frame.getChrName().equals(Globals.CHR_ALL) || frame.getScale() > resolutionThreshold) { return true; } else { String chr = frame.getChrName(); int start = (int) frame.getOrigin(); int end = (int) frame.getEnd(); return loadedRange.contains(chr, start, end); } } @Override public void load(ReferenceFrame frame) { String chr = frame.getChrName(); int start = (int) frame.getOrigin(); int end = (int) frame.getEnd(); int width = (end - start) / 2; int expandedStart = Math.max(0, start - width); int expandedEnd = end + width; List<MethylScore> scores = new ArrayList<MethylScore>(1000); Iterator<MethylScore> iter = dataSource.query(chr, expandedStart, expandedEnd); while (iter.hasNext()) { scores.add(iter.next()); } loadedRange = new Range(chr, expandedStart, expandedEnd, scores); } /** * Render the track in the supplied rectangle. It is the responsibility of the track to draw within the * bounds of the rectangle. * * @param context the render context * @param rect the track bounds, relative to the enclosing DataPanel bounds. */ public void render(final RenderContext context, final Rectangle rect) { if (context.getChr().equals(Globals.CHR_ALL) || context.getScale() > resolutionThreshold) { Graphics2D g = context.getGraphic2DForColor(Color.gray); Rectangle textRect = new Rectangle(rect); // Keep text near the top of the track rectangle textRect.height = Math.min(rect.height, 20); textRect.height = Math.min(rect.height, 20); String message = context.getChr().equals(Globals.CHR_ALL) ? "Zoom in to see features." : "Zoom in to see features, or right-click to increase Feature Visibility Window."; GraphicUtils.drawCenteredText(message, textRect, g); return; } final String chr = context.getChr(); final int start = (int) context.getOrigin(); final int end = (int) context.getEndLocation(); if (loadedRange.contains(chr, start, end)) { renderer.render(loadedRange.scores, context, rect, this); } } public Renderer getRenderer() { return renderer; } static class Range extends org.broad.igv.feature.Range { List<MethylScore> scores; Range(String chr, int start, int end, List<MethylScore> scores) { super(chr, start, end); this.scores = scores; } } }