/* * Copyright (c) 2009 The Jackson Laboratory * * This software was developed by Gary Churchill's Lab at The Jackson * Laboratory (see http://research.jax.org/faculty/churchill). * * This is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software. If not, see <http://www.gnu.org/licenses/>. */ package org.jax.qtl.graph; import java.awt.font.FontRenderContext; import java.awt.geom.Rectangle2D; import java.util.List; import org.jax.qtl.cross.Cross; import org.jax.qtl.cross.CrossChromosome; import org.jax.qtl.cross.GeneticMap; import org.jax.qtl.cross.GeneticMarker; import org.jax.qtl.cross.SexAwareGeneticMap; /** * <p>Title: QTL data analysis</p> * * <p>Description: </p> * * <p>Company: The Jackson Laboratory</p> * * @author Lei Wu * @version 1.0 */ public class CompareGeneticMapPlot extends GeneticMapPlot { /** * every {@link java.io.Serializable} is supposed to have one of these */ private static final long serialVersionUID = -630110935598985219L; private final List<SexAwareGeneticMap> estimatedGeneticMaps; /** * Constructor * @param cross * the cross to plot the map for * @param estimatedGeneticMaps * the maps to plot */ public CompareGeneticMapPlot( Cross cross, List<SexAwareGeneticMap> estimatedGeneticMaps) { super(cross); this.estimatedGeneticMaps = estimatedGeneticMaps; for(SexAwareGeneticMap currSexAwareMap: estimatedGeneticMaps) { GeneticMap currMap = currSexAwareMap.getAnyGeneticMap(); for(GeneticMarker currMarker: currMap.getMarkerPositions()) { double currPosition = currMarker.getMarkerPositionCentimorgans(); if(currPosition > this.maxPos) { this.maxPos = currPosition; } } } setTitle("Comparison of Genetic Maps for " + cross.toString()); } @Override void plot() { int leftConerX = this.inset.left + this.plotInset.left; int leftConerY = this.inset.top + this.plotInset.top; int width = this.plotWidth - (this.plotInset.left + this.plotInset.right); int height = this.plotHeight - (this.plotInset.top + this.plotInset.bottom); double yscaler = height / this.maxPos; // draw ticks and labels on y axis for (int i = 0; i < this.maxPos; i += 20) { drawYtickAndLabel(yscaler, i, 0); } for (int i = 0; i < this.numChr; i++) { CrossChromosome chr = this.cross.getGenotypeData().get(i); List<GeneticMarker> originalMarkers = chr.getAnyGeneticMap().getMarkerPositions(); List<GeneticMarker> estimatedMarkers = this.estimatedGeneticMaps.get(i).getAnyGeneticMap().getMarkerPositions(); int numMarkers = originalMarkers.size(); double x = leftConerX + (i + 1) * width * 1.0 / (this.numChr + 1); double firstMarkerPos = originalMarkers.get(0).getMarkerPositionCentimorgans(); double lastMarkerPos = originalMarkers.get(numMarkers - 1).getMarkerPositionCentimorgans(); double firstEstMarkerPos = estimatedMarkers.get(0).getMarkerPositionCentimorgans(); double lastEstMarkerPos = estimatedMarkers.get(numMarkers -1).getMarkerPositionCentimorgans(); double adjustment = 0; if (!this.startFromZero) { adjustment = Math.min(firstMarkerPos, firstEstMarkerPos); } double y1 = leftConerY + height - (firstMarkerPos - adjustment) * yscaler; double y2 = leftConerY + height - (lastMarkerPos - adjustment) * yscaler; double y1Est = leftConerY + height - (firstEstMarkerPos - adjustment) * yscaler; double y2Est = leftConerY + height - (lastEstMarkerPos - adjustment) * yscaler; // draw horizontal lines for each marker for (int j = 0; j < numMarkers; j++) { GeneticMarker currOriginalMarker = originalMarkers.get(j); GeneticMarker currEstimatedMarker = estimatedMarkers.get(j); double y = leftConerY + height - (currOriginalMarker.getMarkerPositionCentimorgans() - adjustment) * yscaler; double yEst = leftConerY + height - (currEstimatedMarker.getMarkerPositionCentimorgans() - adjustment) * yscaler; // TODO add back interaction // if (currentMarker.getMap().isSelected()) // big.setColor(highlightColor); // else this.big.setColor(this.normalColor); this.big.drawLine( (int) (x - this.markerLength / 2), (int) y, (int) (x + this.markerLength / 2), (int) yEst); } // draw vertical lines (old on left, new on right) for each chromosome this.big.setColor(this.normalColor); this.big.drawLine( (int)(x - this.markerLength/2), (int) y1, (int)(x - this.markerLength/2), (int) y2); this.big.drawLine( (int)(x + this.markerLength/2), (int) y1Est, (int)(x + this.markerLength/2), (int) y2Est); // draw ticks and label on x axis int baseY = this.inset.top + this.plotHeight; this.big.setColor(this.lineColor); this.big.setStroke(this.normalLinetype); this.big.drawLine( (int) x, baseY, (int) x, baseY - this.tickHeight); String label = chr.getChromosomeName(); FontRenderContext context = this.big.getFontRenderContext(); Rectangle2D labelBounds = this.tickLabelFont.getStringBounds(label, context); int labelWidth = (int) labelBounds.getWidth(); int labelHeight = (int) labelBounds.getHeight(); int labelStartX = this.inset.left + this.plotInset.left + (int) (width * 1.0 / (this.numChr + 1) * (i + 1) - labelWidth / 2); int labelStartY = getHeight() - this.inset.bottom + labelHeight; this.big.setFont(this.tickLabelFont); this.big.drawString(label, labelStartX, labelStartY); } } }