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