/*
- * Jalview - A Sequence Alignment Editor and Viewer (Version 2.5)
- * Copyright (C) 2010 J Procter, AM Waterhouse, G Barton, M Clamp, S Searle
+ * Jalview - A Sequence Alignment Editor and Viewer (Version 2.8.1)
+ * Copyright (C) 2014 The Jalview Authors
*
* 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/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
*/
package jalview.gui;
import java.util.*;
-
import java.awt.*;
import java.awt.event.*;
import java.awt.print.*;
+
import javax.swing.*;
-import jalview.analysis.*;
import jalview.datamodel.*;
import jalview.jbgui.*;
+import jalview.schemes.ResidueProperties;
+import jalview.util.MessageManager;
+import jalview.viewmodel.PCAModel;
/**
* DOCUMENT ME!
* @author $author$
* @version $Revision$
*/
-public class PCAPanel extends GPCAPanel implements Runnable
+public class PCAPanel extends GPCAPanel implements Runnable,
+ IProgressIndicator
{
- PCA pca;
-
- int top;
-
RotatableCanvas rc;
AlignmentPanel ap;
AlignViewport av;
- AlignmentView seqstrings;
+ PCAModel pcaModel;
- SequenceI[] seqs;
+ int top = 0;
/**
* Creates a new PCAPanel object.
this.ap = ap;
boolean sameLength = true;
-
- seqstrings = av.getAlignmentView(av.getSelectionGroup() != null);
- if (av.getSelectionGroup() == null)
+ boolean selected = av.getSelectionGroup() != null
+ && av.getSelectionGroup().getSize() > 0;
+ AlignmentView seqstrings = av.getAlignmentView(selected);
+ boolean nucleotide = av.getAlignment().isNucleotide();
+ SequenceI[] seqs;
+ if (!selected)
{
- seqs = av.alignment.getSequencesArray();
+ seqs = av.getAlignment().getSequencesArray();
}
else
{
- seqs = av.getSelectionGroup().getSequencesInOrder(av.alignment);
+ seqs = av.getSelectionGroup().getSequencesInOrder(av.getAlignment());
}
SeqCigar sq[] = seqstrings.getSequences();
int length = sq[0].getWidth();
return;
}
-
- Desktop
- .addInternalFrame(this, "Principal component analysis", 400,
- 400);
-
+ pcaModel = new PCAModel(seqstrings, seqs, nucleotide);
PaintRefresher.Register(this, av.getSequenceSetId());
rc = new RotatableCanvas(ap);
Thread worker = new Thread(this);
worker.start();
}
-
+ @Override
+ protected void scoreMatrix_menuSelected()
+ {
+ scoreMatrixMenu.removeAll();
+ for (final String sm:ResidueProperties.scoreMatrices.keySet())
+ {
+ if (ResidueProperties.getScoreMatrix(sm) != null)
+ {
+ // create an entry for this score matrix for use in PCA
+ JCheckBoxMenuItem jm = new JCheckBoxMenuItem();
+ jm.setText(MessageManager
+ .getStringOrReturn("label.score_model", sm));
+ jm.setSelected(pcaModel.getScore_matrix().equals(sm));
+ if ((ResidueProperties.scoreMatrices.get(sm).isDNA() && ResidueProperties.scoreMatrices
+ .get(sm).isProtein())
+ || pcaModel.isNucleotide() == ResidueProperties.scoreMatrices
+ .get(sm).isDNA())
+ {
+ final PCAPanel us = this;
+ jm.addActionListener(new ActionListener()
+ {
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ if (!pcaModel.getScore_matrix().equals((String) sm))
+ {
+ pcaModel.setScore_matrix((String) sm);
+ Thread worker = new Thread(us);
+ worker.start();
+ }
+ }
+ });
+ scoreMatrixMenu.add(jm);
+ }
+ }
+ }
+ }
public void bgcolour_actionPerformed(ActionEvent e)
{
Color col = JColorChooser.showDialog(this, "Select Background Colour",
*/
public void run()
{
+ long progId = System.currentTimeMillis();
+ IProgressIndicator progress = this;
+ String message = "Recalculating PCA";
+ if (getParent() == null)
+ {
+ progress = ap.alignFrame;
+ message = "Calculating PCA";
+ }
+ progress.setProgressBar(message, progId);
try
{
- 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);
- }
- }
-
+ calcSettings.setEnabled(false);
+ pcaModel.run();
// ////////////////
xCombobox.setSelectedIndex(0);
yCombobox.setSelectedIndex(1);
zCombobox.setSelectedIndex(2);
- top = pca.getM().rows - 1;
+ pcaModel.updateRc(rc);
+ // rc.invalidate();
+ nuclSetting.setSelected(pcaModel.isNucleotide());
+ protSetting.setSelected(!pcaModel.isNucleotide());
+ jvVersionSetting.setSelected(pcaModel.isJvCalcMode());
+ top = pcaModel.getTop();
- Vector points = new Vector();
- float[][] scores = pca.getComponents(top - 1, top - 2, top - 3, 100);
+ } catch (OutOfMemoryError er)
+ {
+ new OOMWarning("calculating PCA", er);
+ return;
+ } finally
+ {
+ progress.setProgressBar("", progId);
+ }
+ calcSettings.setEnabled(true);
+ repaint();
+ if (getParent() == null)
+ {
+ addKeyListener(rc);
+ Desktop.addInternalFrame(this, MessageManager.getString("label.principal_component_analysis"), 475,
+ 450);
+ }
+ }
- for (int i = 0; i < pca.getM().rows; i++)
- {
- SequencePoint sp = new SequencePoint(seqs[i], scores[i]);
- points.addElement(sp);
- }
+ @Override
+ protected void nuclSetting_actionPerfomed(ActionEvent arg0)
+ {
+ if (!pcaModel.isNucleotide())
+ {
+ pcaModel.setNucleotide(true);
+ pcaModel.setScore_matrix("DNA");
+ Thread worker = new Thread(this);
+ worker.start();
+ }
- rc.setPoints(points, pca.getM().rows);
- rc.repaint();
+ }
- addKeyListener(rc);
+ @Override
+ protected void protSetting_actionPerfomed(ActionEvent arg0)
+ {
- } catch (OutOfMemoryError er)
+ if (pcaModel.isNucleotide())
{
- new OOMWarning("calculating PCA", er);
-
+ pcaModel.setNucleotide(false);
+ pcaModel.setScore_matrix("BLOSUM62");
+ Thread worker = new Thread(this);
+ worker.start();
}
+ }
+ @Override
+ protected void jvVersionSetting_actionPerfomed(ActionEvent arg0)
+ {
+ pcaModel.setJvCalcMode(jvVersionSetting.isSelected());
+ Thread worker = new Thread(this);
+ worker.start();
}
/**
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];
- }
-
+ pcaModel.updateRcView(dim1, dim2, dim3);
rc.img = null;
rc.rotmat.setIdentity();
rc.initAxes();
public void outputValues_actionPerformed(ActionEvent e)
{
CutAndPasteTransfer cap = new CutAndPasteTransfer();
- try {
- cap.setText(pca.getDetails());
- Desktop.addInternalFrame(cap, "PCA details", 500, 500);
+ try
+ {
+ cap.setText(pcaModel.getDetails());
+ Desktop.addInternalFrame(cap, MessageManager.getString("label.pca_details"), 500, 500);
} catch (OutOfMemoryError oom)
{
- new OOMWarning("opening PCA details",oom);
+ new OOMWarning("opening PCA details", oom);
cap.dispose();
}
}
{
// this was cut'n'pasted from the equivalent TreePanel method - we should
// make this an abstract function of all jalview analysis windows
- if (seqstrings == null)
+ if (pcaModel.getSeqtrings() == null)
{
jalview.bin.Cache.log
.info("Unexpected call to originalSeqData_actionPerformed - should have hidden this menu action.");
{
}
;
- Object[] alAndColsel = seqstrings.getAlignmentAndColumnSelection(gc);
+ Object[] alAndColsel = pcaModel.getSeqtrings()
+ .getAlignmentAndColumnSelection(gc);
if (alAndColsel != null && alAndColsel[0] != null)
{
// af.addSortByOrderMenuItem(ServiceName + " Ordering",
// msaorder);
- Desktop.addInternalFrame(af, "Original Data for " + this.title,
+ Desktop.addInternalFrame(af, MessageManager.formatMessage("label.original_data_for_params", new String[]{this.title}),
AlignFrame.DEFAULT_WIDTH, AlignFrame.DEFAULT_HEIGHT);
}
}
else
{
im = new jalview.util.ImageMaker(this, jalview.util.ImageMaker.EPS,
- "Make EPS file from PCA", width, height, null, this
- .getTitle());
+ "Make EPS file from PCA", width, height, null,
+ this.getTitle());
}
if (im.getGraphics() != null)
}
}
+
public void viewMenu_menuSelected()
{
buildAssociatedViewMenu();
associateViewsMenu.add(itemf);
}
- /* (non-Javadoc)
- * @see jalview.jbgui.GPCAPanel#outputPoints_actionPerformed(java.awt.event.ActionEvent)
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * jalview.jbgui.GPCAPanel#outputPoints_actionPerformed(java.awt.event.ActionEvent
+ * )
*/
protected void outputPoints_actionPerformed(ActionEvent e)
{
CutAndPasteTransfer cap = new CutAndPasteTransfer();
- try {
- cap.setText(getPointsasCsv(false));
- Desktop.addInternalFrame(cap, "Points for "+getTitle(), 500, 500);
+ try
+ {
+ cap.setText(pcaModel.getPointsasCsv(false,
+ xCombobox.getSelectedIndex(), yCombobox.getSelectedIndex(),
+ zCombobox.getSelectedIndex()));
+ Desktop.addInternalFrame(cap, MessageManager.formatMessage("label.points_for_params", new String[]{this.getTitle()}), 500, 500);
} catch (OutOfMemoryError oom)
{
- new OOMWarning("exporting PCA points",oom);
+ new OOMWarning("exporting PCA points", oom);
cap.dispose();
}
}
- private String getPointsasCsv(boolean transformed)
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * jalview.jbgui.GPCAPanel#outputProjPoints_actionPerformed(java.awt.event
+ * .ActionEvent)
+ */
+ protected void outputProjPoints_actionPerformed(ActionEvent e)
{
- StringBuffer csv = new StringBuffer();
- csv.append("\"Sequence\"");
- if (transformed) {
- csv.append(",");
- csv.append(xCombobox.getSelectedIndex());
- csv.append(",");
- csv.append(yCombobox.getSelectedIndex());
- csv.append(",");
- csv.append(zCombobox.getSelectedIndex());
- } else {
- for (int d=1,dmax=pca.component(1).length;d<=dmax;d++)
+ CutAndPasteTransfer cap = new CutAndPasteTransfer();
+ try
+ {
+ cap.setText(pcaModel.getPointsasCsv(true,
+ xCombobox.getSelectedIndex(), yCombobox.getSelectedIndex(),
+ zCombobox.getSelectedIndex()));
+ Desktop.addInternalFrame(cap, MessageManager.formatMessage("label.transformed_points_for_params", new String[]{this.getTitle()}),
+ 500, 500);
+ } catch (OutOfMemoryError oom)
+ {
+ new OOMWarning("exporting transformed PCA points", oom);
+ cap.dispose();
+ }
+ }
+
+ // methods for implementing IProgressIndicator
+ // need to refactor to a reusable stub class
+ Hashtable progressBars, progressBarHandlers;
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see jalview.gui.IProgressIndicator#setProgressBar(java.lang.String, long)
+ */
+ @Override
+ public void setProgressBar(String message, long id)
+ {
+ if (progressBars == null)
+ {
+ progressBars = new Hashtable();
+ progressBarHandlers = new Hashtable();
+ }
+
+ JPanel progressPanel;
+ Long lId = new Long(id);
+ GridLayout layout = (GridLayout) statusPanel.getLayout();
+ if (progressBars.get(lId) != null)
+ {
+ progressPanel = (JPanel) progressBars.get(new Long(id));
+ statusPanel.remove(progressPanel);
+ progressBars.remove(lId);
+ progressPanel = null;
+ if (message != null)
{
- csv.append(","+d);
+ statusBar.setText(message);
}
+ if (progressBarHandlers.contains(lId))
+ {
+ progressBarHandlers.remove(lId);
+ }
+ layout.setRows(layout.getRows() - 1);
}
- csv.append("\n");
- for (int s=0;s<seqs.length;s++)
+ else
{
- csv.append("\""+seqs[s].getName()+"\"");
- double fl[];
- if (!transformed) {
- // output pca in correct order
- fl = pca.component(s);
- for (int d=fl.length-1; d>=0;d--)
- {
- csv.append(",");
- csv.append(fl[d]);
- }
- } else {
- // output current x,y,z coords for points
- fl = rc.getPointPosition(s);
- for (int d=0; d<fl.length;d++)
+ progressPanel = new JPanel(new BorderLayout(10, 5));
+
+ JProgressBar progressBar = new JProgressBar();
+ progressBar.setIndeterminate(true);
+
+ progressPanel.add(new JLabel(message), BorderLayout.WEST);
+ progressPanel.add(progressBar, BorderLayout.CENTER);
+
+ layout.setRows(layout.getRows() + 1);
+ statusPanel.add(progressPanel);
+
+ progressBars.put(lId, progressPanel);
+ }
+ // update GUI
+ // setMenusForViewport();
+ validate();
+ }
+
+ @Override
+ public void registerHandler(final long id,
+ final IProgressIndicatorHandler handler)
+ {
+ if (progressBarHandlers == null || !progressBars.contains(new Long(id)))
+ {
+ throw new Error(
+ "call setProgressBar before registering the progress bar's handler.");
+ }
+ progressBarHandlers.put(new Long(id), handler);
+ final JPanel progressPanel = (JPanel) progressBars.get(new Long(id));
+ if (handler.canCancel())
+ {
+ JButton cancel = new JButton(MessageManager.getString("action.cancel"));
+ final IProgressIndicator us = this;
+ cancel.addActionListener(new ActionListener()
+ {
+
+ @Override
+ public void actionPerformed(ActionEvent e)
{
- csv.append(",");
- csv.append(fl[d]);
+ handler.cancelActivity(id);
+ us.setProgressBar(
+ "Cancelled "
+ + ((JLabel) progressPanel.getComponent(0))
+ .getText(), id);
}
- }
- csv.append("\n");
+ });
+ progressPanel.add(cancel, BorderLayout.EAST);
}
- return csv.toString();
}
- /* (non-Javadoc)
- * @see jalview.jbgui.GPCAPanel#outputProjPoints_actionPerformed(java.awt.event.ActionEvent)
+ /**
+ *
+ * @return true if any progress bars are still active
*/
- protected void outputProjPoints_actionPerformed(ActionEvent e)
+ @Override
+ public boolean operationInProgress()
{
- CutAndPasteTransfer cap = new CutAndPasteTransfer();
- try {
- cap.setText(getPointsasCsv(true));
- Desktop.addInternalFrame(cap, "Transformed points for "+getTitle(), 500, 500);
- } catch (OutOfMemoryError oom)
+ if (progressBars != null && progressBars.size() > 0)
{
- new OOMWarning("exporting transformed PCA points",oom);
- cap.dispose();
+ return true;
}
+ return false;
}
+ @Override
+ protected void resetButton_actionPerformed(ActionEvent e)
+ {
+ int t = top;
+ top = 0; // ugly - prevents dimensionChanged events from being processed
+ xCombobox.setSelectedIndex(0);
+ yCombobox.setSelectedIndex(1);
+ top = t;
+ zCombobox.setSelectedIndex(2);
+ }
}