3 // FORESTER -- software libraries and applications
4 // for evolutionary biology research and applications.
6 // Copyright (C) 2008-2009 Christian M. Zmasek
7 // Copyright (C) 2008-2009 Burnham Institute for Medical Research
10 // This library is free software; you can redistribute it and/or
11 // modify it under the terms of the GNU Lesser General Public
12 // License as published by the Free Software Foundation; either
13 // version 2.1 of the License, or (at your option) any later version.
15 // This library is distributed in the hope that it will be useful,
16 // but WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 // Lesser General Public License for more details.
20 // You should have received a copy of the GNU Lesser General Public
21 // License along with this library; if not, write to the Free Software
22 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
24 // Contact: phylosoft @ gmail . com
25 // WWW: https://sites.google.com/site/cmzmasek/home/software/forester
27 package org.forester.archaeopteryx.phylogeny.data;
29 import java.awt.BasicStroke;
30 import java.awt.Color;
31 import java.awt.Dimension;
32 import java.awt.Graphics2D;
33 import java.awt.Stroke;
34 import java.awt.geom.Rectangle2D;
35 import java.io.IOException;
36 import java.io.Writer;
37 import java.math.BigDecimal;
39 import java.util.SortedMap;
41 import org.forester.archaeopteryx.AptxConstants;
42 import org.forester.archaeopteryx.AptxUtil;
43 import org.forester.archaeopteryx.TreePanel;
44 import org.forester.phylogeny.data.DomainArchitecture;
45 import org.forester.phylogeny.data.PhylogenyData;
46 import org.forester.phylogeny.data.ProteinDomain;
47 import org.forester.util.ForesterUtil;
49 public final class RenderableDomainArchitecture extends DomainArchitecture implements RenderablePhylogenyData {
51 final static private String SPECIAL_DOMAIN = "RRMa";
52 final static private int BRIGHTEN_COLOR_BY = 200;
53 final static private int E_VALUE_THRESHOLD_EXP_DEFAULT = 0;
54 final static private BasicStroke STROKE_1 = new BasicStroke( 1f );
55 private static Map<String, Color> _domain_colors;
56 private final DomainArchitecture _domain_structure;
57 private int _e_value_threshold_exp = E_VALUE_THRESHOLD_EXP_DEFAULT;
58 private final Rectangle2D _rectangle = new Rectangle2D.Float();
59 private float _rendering_factor_width = 1;
60 private float _rendering_height = 0;
61 private String _node_name;
63 public RenderableDomainArchitecture( final DomainArchitecture domain_structure ) {
64 _domain_structure = domain_structure;
67 public RenderableDomainArchitecture( final DomainArchitecture domain_structure, final String node_name ) {
68 _domain_structure = domain_structure;
69 _node_name = node_name;
72 public static void setColorMap( final Map<String, Color> domain_colors ) {
73 _domain_colors = domain_colors;
77 public StringBuffer asSimpleText() {
78 return _domain_structure.asSimpleText();
82 public StringBuffer asText() {
83 return _domain_structure.asText();
87 public PhylogenyData copy() {
88 return _domain_structure.copy();
91 private final void drawDomain( final double x,
97 final boolean to_pdf ) {
98 final double h2 = heigth / 2.0;
99 final Color color_one = getColorOne( name );
100 final Color color_two = getColorTwo( color_one );
105 for( double i = 0; i < heigth; i += step ) {
106 g.setColor( org.forester.util.ForesterUtil
107 .calcColor( i >= h2 ? heigth - i : i, 0, h2, color_one, color_two ) );
108 _rectangle.setFrame( x, i + y, width, step );
109 g.fill( _rectangle );
113 private final void drawDomainGrey( final double x,
119 final boolean to_pdf ) {
120 final double h2 = heigth / 2.0;
121 final Color color_one = Color.GRAY;
122 final Color color_two = getColorTwo( color_one );
127 for( double i = 0; i < heigth; i += step ) {
128 g.setColor( org.forester.util.ForesterUtil
129 .calcColor( i >= h2 ? heigth - i : i, 0, h2, color_one, color_two ) );
130 _rectangle.setFrame( x, i + y, width, step );
131 g.fill( _rectangle );
135 private final Color getColorOne( final String name ) {
136 Color c = _domain_colors.get( name );
138 c = AptxUtil.calculateColorFromString( name, false );
140 throw new IllegalStateException();
142 _domain_colors.put( name, c );
147 private Color getColorTwo( final Color color_one ) {
148 final int red = color_one.getRed() + RenderableDomainArchitecture.BRIGHTEN_COLOR_BY;
149 final int green = color_one.getGreen() + RenderableDomainArchitecture.BRIGHTEN_COLOR_BY;
150 final int blue = color_one.getBlue() + RenderableDomainArchitecture.BRIGHTEN_COLOR_BY;
151 return new Color( red > 255 ? 255 : red, green > 255 ? 255 : green, blue > 255 ? 255 : blue );
155 public ProteinDomain getDomain( final int i ) {
156 return _domain_structure.getDomain( i );
160 public SortedMap<BigDecimal, ProteinDomain> getDomains() {
161 return _domain_structure.getDomains();
165 public int getNumberOfDomains() {
166 return _domain_structure.getNumberOfDomains();
170 public Dimension getOriginalSize() {
171 return new Dimension( _domain_structure.getTotalLength(), ForesterUtil.roundToInt( _rendering_height ) );
175 public Object getParameter() {
176 return new Integer( _e_value_threshold_exp );
179 public float getRenderingFactorWidth() {
180 return _rendering_factor_width;
184 public Dimension getRenderingSize() {
185 return new Dimension( ForesterUtil.roundToInt( _domain_structure.getTotalLength() * getRenderingFactorWidth() ),
186 ForesterUtil.roundToInt( _rendering_height ) );
190 public int getTotalLength() {
191 return _domain_structure.getTotalLength();
195 public boolean isEqual( final PhylogenyData data ) {
196 return _domain_structure.isEqual( data );
200 public void render( final float x1,
203 final TreePanel tree_panel,
204 final boolean to_pdf ) {
205 final float f = getRenderingFactorWidth();
206 final float y = y1 + ( _rendering_height / 2 );
207 final float start = x1 + 20;
208 final Stroke s = g.getStroke();
209 g.setStroke( STROKE_1 );
211 g.setColor( tree_panel.getTreeColorSet().getDomainBaseColor() );
214 g.setColor( AptxConstants.DOMAIN_BASE_COLOR_FOR_PDF );
216 _rectangle.setFrame( start, y - 0.5, _domain_structure.getTotalLength() * f, 1 );
217 g.fill( _rectangle );
218 short special_domain_count = 0;
219 for( int i = 0; i < _domain_structure.getDomains().size(); ++i ) {
220 final ProteinDomain d = _domain_structure.getDomain( i );
221 if ( ( d.getConfidence() <= Math.pow( 10, _e_value_threshold_exp ) )
222 || ( TreePanel.SPECIAL_DOMAIN_COLORING && ( d.getName().equals( SPECIAL_DOMAIN ) ) && ( ( d
223 .getConfidence() <= 1 ) ) ) ) {
224 if ( TreePanel.SPECIAL_DOMAIN_COLORING && ( d.getName().equals( SPECIAL_DOMAIN ) ) ) {
225 special_domain_count++;
227 final float xa = start + ( d.getFrom() * f );
228 final float xb = xa + ( d.getLength() * f );
229 if ( tree_panel.getMainPanel().getOptions().isShowDomainLabels()
230 && ( tree_panel.getMainPanel().getTreeFontSet().getFontMetricsSmall().getHeight() > 4 ) ) {
231 g.setFont( tree_panel.getMainPanel().getTreeFontSet().getSmallFont() );
233 g.setColor( tree_panel.getTreeColorSet().getDomainLabelColor() );
236 g.setColor( AptxConstants.DOMAIN_LABEL_COLOR_FOR_PDF );
238 g.drawString( d.getName(), xa, y1
239 + tree_panel.getMainPanel().getTreeFontSet().getFontMetricsSmall().getAscent()
240 + _rendering_height );
242 if ( TreePanel.SPECIAL_DOMAIN_COLORING && ( _node_name.indexOf( "~" ) > 1 )
243 && ( d.getName().equals( SPECIAL_DOMAIN ) )
244 && ( _node_name.indexOf( "~" + special_domain_count + "-" ) < 1 ) ) {
245 drawDomainGrey( xa, y1, xb - xa, _rendering_height, d.getName(), g, to_pdf );
248 drawDomain( xa, y1, xb - xa, _rendering_height, d.getName(), g, to_pdf );
256 public void setParameter( final double e_value_threshold_exp ) {
257 _e_value_threshold_exp = ( int ) e_value_threshold_exp;
260 public void setRenderingFactorWidth( final float rendering_factor_width ) {
261 _rendering_factor_width = rendering_factor_width;
265 public void setRenderingHeight( final float rendering_height ) {
266 _rendering_height = rendering_height;
270 public StringBuffer toNHX() {
271 return _domain_structure.toNHX();
275 public void toPhyloXML( final Writer writer, final int level, final String indentation ) throws IOException {
276 _domain_structure.toPhyloXML( writer, level, indentation );