updated to jalview 2.1 and begun ArchiveClient/VamsasClient/VamsasStore updates.
[jalview.git] / src / jalview / appletgui / PCAPanel.java
1 /*
2  * Jalview - A Sequence Alignment Editor and Viewer
3  * Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * as published by the Free Software Foundation; either version 2
8  * of the License, or (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
18  */
19
20 package jalview.appletgui;
21
22 import java.util.*;
23
24 import java.awt.*;
25 import java.awt.event.*;
26
27 import jalview.analysis.*;
28 import jalview.datamodel.*;
29
30
31 public class PCAPanel
32     extends Frame implements Runnable, ActionListener, ItemListener
33 {
34   PCA pca;
35   int top;
36   RotatableCanvas rc;
37   AlignViewport av;
38   SequenceI [] seqs;
39   AlignmentView seqstrings;
40
41
42   public PCAPanel(AlignViewport av)
43   {
44     try
45     {
46       jbInit();
47     }
48     catch (Exception e)
49     {
50       e.printStackTrace();
51     }
52
53     for (int i = 1; i < 8; i++)
54     {
55       xCombobox.addItem("dim " + i);
56       yCombobox.addItem("dim " + i);
57       zCombobox.addItem("dim " + i);
58     }
59
60     this.av = av;
61     seqstrings = av.getAlignmentView(av.getSelectionGroup()!=null);
62     if(av.getSelectionGroup()==null)
63     {
64       seqs = av.alignment.getSequencesArray();
65     }
66     else
67     {
68       seqs = av.getSelectionGroup().getSequencesInOrder(av.alignment);
69     }
70     SeqCigar sq[]=seqstrings.getSequences();
71     int length = sq[0].getWidth();
72
73     for (int i = 0; i < seqs.length; i++)
74     {
75       if (sq[i].getWidth() != length)
76       {
77         System.out.println("Sequences must be equal length for PCA analysis");
78         return;
79       }
80     }
81
82
83     rc = new RotatableCanvas(av);
84     add(rc, BorderLayout.CENTER);
85
86     jalview.bin.JalviewLite.addFrame(this, "Principal component analysis",
87                                        400, 400);
88
89
90     Thread worker = new Thread(this);
91     worker.start();
92   }
93
94   /**
95    * DOCUMENT ME!
96    */
97   public void run()
98   {
99               pca = new PCA(seqstrings.getSequenceStrings(' '));
100               pca.run();
101
102               // Now find the component coordinates
103               int ii = 0;
104
105               while ((ii < seqs.length) && (seqs[ii] != null))
106               {
107                   ii++;
108               }
109
110               double[][] comps = new double[ii][ii];
111
112               for (int i = 0; i < ii; i++)
113               {
114                   if (pca.getEigenvalue(i) > 1e-4)
115                   {
116                       comps[i] = pca.component(i);
117                   }
118               }
119
120               //////////////////
121               xCombobox.select(0);
122               yCombobox.select(1);
123               zCombobox.select(2);
124
125               top = pca.getM().rows - 1;
126
127               Vector points = new Vector();
128               float[][] scores = pca.getComponents(top - 1, top - 2, top - 3, 100);
129
130               for (int i = 0; i < pca.getM().rows; i++)
131               {
132                   SequencePoint sp = new SequencePoint(seqs[i], scores[i]);
133                   points.addElement(sp);
134               }
135
136               rc.setPoints(points, pca.getM().rows);
137               rc.repaint();
138               seqs = null;
139               this.repaint();
140   }
141
142   void doDimensionChange()
143   {
144     if (top == 0)
145     {
146       return;
147     }
148
149     int dim1 = top - xCombobox.getSelectedIndex();
150     int dim2 = top - yCombobox.getSelectedIndex();
151     int dim3 = top - zCombobox.getSelectedIndex();
152
153     float[][] scores = pca.getComponents(dim1, dim2, dim3, 100);
154     for (int i = 0; i < pca.getM().rows; i++)
155     {
156       ( (SequencePoint) rc.points.elementAt(i)).coord = scores[i];
157     }
158
159     rc.img = null;
160     rc.rotmat.setIdentity();
161     rc.initAxes();
162     rc.paint(rc.getGraphics());
163   }
164
165   public void actionPerformed(ActionEvent evt)
166   {
167     if(evt.getSource()==inputData)
168       showOriginalData();
169     else
170       values_actionPerformed();
171   }
172
173   public void itemStateChanged(ItemEvent evt)
174   {
175     if(evt.getSource()==xCombobox)
176       xCombobox_actionPerformed();
177     else if(evt.getSource()==yCombobox)
178       yCombobox_actionPerformed();
179     else if(evt.getSource()==zCombobox)
180       zCombobox_actionPerformed();
181   }
182
183
184   protected void xCombobox_actionPerformed()
185   {
186     doDimensionChange();
187   }
188
189   protected void yCombobox_actionPerformed()
190   {
191     doDimensionChange();
192   }
193
194   protected void zCombobox_actionPerformed()
195   {
196     doDimensionChange();
197   }
198
199   public void values_actionPerformed()
200   {
201
202     CutAndPasteTransfer cap = new CutAndPasteTransfer(false, null);
203     Frame frame = new Frame();
204     frame.add(cap);
205     jalview.bin.JalviewLite.addFrame(frame, "PCA details", 500, 500);
206
207       cap.setText(pca.getDetails());
208   }
209
210   void showOriginalData()
211   {
212     // decide if av alignment is sufficiently different to original data to warrant a new window to be created
213     // create new alignmnt window with hidden regions (unhiding hidden regions yields unaligned seqs)
214     // or create a selection box around columns in alignment view
215     // test Alignment(SeqCigar[])
216     Object[] alAndColsel = seqstrings.getAlignmentAndColumnSelection(av.
217         getGapCharacter());
218
219
220     if (alAndColsel != null && alAndColsel[0]!=null)
221      {
222        Alignment al = new Alignment( (SequenceI[]) alAndColsel[0]);
223        AlignFrame af = new AlignFrame(al,
224              av.applet,
225              "Original Data for PCA",
226              false);
227
228       af.viewport.setHiddenColumns( (ColumnSelection) alAndColsel[1] );
229      }
230   }
231
232   public void labels_itemStateChanged(ItemEvent itemEvent)
233   {
234     rc.showLabels( labels.getState() );
235   }
236   Panel jPanel2 = new Panel();
237   Label jLabel1 = new Label();
238   Label jLabel2 = new Label();
239   Label jLabel3 = new Label();
240   protected Choice xCombobox = new Choice();
241   protected Choice yCombobox = new Choice();
242   protected Choice zCombobox = new Choice();
243   FlowLayout flowLayout1 = new FlowLayout();
244   BorderLayout borderLayout1 = new BorderLayout();
245   MenuBar menuBar1 = new MenuBar();
246   Menu menu1 = new Menu();
247   Menu menu2 = new Menu();
248   protected CheckboxMenuItem labels = new CheckboxMenuItem();
249   MenuItem values = new MenuItem();
250   MenuItem inputData = new MenuItem();
251
252   private void jbInit()
253       throws Exception
254   {
255     this.setLayout(borderLayout1);
256     jPanel2.setLayout(flowLayout1);
257     jLabel1.setFont(new java.awt.Font("Verdana", 0, 12));
258     jLabel1.setText("x=");
259     jLabel2.setFont(new java.awt.Font("Verdana", 0, 12));
260     jLabel2.setText("y=");
261     jLabel3.setFont(new java.awt.Font("Verdana", 0, 12));
262     jLabel3.setText("z=");
263     jPanel2.setBackground(Color.white);
264     zCombobox.setFont(new java.awt.Font("Verdana", 0, 12));
265     zCombobox.addItemListener(this);
266     yCombobox.setFont(new java.awt.Font("Verdana", 0, 12));
267     yCombobox.addItemListener(this);
268     xCombobox.setFont(new java.awt.Font("Verdana", 0, 12));
269     xCombobox.addItemListener(this);
270     this.setMenuBar(menuBar1);
271     menu1.setLabel("File");
272     menu2.setLabel("View");
273     labels.setLabel("Labels");
274     labels.addItemListener(this);
275     values.setLabel("Output Values...");
276     values.addActionListener(this);
277     inputData.setLabel("Input Data...");
278     this.add(jPanel2, BorderLayout.SOUTH);
279     jPanel2.add(jLabel1, null);
280     jPanel2.add(xCombobox, null);
281     jPanel2.add(jLabel2, null);
282     jPanel2.add(yCombobox, null);
283     jPanel2.add(jLabel3, null);
284     jPanel2.add(zCombobox, null);
285     menuBar1.add(menu1);
286     menuBar1.add(menu2);
287     menu2.add(labels);
288     menu1.add(values);
289     menu1.add(inputData);
290     inputData.addActionListener(this);
291   }
292
293 }