import jalview.analysis.*;
import jalview.datamodel.*;
import jalview.jbgui.*;
+import jalview.viewmodel.PCAModel;
/**
* DOCUMENT ME!
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 nucleotide=false;
+ PCAModel pcaModel;
+ int top=0;
/**
* Creates a new PCAPanel object.
boolean sameLength = true;
- seqstrings = av.getAlignmentView(av.getSelectionGroup() != null);
- nucleotide=av.getAlignment().isNucleotide();
+ AlignmentView seqstrings = av.getAlignmentView(av.getSelectionGroup() != null);
+ boolean nucleotide=av.getAlignment().isNucleotide();
+ SequenceI[] seqs;
if (av.getSelectionGroup() == null)
{
seqs = av.getAlignment().getSequencesArray();
return;
}
-
+ 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);
try
{
calcSettings.setEnabled(false);
-
- pca = new PCA(seqstrings.getSequenceStrings(' '), nucleotide);
- 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);
+
+ pcaModel.updateRc(rc);
// rc.invalidate();
- nuclSetting.setSelected(nucleotide);
- protSetting.setSelected(!nucleotide);
+ nuclSetting.setSelected(pcaModel.isNucleotide());
+ protSetting.setSelected(!pcaModel.isNucleotide());
+ top=pcaModel.getTop();
} catch (OutOfMemoryError er)
{
@Override
protected void nuclSetting_actionPerfomed(ActionEvent arg0)
{
- if (!nucleotide)
+ if (!pcaModel.isNucleotide())
{
- nucleotide=true;
+ pcaModel.setNucleotide(true);
Thread worker = new Thread(this);
worker.start();
}
protected void protSetting_actionPerfomed(ActionEvent arg0)
{
- if (nucleotide)
+ if (pcaModel.isNucleotide())
{
- nucleotide=false;
+ pcaModel.setNucleotide(false);
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();
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)
--- /dev/null
+package jalview.viewmodel;
+
+import java.util.Vector;
+
+import jalview.analysis.PCA;
+import jalview.datamodel.AlignmentView;
+import jalview.datamodel.SequenceI;
+import jalview.datamodel.SequencePoint;
+import jalview.api.RotatableCanvasI;
+
+public class PCAModel
+{
+
+ public PCAModel(AlignmentView seqstrings2, SequenceI[] seqs2,
+ boolean nucleotide2)
+ {
+ seqstrings=seqstrings2;
+ seqs=seqs2;
+ nucleotide=nucleotide2;
+ }
+
+ PCA pca;
+
+ int top;
+
+ AlignmentView seqstrings;
+
+ SequenceI[] seqs;
+
+ /**
+ * use the identity matrix for calculating similarity between sequences.
+ */
+ private boolean nucleotide=false;
+
+ private Vector<SequencePoint> points;
+
+ public void run()
+ {
+
+ pca = new PCA(seqstrings.getSequenceStrings(' '), nucleotide);
+ 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);
+ }
+ }
+
+ top = pca.getM().rows - 1;
+
+ points = new Vector<SequencePoint>();
+ 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);
+ }
+
+ }
+
+ public void updateRc(RotatableCanvasI rc)
+ {
+ rc.setPoints(points, pca.getM().rows);
+ }
+
+ public boolean isNucleotide()
+ {
+ return nucleotide;
+ }
+ public void setNucleotide(boolean nucleotide)
+ {
+ this.nucleotide=nucleotide;
+ }
+
+ /**
+ *
+ *
+ * @return index of principle dimension of PCA
+ */
+ public int getTop()
+ {
+ return top;
+ }
+
+ /**
+ * update the 2d coordinates for the list of points to the given dimensions
+ * Principal dimension is getTop(). Next greated eigenvector is getTop()-1.
+ * Note - pca.getComponents starts counting the spectrum from zero rather than one, so getComponents(dimN ...) == updateRcView(dimN+1 ..)
+ * @param dim1
+ * @param dim2
+ * @param dim3
+ */
+ public void updateRcView(int dim1, int dim2, int dim3)
+ {
+ float[][] scores = pca.getComponents(dim1-1, dim2-1, dim3-1, 100);
+
+ for (int i = 0; i < pca.getM().rows; i++)
+ {
+ ((SequencePoint) points.elementAt(i)).coord = scores[i];
+ }
+ }
+
+ public String getDetails()
+ {
+ return pca.getDetails();
+ }
+
+ public AlignmentView getSeqtrings()
+ {
+ return seqstrings;
+ }
+ public String getPointsasCsv(boolean transformed, int xdim, int ydim, int zdim)
+ {
+ StringBuffer csv = new StringBuffer();
+ csv.append("\"Sequence\"");
+ if (transformed)
+ {
+ csv.append(",");
+ csv.append(xdim);
+ csv.append(",");
+ csv.append(ydim);
+ csv.append(",");
+ csv.append(zdim);
+ }
+ 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 = getPointPosition(s);
+ for (int d = 0; d < fl.length; d++)
+ {
+ csv.append(",");
+ csv.append(fl[d]);
+ }
+ }
+ csv.append("\n");
+ }
+ return csv.toString();
+ }
+
+ /**
+ *
+ * @return x,y,z positions of point s (index into points) under current
+ * transform.
+ */
+ public double[] getPointPosition(int s)
+ {
+ double pts[] = new double[3];
+ float[] p = points.elementAt(s).coord;
+ pts[0] = p[0];
+ pts[1] = p[1];
+ pts[2] = p[2];
+ return pts;
+ }
+
+}