update author list in license for (JAL-826)
[jalview.git] / src / jalview / appletgui / PCAPanel.java
index a75de06..89999d9 100755 (executable)
-/*\r
- * Jalview - A Sequence Alignment Editor and Viewer\r
- * Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU General Public License\r
- * as published by the Free Software Foundation; either version 2\r
- * of the License, or (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this program; if not, write to the Free Software\r
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
- */\r
-\r
-package jalview.appletgui;\r
-\r
-import java.util.*;\r
-\r
-import java.awt.*;\r
-import java.awt.event.*;\r
-\r
-import jalview.analysis.*;\r
-import jalview.datamodel.*;\r
-\r
-\r
-public class PCAPanel\r
-    extends Frame implements Runnable, ActionListener, ItemListener\r
-{\r
-  PCA pca;\r
-  int top;\r
-  RotatableCanvas rc;\r
-  AlignViewport av;\r
-  SequenceI [] seqs;\r
-\r
-\r
-  public PCAPanel(AlignViewport av)\r
-  {\r
-    try\r
-    {\r
-      jbInit();\r
-    }\r
-    catch (Exception e)\r
-    {\r
-      e.printStackTrace();\r
-    }\r
-\r
-    for (int i = 1; i < 8; i++)\r
-    {\r
-      xCombobox.addItem("dim " + i);\r
-      yCombobox.addItem("dim " + i);\r
-      zCombobox.addItem("dim " + i);\r
-    }\r
-\r
-    this.av = av;\r
-    if (av.getSelectionGroup()!=null && av.getSelectionGroup().getSize() > 3)\r
-    {\r
-      seqs = new Sequence[av.getSelectionGroup().getSize()];\r
-      for (int i = 0; i < av.getSelectionGroup().getSize(); i++)\r
-      {\r
-        seqs[i] = av.getSelectionGroup().getSequenceAt(i);\r
-      }\r
-    }\r
-    else\r
-    {\r
-      seqs = new Sequence[av.getAlignment().getHeight()];\r
-      for (int i = 0; i < av.getAlignment().getHeight(); i++)\r
-      {\r
-        seqs[i] = av.getAlignment().getSequenceAt(i);\r
-      }\r
-    }\r
-\r
-    rc = new RotatableCanvas(av);\r
-    add(rc, BorderLayout.CENTER);\r
-\r
-    jalview.bin.JalviewLite.addFrame(this, "Principal component analysis",\r
-                                       400, 400);\r
-\r
-\r
-    Thread worker = new Thread(this);\r
-    worker.start();\r
-  }\r
-\r
-  /**\r
-   * DOCUMENT ME!\r
-   */\r
-  public void run()\r
-  {\r
-              pca = new PCA(seqs);\r
-              pca.run();\r
-\r
-              // Now find the component coordinates\r
-              int ii = 0;\r
-\r
-              while ((ii < seqs.length) && (seqs[ii] != null))\r
-              {\r
-                  ii++;\r
-              }\r
-\r
-              double[][] comps = new double[ii][ii];\r
-\r
-              for (int i = 0; i < ii; i++)\r
-              {\r
-                  if (pca.getEigenvalue(i) > 1e-4)\r
-                  {\r
-                      comps[i] = pca.component(i);\r
-                  }\r
-              }\r
-\r
-              //////////////////\r
-              xCombobox.select(0);\r
-              yCombobox.select(1);\r
-              zCombobox.select(2);\r
-\r
-              top = pca.getM().rows - 1;\r
-\r
-              Vector points = new Vector();\r
-              float[][] scores = pca.getComponents(top - 1, top - 2, top - 3, 100);\r
-\r
-              for (int i = 0; i < pca.getM().rows; i++)\r
-              {\r
-                  SequencePoint sp = new SequencePoint(seqs[i], scores[i]);\r
-                  points.addElement(sp);\r
-              }\r
-\r
-              rc.setPoints(points, pca.getM().rows);\r
-              rc.repaint();\r
-              seqs = null;\r
-              this.repaint();\r
-  }\r
-\r
-  void doDimensionChange()\r
-  {\r
-    if (top == 0)\r
-    {\r
-      return;\r
-    }\r
-\r
-    int dim1 = top - xCombobox.getSelectedIndex();\r
-    int dim2 = top - yCombobox.getSelectedIndex();\r
-    int dim3 = top - zCombobox.getSelectedIndex();\r
-\r
-    float[][] scores = pca.getComponents(dim1, dim2, dim3, 100);\r
-    for (int i = 0; i < pca.getM().rows; i++)\r
-    {\r
-      ( (SequencePoint) rc.points.elementAt(i)).coord = scores[i];\r
-    }\r
-\r
-    rc.img = null;\r
-    rc.rotmat.setIdentity();\r
-    rc.initAxes();\r
-    rc.paint(rc.getGraphics());\r
-  }\r
-\r
-  public void actionPerformed(ActionEvent evt)\r
-  {\r
-    values_actionPerformed();\r
-  }\r
-\r
-  public void itemStateChanged(ItemEvent evt)\r
-  {\r
-    if(evt.getSource()==xCombobox)\r
-      xCombobox_actionPerformed();\r
-    else if(evt.getSource()==yCombobox)\r
-      yCombobox_actionPerformed();\r
-    else if(evt.getSource()==zCombobox)\r
-      zCombobox_actionPerformed();\r
-  }\r
-\r
-\r
-  protected void xCombobox_actionPerformed()\r
-  {\r
-    doDimensionChange();\r
-  }\r
-\r
-  protected void yCombobox_actionPerformed()\r
-  {\r
-    doDimensionChange();\r
-  }\r
-\r
-  protected void zCombobox_actionPerformed()\r
-  {\r
-    doDimensionChange();\r
-  }\r
-\r
-  public void values_actionPerformed()\r
-  {\r
-\r
-    CutAndPasteTransfer cap = new CutAndPasteTransfer(false, null);\r
-    Frame frame = new Frame();\r
-    frame.add(cap);\r
-    jalview.bin.JalviewLite.addFrame(frame, "PCA details", 500, 500);\r
-\r
-      cap.setText(pca.getDetails());\r
-  }\r
-\r
-  public void labels_itemStateChanged(ItemEvent itemEvent)\r
-  {\r
-    rc.showLabels( labels.getState() );\r
-  }\r
-  Panel jPanel2 = new Panel();\r
-  Label jLabel1 = new Label();\r
-  Label jLabel2 = new Label();\r
-  Label jLabel3 = new Label();\r
-  protected Choice xCombobox = new Choice();\r
-  protected Choice yCombobox = new Choice();\r
-  protected Choice zCombobox = new Choice();\r
-  FlowLayout flowLayout1 = new FlowLayout();\r
-  BorderLayout borderLayout1 = new BorderLayout();\r
-  MenuBar menuBar1 = new MenuBar();\r
-  Menu menu1 = new Menu();\r
-  Menu menu2 = new Menu();\r
-  protected CheckboxMenuItem labels = new CheckboxMenuItem();\r
-  MenuItem values = new MenuItem();\r
-\r
-  private void jbInit()\r
-      throws Exception\r
-  {\r
-    this.setLayout(borderLayout1);\r
-    jPanel2.setLayout(flowLayout1);\r
-    jLabel1.setFont(new java.awt.Font("Verdana", 0, 12));\r
-    jLabel1.setText("x=");\r
-    jLabel2.setFont(new java.awt.Font("Verdana", 0, 12));\r
-    jLabel2.setText("y=");\r
-    jLabel3.setFont(new java.awt.Font("Verdana", 0, 12));\r
-    jLabel3.setText("z=");\r
-    jPanel2.setBackground(Color.white);\r
-    zCombobox.setFont(new java.awt.Font("Verdana", 0, 12));\r
-    zCombobox.addItemListener(this);\r
-    yCombobox.setFont(new java.awt.Font("Verdana", 0, 12));\r
-    yCombobox.addItemListener(this);\r
-    xCombobox.setFont(new java.awt.Font("Verdana", 0, 12));\r
-    xCombobox.addItemListener(this);\r
-    this.setMenuBar(menuBar1);\r
-    menu1.setLabel("File");\r
-    menu2.setLabel("View");\r
-    labels.setLabel("Labels");\r
-    labels.addItemListener(this);\r
-    values.setLabel("Output Values...");\r
-    values.addActionListener(this);\r
-    this.add(jPanel2, BorderLayout.SOUTH);\r
-    jPanel2.add(jLabel1, null);\r
-    jPanel2.add(xCombobox, null);\r
-    jPanel2.add(jLabel2, null);\r
-    jPanel2.add(yCombobox, null);\r
-    jPanel2.add(jLabel3, null);\r
-    jPanel2.add(zCombobox, null);\r
-    menuBar1.add(menu1);\r
-    menuBar1.add(menu2);\r
-    menu2.add(labels);\r
-    menu1.add(values);\r
-  }\r
-\r
-}\r
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer (Version 2.7)
+ * Copyright (C) 2011 J Procter, AM Waterhouse, J Engelhardt, LM Lui, G Barton, M Clamp, S Searle
+ * 
+ * This file is part of Jalview.
+ * 
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License 
+ * as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
+ * 
+ * Jalview is distributed in the hope that it will be useful, but 
+ * WITHOUT ANY WARRANTY; without even the implied warranty 
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
+ * PURPOSE.  See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package jalview.appletgui;
+
+import java.util.*;
+
+import java.awt.*;
+import java.awt.event.*;
+
+import jalview.analysis.*;
+import jalview.datamodel.*;
+
+public class PCAPanel extends EmbmenuFrame implements Runnable,
+        ActionListener, ItemListener
+{
+  PCA pca;
+
+  int top;
+
+  RotatableCanvas rc;
+
+  AlignViewport av;
+
+  SequenceI[] seqs;
+
+  AlignmentView seqstrings;
+
+  public PCAPanel(AlignViewport av)
+  {
+    try
+    {
+      jbInit();
+    } catch (Exception e)
+    {
+      e.printStackTrace();
+    }
+
+    for (int i = 1; i < 8; i++)
+    {
+      xCombobox.addItem("dim " + i);
+      yCombobox.addItem("dim " + i);
+      zCombobox.addItem("dim " + i);
+    }
+
+    this.av = av;
+    seqstrings = av.getAlignmentView(av.getSelectionGroup() != null);
+    if (av.getSelectionGroup() == null)
+    {
+      seqs = av.alignment.getSequencesArray();
+    }
+    else
+    {
+      seqs = av.getSelectionGroup().getSequencesInOrder(av.alignment);
+    }
+    SeqCigar sq[] = seqstrings.getSequences();
+    int length = sq[0].getWidth();
+
+    for (int i = 0; i < seqs.length; i++)
+    {
+      if (sq[i].getWidth() != length)
+      {
+        System.out
+                .println("Sequences must be equal length for PCA analysis");
+        return;
+      }
+    }
+
+    rc = new RotatableCanvas(av);
+    embedMenuIfNeeded(rc);
+    add(rc, BorderLayout.CENTER);
+
+    jalview.bin.JalviewLite.addFrame(this, "Principal component analysis",
+            400, 400);
+
+    Thread worker = new Thread(this);
+    worker.start();
+  }
+
+  /**
+   * DOCUMENT ME!
+   */
+  public void run()
+  {
+    pca = new PCA(seqstrings.getSequenceStrings(' '));
+    pca.run();
+
+    // Now find the component coordinates
+    int ii = 0;
+
+    while ((ii < seqs.length) && (seqs[ii] != null))
+    {
+      ii++;
+    }
+
+    double[][] comps = new double[ii][ii];
+
+    for (int i = 0; i < ii; i++)
+    {
+      if (pca.getEigenvalue(i) > 1e-4)
+      {
+        comps[i] = pca.component(i);
+      }
+    }
+
+    // ////////////////
+    xCombobox.select(0);
+    yCombobox.select(1);
+    zCombobox.select(2);
+
+    top = pca.getM().rows - 1;
+
+    Vector points = new Vector();
+    float[][] scores = pca.getComponents(top - 1, top - 2, top - 3, 100);
+
+    for (int i = 0; i < pca.getM().rows; i++)
+    {
+      SequencePoint sp = new SequencePoint(seqs[i], scores[i]);
+      points.addElement(sp);
+    }
+
+    rc.setPoints(points, pca.getM().rows);
+    rc.repaint();
+    seqs = null;
+    this.repaint();
+  }
+
+  void doDimensionChange()
+  {
+    if (top == 0)
+    {
+      return;
+    }
+
+    int dim1 = top - xCombobox.getSelectedIndex();
+    int dim2 = top - yCombobox.getSelectedIndex();
+    int dim3 = top - zCombobox.getSelectedIndex();
+
+    float[][] scores = pca.getComponents(dim1, dim2, dim3, 100);
+    for (int i = 0; i < pca.getM().rows; i++)
+    {
+      ((SequencePoint) rc.points.elementAt(i)).coord = scores[i];
+    }
+
+    rc.img = null;
+    rc.rotmat.setIdentity();
+    rc.initAxes();
+    rc.paint(rc.getGraphics());
+  }
+
+  public void actionPerformed(ActionEvent evt)
+  {
+    if (evt.getSource() == inputData)
+    {
+      showOriginalData();
+    }
+    else
+    {
+      values_actionPerformed();
+    }
+  }
+
+  public void itemStateChanged(ItemEvent evt)
+  {
+    if (evt.getSource() == xCombobox)
+    {
+      xCombobox_actionPerformed();
+    }
+    else if (evt.getSource() == yCombobox)
+    {
+      yCombobox_actionPerformed();
+    }
+    else if (evt.getSource() == zCombobox)
+    {
+      zCombobox_actionPerformed();
+    }
+  }
+
+  protected void xCombobox_actionPerformed()
+  {
+    doDimensionChange();
+  }
+
+  protected void yCombobox_actionPerformed()
+  {
+    doDimensionChange();
+  }
+
+  protected void zCombobox_actionPerformed()
+  {
+    doDimensionChange();
+  }
+
+  public void values_actionPerformed()
+  {
+
+    CutAndPasteTransfer cap = new CutAndPasteTransfer(false, null);
+    Frame frame = new Frame();
+    frame.add(cap);
+    jalview.bin.JalviewLite.addFrame(frame, "PCA details", 500, 500);
+
+    cap.setText(pca.getDetails());
+  }
+
+  void showOriginalData()
+  {
+    // decide if av alignment is sufficiently different to original data to
+    // warrant a new window to be created
+    // create new alignmnt window with hidden regions (unhiding hidden regions
+    // yields unaligned seqs)
+    // or create a selection box around columns in alignment view
+    // test Alignment(SeqCigar[])
+    char gc = '-';
+    try
+    {
+      // we try to get the associated view's gap character
+      // but this may fail if the view was closed...
+      gc = av.getGapCharacter();
+    } catch (Exception ex)
+    {
+    }
+    ;
+    Object[] alAndColsel = seqstrings.getAlignmentAndColumnSelection(gc);
+
+    if (alAndColsel != null && alAndColsel[0] != null)
+    {
+      Alignment al = new Alignment((SequenceI[]) alAndColsel[0]);
+      AlignFrame af = new AlignFrame(al, av.applet,
+              "Original Data for PCA", false);
+
+      af.viewport.setHiddenColumns((ColumnSelection) alAndColsel[1]);
+    }
+  }
+
+  public void labels_itemStateChanged(ItemEvent itemEvent)
+  {
+    rc.showLabels(labels.getState());
+  }
+
+  Panel jPanel2 = new Panel();
+
+  Label jLabel1 = new Label();
+
+  Label jLabel2 = new Label();
+
+  Label jLabel3 = new Label();
+
+  protected Choice xCombobox = new Choice();
+
+  protected Choice yCombobox = new Choice();
+
+  protected Choice zCombobox = new Choice();
+
+  FlowLayout flowLayout1 = new FlowLayout();
+
+  BorderLayout borderLayout1 = new BorderLayout();
+
+  MenuBar menuBar1 = new MenuBar();
+
+  Menu menu1 = new Menu();
+
+  Menu menu2 = new Menu();
+
+  protected CheckboxMenuItem labels = new CheckboxMenuItem();
+
+  MenuItem values = new MenuItem();
+
+  MenuItem inputData = new MenuItem();
+
+  private void jbInit() throws Exception
+  {
+    this.setLayout(borderLayout1);
+    jPanel2.setLayout(flowLayout1);
+    jLabel1.setFont(new java.awt.Font("Verdana", 0, 12));
+    jLabel1.setText("x=");
+    jLabel2.setFont(new java.awt.Font("Verdana", 0, 12));
+    jLabel2.setText("y=");
+    jLabel3.setFont(new java.awt.Font("Verdana", 0, 12));
+    jLabel3.setText("z=");
+    jPanel2.setBackground(Color.white);
+    zCombobox.setFont(new java.awt.Font("Verdana", 0, 12));
+    zCombobox.addItemListener(this);
+    yCombobox.setFont(new java.awt.Font("Verdana", 0, 12));
+    yCombobox.addItemListener(this);
+    xCombobox.setFont(new java.awt.Font("Verdana", 0, 12));
+    xCombobox.addItemListener(this);
+    this.setMenuBar(menuBar1);
+    menu1.setLabel("File");
+    menu2.setLabel("View");
+    labels.setLabel("Labels");
+    labels.addItemListener(this);
+    values.setLabel("Output Values...");
+    values.addActionListener(this);
+    inputData.setLabel("Input Data...");
+    this.add(jPanel2, BorderLayout.SOUTH);
+    jPanel2.add(jLabel1, null);
+    jPanel2.add(xCombobox, null);
+    jPanel2.add(jLabel2, null);
+    jPanel2.add(yCombobox, null);
+    jPanel2.add(jLabel3, null);
+    jPanel2.add(zCombobox, null);
+    menuBar1.add(menu1);
+    menuBar1.add(menu2);
+    menu2.add(labels);
+    menu1.add(values);
+    menu1.add(inputData);
+    inputData.addActionListener(this);
+  }
+
+}