in progress
[jalview.git] / forester / java / src / org / forester / archaeopteryx / phylogeny / data / RenderableDomainArchitecture.java
1 // $Id:
2 // $
3 // FORESTER -- software libraries and applications
4 // for evolutionary biology research and applications.
5 //
6 // Copyright (C) 2008-2009 Christian M. Zmasek
7 // Copyright (C) 2008-2009 Burnham Institute for Medical Research
8 // All rights reserved
9 //
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.
14 //
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.
19 //
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
23 //
24 // Contact: phylosoft @ gmail . com
25 // WWW: https://sites.google.com/site/cmzmasek/home/software/forester
26
27 package org.forester.archaeopteryx.phylogeny.data;
28
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;
38 import java.util.Map;
39 import java.util.SortedMap;
40
41 import org.forester.archaeopteryx.AptxUtil;
42 import org.forester.archaeopteryx.Constants;
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.PhylogenyDataUtil;
47 import org.forester.phylogeny.data.ProteinDomain;
48 import org.forester.util.ForesterUtil;
49
50 public final class RenderableDomainArchitecture extends DomainArchitecture implements RenderablePhylogenyData {
51
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
62     public RenderableDomainArchitecture( final DomainArchitecture domain_structure ) {
63         _domain_structure = domain_structure;
64     }
65
66     public static void setColorMap( final Map<String, Color> domain_colors ) {
67         _domain_colors = domain_colors;
68     }
69
70     @Override
71     public StringBuffer asSimpleText() {
72         return _domain_structure.asSimpleText();
73     }
74
75     @Override
76     public StringBuffer asText() {
77         return _domain_structure.asText();
78     }
79
80     @Override
81     public PhylogenyData copy() {
82         return _domain_structure.copy();
83     }
84
85     private final void drawDomain( final double x,
86                                    final double y,
87                                    final double width,
88                                    final double heigth,
89                                    final String name,
90                                    final Graphics2D g,
91                                    final boolean to_pdf ) {
92         final double h2 = heigth / 2.0;
93         final Color color_one = getColorOne( name );
94         final Color color_two = getColorTwo( color_one );
95         double step = 1;
96         if ( to_pdf ) {
97             step = 0.05;
98         }
99         for( double i = 0; i < heigth; i += step ) {
100             g.setColor( org.forester.util.ForesterUtil
101                     .calcColor( i >= h2 ? heigth - i : i, 0, h2, color_one, color_two ) );
102             _rectangle.setFrame( x, i + y, width, step );
103             g.fill( _rectangle );
104         }
105     }
106
107     private final Color getColorOne( final String name ) {
108         Color c = _domain_colors.get( name );
109         if ( c == null ) {
110             c = AptxUtil.calculateColorFromString( name, false );
111             if ( c == null ) {
112                 throw new IllegalStateException();
113             }
114             _domain_colors.put( name, c );
115         }
116         return c;
117     }
118
119     private Color getColorTwo( final Color color_one ) {
120         final int red = color_one.getRed() + RenderableDomainArchitecture.BRIGHTEN_COLOR_BY;
121         final int green = color_one.getGreen() + RenderableDomainArchitecture.BRIGHTEN_COLOR_BY;
122         final int blue = color_one.getBlue() + RenderableDomainArchitecture.BRIGHTEN_COLOR_BY;
123         return new Color( red > 255 ? 255 : red, green > 255 ? 255 : green, blue > 255 ? 255 : blue );
124     }
125
126     @Override
127     public ProteinDomain getDomain( final int i ) {
128         return _domain_structure.getDomain( i );
129     }
130
131     @Override
132     public SortedMap<BigDecimal, ProteinDomain> getDomains() {
133         return _domain_structure.getDomains();
134     }
135
136     @Override
137     public int getNumberOfDomains() {
138         return _domain_structure.getNumberOfDomains();
139     }
140
141     @Override
142     public Dimension getOriginalSize() {
143         return new Dimension( _domain_structure.getTotalLength(), ForesterUtil.roundToInt( _rendering_height ) );
144     }
145
146     @Override
147     public Object getParameter() {
148         return new Integer( _e_value_threshold_exp );
149     }
150
151     public float getRenderingFactorWidth() {
152         return _rendering_factor_width;
153     }
154
155     @Override
156     public Dimension getRenderingSize() {
157         return new Dimension( ForesterUtil.roundToInt( _domain_structure.getTotalLength() * getRenderingFactorWidth() ),
158                               ForesterUtil.roundToInt( _rendering_height ) );
159     }
160
161     @Override
162     public int getTotalLength() {
163         return _domain_structure.getTotalLength();
164     }
165
166     @Override
167     public boolean isEqual( final PhylogenyData data ) {
168         return _domain_structure.isEqual( data );
169     }
170
171     @Override
172     public void render( final float x1,
173                         final float y1,
174                         final Graphics2D g,
175                         final TreePanel tree_panel,
176                         final boolean to_pdf ) {
177         final float f = getRenderingFactorWidth();
178         final float y = y1 + ( _rendering_height / 2 );
179         final float start = x1 + 20;
180         final Stroke s = g.getStroke();
181         g.setStroke( STROKE_1 );
182         if ( !to_pdf ) {
183             g.setColor( tree_panel.getTreeColorSet().getDomainBaseColor() );
184         }
185         else {
186             g.setColor( Constants.DOMAIN_BASE_COLOR_FOR_PDF );
187         }
188         _rectangle.setFrame( start, y - 0.5, _domain_structure.getTotalLength() * f, 1 );
189         g.fill( _rectangle );
190         for( int i = 0; i < _domain_structure.getDomains().size(); ++i ) {
191             final ProteinDomain d = _domain_structure.getDomain( i );
192             if ( d.getConfidence() <= Math.pow( 10, _e_value_threshold_exp ) ) {
193                 final float xa = start + ( d.getFrom() * f );
194                 final float xb = xa + ( d.getLength() * f );
195                 if ( tree_panel.getMainPanel().getOptions().isShowDomainLabels()
196                         && ( tree_panel.getMainPanel().getTreeFontSet().getFontMetricsSmall().getHeight() > 4 ) ) {
197                     g.setFont( tree_panel.getMainPanel().getTreeFontSet().getSmallFont() );
198                     if ( !to_pdf ) {
199                         g.setColor( tree_panel.getTreeColorSet().getDomainLabelColor() );
200                     }
201                     else {
202                         g.setColor( Constants.DOMAIN_LABEL_COLOR_FOR_PDF );
203                     }
204                     g.drawString( d.getName(),
205                                   xa,
206                                   y1
207                                   + tree_panel.getMainPanel().getTreeFontSet().getFontMetricsSmall().getAscent()
208                                   + _rendering_height  );
209                     
210                     
211                 }
212                 drawDomain( xa, y1, xb - xa, _rendering_height, d.getName(), g, to_pdf );
213             }
214         }
215         g.setStroke( s );
216     }
217
218     @Override
219     public void setParameter( final double e_value_threshold_exp ) {
220         _e_value_threshold_exp = ( int ) e_value_threshold_exp;
221     }
222
223     public void setRenderingFactorWidth( final float rendering_factor_width ) {
224         _rendering_factor_width = rendering_factor_width;
225     }
226
227     @Override
228     public void setRenderingHeight( final float rendering_height ) {
229         _rendering_height = rendering_height;
230     }
231
232     @Override
233     public StringBuffer toNHX() {
234         return _domain_structure.toNHX();
235     }
236
237     @Override
238     public void toPhyloXML( final Writer writer, final int level, final String indentation ) throws IOException {
239         _domain_structure.toPhyloXML( writer, level, indentation );
240     }
241 }