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