in progress
[jalview.git] / forester / java / src / org / forester / msa_compactor / Chart.java
1 // $Id:
2 // FORESTER -- software libraries and applications
3 // for evolutionary biology research and applications.
4 //
5 // Copyright (C) 2014 Christian M. Zmasek
6 // Copyright (C) 2014 Sanford-Burnham Medical Research Institute
7 // All rights reserved
8 //
9 // This library is free software; you can redistribute it and/or
10 // modify it under the terms of the GNU Lesser General Public
11 // License as published by the Free Software Foundation; either
12 // version 2.1 of the License, or (at your option) any later version.
13 //
14 // This library is distributed in the hope that it will be useful,
15 // but WITHOUT ANY WARRANTY; without even the implied warranty of
16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 // Lesser General Public License for more details.
18 //
19 // You should have received a copy of the GNU Lesser General Public
20 // License along with this library; if not, write to the Free Software
21 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
22 //
23 // WWW: https://sites.google.com/site/cmzmasek/home/software/forester
24
25 package org.forester.msa_compactor;
26
27 import java.awt.BorderLayout;
28 import java.awt.event.ActionListener;
29 import java.util.List;
30
31 import javax.swing.JDialog;
32 import javax.swing.JMenu;
33 import javax.swing.JMenuBar;
34 import javax.swing.JMenuItem;
35 import javax.swing.JPanel;
36 import javax.swing.UIManager;
37 import javax.swing.WindowConstants;
38
39 import org.forester.util.ForesterUtil;
40
41 import com.approximatrix.charting.coordsystem.BoxCoordSystem;
42 import com.approximatrix.charting.model.MultiScatterDataModel;
43 import com.approximatrix.charting.render.MultiScatterChartRenderer;
44 import com.approximatrix.charting.swing.ChartPanel;
45
46 public final class Chart extends JDialog implements ActionListener {
47
48     private static final long         serialVersionUID = -5292420246132943515L;
49     private ChartPanel                _chart_panel     = null;
50     private final int                 _initial_number_of_seqs;
51     private final JMenuItem           _m_exit          = new JMenuItem();
52     private final List<MsaProperties> _msa_props;
53     private final boolean             _show_msa_qual;
54     private final String              _title;
55
56     private Chart( final List<MsaProperties> msa_props,
57                    final int initial_number_of_seqs,
58                    final boolean show_msa_qual,
59                    final String title ) {
60         super();
61         _msa_props = msa_props;
62         _title = title;
63         _initial_number_of_seqs = initial_number_of_seqs;
64         _show_msa_qual = show_msa_qual;
65         setTitle( "msa compactor" );
66         setSize( 600, 500 );
67         setResizable( true );
68         final JPanel content_pane = new JPanel();
69         content_pane.setLayout( new BorderLayout() );
70         setContentPane( content_pane );
71         final JMenuBar menu_bar = new JMenuBar();
72         final JMenu file_menu = new JMenu();
73         file_menu.setText( "File" );
74         _m_exit.setText( "Exit" );
75         file_menu.add( _m_exit );
76         menu_bar.add( file_menu );
77         setJMenuBar( menu_bar );
78         setDefaultCloseOperation( WindowConstants.DISPOSE_ON_CLOSE );
79         _m_exit.addActionListener( this );
80         content_pane.add( obtainChartPanel(), BorderLayout.CENTER );
81     }
82
83     @Override
84     public void actionPerformed( final java.awt.event.ActionEvent e ) {
85         if ( e.getSource() == _m_exit ) {
86             dispose();
87         }
88     }
89
90     private ChartPanel obtainChartPanel() {
91         if ( _chart_panel == null ) {
92             final MultiScatterDataModel model = new MultiScatterDataModel();
93             final double[][] seqs_length = new double[ _msa_props.size() ][ 2 ];
94             int max_length = -1;
95             for( int i = 0; i < _msa_props.size(); ++i ) {
96                 seqs_length[ i ][ 0 ] = _initial_number_of_seqs - _msa_props.get( i ).getNumberOfSequences();
97                 seqs_length[ i ][ 1 ] = _msa_props.get( i ).getLength();
98                 if ( _msa_props.get( i ).getLength() > max_length ) {
99                     max_length = _msa_props.get( i ).getLength();
100                 }
101             }
102             model.addData( seqs_length, "Length" );
103             model.setSeriesLine( "Series " + "Length", true );
104             model.setSeriesMarker( "Series " + "Length", false );
105             final double[][] seqs_gaps = new double[ _msa_props.size() ][ 2 ];
106             double max_gap_ratio = -1;
107             double max_ent7 = -1;
108             double max_ent21 = -1;
109             for( int i = 0; i < _msa_props.size(); ++i ) {
110                 if ( _msa_props.get( i ).getGapRatio() > max_gap_ratio ) {
111                     max_gap_ratio = _msa_props.get( i ).getGapRatio();
112                 }
113                 if ( _show_msa_qual ) {
114                     if ( _msa_props.get( i ).getEntropy7() > max_ent7 ) {
115                         max_ent7 = _msa_props.get( i ).getEntropy7();
116                     }
117                     if ( _msa_props.get( i ).getEntropy21() > max_ent21 ) {
118                         max_ent21 = _msa_props.get( i ).getEntropy21();
119                     }
120                 }
121             }
122             final double gap_ratio_factor = ( max_length / 2.0 ) / max_gap_ratio;
123             final double ent7_factor = ( max_length / 2.0 ) / max_ent7;
124             final double ent21_factor = ( max_length / 2.0 ) / max_ent21;
125             for( int i = 0; i < _msa_props.size(); ++i ) {
126                 seqs_gaps[ i ][ 0 ] = _initial_number_of_seqs - _msa_props.get( i ).getNumberOfSequences();
127                 seqs_gaps[ i ][ 1 ] = ForesterUtil.roundToInt( _msa_props.get( i ).getGapRatio() * gap_ratio_factor );
128             }
129             model.addData( seqs_gaps, "Gap ratio" );
130             model.setSeriesLine( "Series " + "Gap ratio", true );
131             model.setSeriesMarker( "Series " + "Gap ratio", false );
132             if ( _show_msa_qual ) {
133                 final double[][] entropy7 = new double[ _msa_props.size() ][ 2 ];
134                 for( int i = 0; i < _msa_props.size(); ++i ) {
135                     entropy7[ i ][ 0 ] = _initial_number_of_seqs - _msa_props.get( i ).getNumberOfSequences();
136                     entropy7[ i ][ 1 ] = ForesterUtil.roundToInt( _msa_props.get( i ).getEntropy7() * ent7_factor );
137                 }
138                 model.addData( entropy7, "Entropy norm 7" );
139                 model.setSeriesLine( "Series " + "Entropy norm 7", true );
140                 model.setSeriesMarker( "Series " + "Entropy norm 7", false );
141                 //
142                 final double[][] entropy21 = new double[ _msa_props.size() ][ 2 ];
143                 for( int i = 0; i < _msa_props.size(); ++i ) {
144                     entropy21[ i ][ 0 ] = _initial_number_of_seqs - _msa_props.get( i ).getNumberOfSequences();
145                     entropy21[ i ][ 1 ] = ForesterUtil.roundToInt( _msa_props.get( i ).getEntropy21() * ent21_factor );
146                 }
147                 model.addData( entropy21, "Entropy norm 21" );
148                 model.setSeriesLine( "Series " + "Entropy norm 21", true );
149                 model.setSeriesMarker( "Series " + "Entropy norm 21", false );
150             }
151             final BoxCoordSystem coord = new BoxCoordSystem( model );
152             coord.setUnitFont( coord.getUnitFont().deriveFont( 16.0f ) );
153             coord.setXAxisUnit( "Number of Removed Sequences" );
154             coord.setPaintGrid( true );
155             coord.setYAxisUnit( "MSA Length" );
156             _chart_panel = new ChartPanel( model, _title );
157             _chart_panel.setCoordSystem( coord );
158             final MultiScatterChartRenderer renderer = new MultiScatterChartRenderer( coord, model );
159             renderer.setAllowBuffer( false );
160             _chart_panel.addChartRenderer( renderer, 0 );
161         }
162         return _chart_panel;
163     }
164
165     public static void display( final List<MsaProperties> msa_props,
166                                 final int initial_number_of_seqs,
167                                 final boolean show_msa_qual,
168                                 final String title ) {
169         try {
170             UIManager.setLookAndFeel( UIManager.getSystemLookAndFeelClassName() );
171         }
172         catch ( final Exception e ) {
173             e.printStackTrace();
174         }
175         final Chart chart = new Chart( msa_props, initial_number_of_seqs, show_msa_qual, title );
176         chart.setVisible( true );
177     }
178
179     public static void main( final String[] args ) {
180         try {
181             UIManager.setLookAndFeel( UIManager.getSystemLookAndFeelClassName() );
182         }
183         catch ( final Exception e ) {
184             e.printStackTrace();
185         }
186         final Chart temp = new Chart( null, 0, true, "title" );
187         temp.setVisible( true );
188     }
189 }