/*
* Jalview - A Sequence Alignment Editor and Viewer (Version 2.7)
- * Copyright (C) 2011 J Procter, AM Waterhouse, G Barton, M Clamp, S Searle
+ * Copyright (C) 2011 J Procter, AM Waterhouse, J Engelhardt, LM Lui, G Barton, M Clamp, S Searle
*
* This file is part of Jalview.
*
import jalview.analysis.*;
import jalview.datamodel.*;
import jalview.jbgui.*;
+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;
-
- SequenceI[] seqs;
-
- /**
- * use the identity matrix for calculating similarity between sequences.
- */
- private boolean useidentity=false;
+ PCAModel pcaModel;
+ int top=0;
/**
* Creates a new PCAPanel object.
boolean sameLength = true;
- seqstrings = av.getAlignmentView(av.getSelectionGroup() != null);
- useidentity=av.getAlignment().isNucleotide();
+ AlignmentView seqstrings = av.getAlignmentView(av.getSelectionGroup() != null);
+ boolean nucleotide=av.getAlignment().isNucleotide();
+ SequenceI[] seqs;
if (av.getSelectionGroup() == null)
{
- 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);
this.getContentPane().add(rc, BorderLayout.CENTER);
Thread worker = new Thread(this);
*/
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
{
calcSettings.setEnabled(false);
- pca = new PCA(seqstrings.getSequenceStrings(' '), useidentity);
- 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);
- }
- }
-
+ pcaModel.run();
// ////////////////
xCombobox.setSelectedIndex(0);
yCombobox.setSelectedIndex(1);
zCombobox.setSelectedIndex(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();
-
- addKeyListener(rc);
+
+ pcaModel.updateRc(rc);
+ // rc.invalidate();
+ nuclSetting.setSelected(pcaModel.isNucleotide());
+ protSetting.setSelected(!pcaModel.isNucleotide());
+ top=pcaModel.getTop();
+ jvVersionSetting.setSelected(pcaModel.isJvCalcMode());
} 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, "Principal component analysis", 475, 450);
+ }
}
@Override
protected void nuclSetting_actionPerfomed(ActionEvent arg0)
{
- useidentity=true;
+ if (!pcaModel.isNucleotide())
+ {
+ pcaModel.setNucleotide(true);
Thread worker = new Thread(this);
worker.start();
+ }
+
}
@Override
protected void protSetting_actionPerfomed(ActionEvent arg0)
{
- useidentity=false;
+
+ if (pcaModel.isNucleotide())
+ {
+ pcaModel.setNucleotide(false);
+ 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();
}
+
/**
* DOCUMENT ME!
*/
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();
CutAndPasteTransfer cap = new CutAndPasteTransfer();
try
{
- cap.setText(pca.getDetails());
+ cap.setText(pcaModel.getDetails());
Desktop.addInternalFrame(cap, "PCA details", 500, 500);
} catch (OutOfMemoryError oom)
{
{
// 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)
{
CutAndPasteTransfer cap = new CutAndPasteTransfer();
try
{
- cap.setText(getPointsasCsv(false));
+ cap.setText(pcaModel.getPointsasCsv(false, xCombobox.getSelectedIndex(), yCombobox.getSelectedIndex(), zCombobox.getSelectedIndex()));
Desktop.addInternalFrame(cap, "Points for " + getTitle(), 500, 500);
} catch (OutOfMemoryError oom)
{
}
}
- private String getPointsasCsv(boolean transformed)
- {
- 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++)
- {
- csv.append("," + d);
- }
- }
- csv.append("\n");
- for (int s = 0; s < seqs.length; s++)
- {
- 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++)
- {
- csv.append(",");
- csv.append(fl[d]);
- }
- }
- csv.append("\n");
- }
- return csv.toString();
- }
+
/*
* (non-Javadoc)
CutAndPasteTransfer cap = new CutAndPasteTransfer();
try
{
- cap.setText(getPointsasCsv(true));
+ cap.setText(pcaModel.getPointsasCsv(true, xCombobox.getSelectedIndex(), yCombobox.getSelectedIndex(), zCombobox.getSelectedIndex()));
Desktop.addInternalFrame(cap, "Transformed points for " + getTitle(),
500, 500);
} catch (OutOfMemoryError oom)
}
}
+ // 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)
+ {
+ statusBar.setText(message);
+ }
+ if (progressBarHandlers.contains(lId))
+ {
+ progressBarHandlers.remove(lId);
+ }
+ layout.setRows(layout.getRows() - 1);
+ }
+ else
+ {
+ 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("Cancel");
+ final IProgressIndicator us = this;
+ cancel.addActionListener(new ActionListener()
+ {
+
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ handler.cancelActivity(id);
+ us.setProgressBar(
+ "Cancelled "
+ + ((JLabel) progressPanel.getComponent(0))
+ .getText(), id);
+ }
+ });
+ progressPanel.add(cancel, BorderLayout.EAST);
+ }
+ }
+
+ /**
+ *
+ * @return true if any progress bars are still active
+ */
+ @Override
+ public boolean operationInProgress()
+ {
+ if (progressBars != null && progressBars.size() > 0)
+ {
+ 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);
+ }
}