70b7a1c1722b10ec2722319b7d59d335c5c24a17
[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.ProteinDomain;
47 import org.forester.util.ForesterUtil;
48
49 public final class RenderableDomainArchitecture extends DomainArchitecture implements RenderablePhylogenyData {
50
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;
62
63     public RenderableDomainArchitecture( final DomainArchitecture domain_structure ) {
64         _domain_structure = domain_structure;
65     }
66
67     public RenderableDomainArchitecture( final DomainArchitecture domain_structure, final String node_name ) {
68         _domain_structure = domain_structure;
69         _node_name = node_name;
70     }
71
72     public static void setColorMap( final Map<String, Color> domain_colors ) {
73         _domain_colors = domain_colors;
74     }
75
76     @Override
77     public StringBuffer asSimpleText() {
78         return _domain_structure.asSimpleText();
79     }
80
81     @Override
82     public StringBuffer asText() {
83         return _domain_structure.asText();
84     }
85
86     @Override
87     public PhylogenyData copy() {
88         return _domain_structure.copy();
89     }
90
91     private final void drawDomain( final double x,
92                                    final double y,
93                                    final double width,
94                                    final double heigth,
95                                    final String name,
96                                    final Graphics2D g,
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 );
101         double step = 1;
102         if ( to_pdf ) {
103             step = 0.05;
104         }
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 );
110         }
111     }
112
113     private final void drawDomainGrey( final double x,
114                                        final double y,
115                                        final double width,
116                                        final double heigth,
117                                        final String name,
118                                        final Graphics2D g,
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 );
123         double step = 1;
124         if ( to_pdf ) {
125             step = 0.05;
126         }
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 );
132         }
133     }
134
135     private final Color getColorOne( final String name ) {
136         Color c = _domain_colors.get( name );
137         if ( c == null ) {
138             c = AptxUtil.calculateColorFromString( name, false );
139             if ( c == null ) {
140                 throw new IllegalStateException();
141             }
142             _domain_colors.put( name, c );
143         }
144         return c;
145     }
146
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 );
152     }
153
154     @Override
155     public ProteinDomain getDomain( final int i ) {
156         return _domain_structure.getDomain( i );
157     }
158
159     @Override
160     public SortedMap<BigDecimal, ProteinDomain> getDomains() {
161         return _domain_structure.getDomains();
162     }
163
164     @Override
165     public int getNumberOfDomains() {
166         return _domain_structure.getNumberOfDomains();
167     }
168
169     @Override
170     public Dimension getOriginalSize() {
171         return new Dimension( _domain_structure.getTotalLength(), ForesterUtil.roundToInt( _rendering_height ) );
172     }
173
174     @Override
175     public Object getParameter() {
176         return new Integer( _e_value_threshold_exp );
177     }
178
179     public float getRenderingFactorWidth() {
180         return _rendering_factor_width;
181     }
182
183     @Override
184     public Dimension getRenderingSize() {
185         return new Dimension( ForesterUtil.roundToInt( _domain_structure.getTotalLength() * getRenderingFactorWidth() ),
186                               ForesterUtil.roundToInt( _rendering_height ) );
187     }
188
189     @Override
190     public int getTotalLength() {
191         return _domain_structure.getTotalLength();
192     }
193
194     @Override
195     public boolean isEqual( final PhylogenyData data ) {
196         return _domain_structure.isEqual( data );
197     }
198
199     @Override
200     public void render( final float x1,
201                         final float y1,
202                         final Graphics2D g,
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 );
210         if ( !to_pdf ) {
211             g.setColor( tree_panel.getTreeColorSet().getDomainBaseColor() );
212         }
213         else {
214             g.setColor( Constants.DOMAIN_BASE_COLOR_FOR_PDF );
215         }
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++;
226                 }
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() );
232                     if ( !to_pdf ) {
233                         g.setColor( tree_panel.getTreeColorSet().getDomainLabelColor() );
234                     }
235                     else {
236                         g.setColor( Constants.DOMAIN_LABEL_COLOR_FOR_PDF );
237                     }
238                     g.drawString( d.getName(), xa, y1
239                                   + tree_panel.getMainPanel().getTreeFontSet().getFontMetricsSmall().getAscent()
240                                   + _rendering_height );
241                 }
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 );
246                 }
247                 else {
248                     drawDomain( xa, y1, xb - xa, _rendering_height, d.getName(), g, to_pdf );
249                 }
250             }
251         }
252         g.setStroke( s );
253     }
254
255     @Override
256     public void setParameter( final double e_value_threshold_exp ) {
257         _e_value_threshold_exp = ( int ) e_value_threshold_exp;
258     }
259
260     public void setRenderingFactorWidth( final float rendering_factor_width ) {
261         _rendering_factor_width = rendering_factor_width;
262     }
263
264     @Override
265     public void setRenderingHeight( final float rendering_height ) {
266         _rendering_height = rendering_height;
267     }
268
269     @Override
270     public StringBuffer toNHX() {
271         return _domain_structure.toNHX();
272     }
273
274     @Override
275     public void toPhyloXML( final Writer writer, final int level, final String indentation ) throws IOException {
276         _domain_structure.toPhyloXML( writer, level, indentation );
277     }
278 }