JAL-1632 add score model params to PCAModel and PCA constructors
authorgmungoc <g.m.carstairs@dundee.ac.uk>
Mon, 27 Feb 2017 10:25:53 +0000 (10:25 +0000)
committergmungoc <g.m.carstairs@dundee.ac.uk>
Mon, 27 Feb 2017 10:25:53 +0000 (10:25 +0000)
src/jalview/analysis/PCA.java
src/jalview/appletgui/PCAPanel.java
src/jalview/gui/PCAPanel.java
src/jalview/viewmodel/PCAModel.java

index 1f923b1..43f2161 100755 (executable)
@@ -20,9 +20,9 @@
  */
 package jalview.analysis;
 
-import jalview.analysis.scoremodels.SimilarityParams;
 import jalview.api.analysis.DistanceScoreModelI;
 import jalview.api.analysis.ScoreModelI;
+import jalview.api.analysis.SimilarityParamsI;
 import jalview.api.analysis.SimilarityScoreModelI;
 import jalview.datamodel.AlignmentView;
 import jalview.math.MatrixI;
@@ -47,12 +47,15 @@ public class PCA implements Runnable
   private AlignmentView seqs;
 
   private ScoreModelI scoreModel;
+  
+  private SimilarityParamsI similarityParams;
 
-  public PCA(AlignmentView s, ScoreModelI sm)
+  public PCA(AlignmentView s, ScoreModelI sm, SimilarityParamsI options)
   {
     this.seqs = s;
-
-    scoreModel = sm;
+    this.similarityParams = options;
+    this.scoreModel = sm;
+    
     details.append("PCA calculation using " + sm.getName()
             + " sequence similarity matrix\n========\n\n");
   }
@@ -229,16 +232,15 @@ public class PCA implements Runnable
   MatrixI computeSimilarity(AlignmentView av)
   {
     MatrixI result = null;
-    // TODO pass choice of params from GUI in constructo
     if (scoreModel instanceof SimilarityScoreModelI)
     {
       result = ((SimilarityScoreModelI) scoreModel).findSimilarities(av,
-              SimilarityParams.SeqSpace);
+              similarityParams);
     }
     else if (scoreModel instanceof DistanceScoreModelI)
     {
       result = ((DistanceScoreModelI) scoreModel).findDistances(av,
-              SimilarityParams.SeqSpace);
+              similarityParams);
       result.reverseRange(false);
     }
     else
index c5ec0c1..21668d3 100644 (file)
@@ -20,6 +20,7 @@
  */
 package jalview.appletgui;
 
+import jalview.analysis.scoremodels.SimilarityParams;
 import jalview.datamodel.Alignment;
 import jalview.datamodel.AlignmentView;
 import jalview.datamodel.ColumnSelection;
@@ -99,7 +100,8 @@ public class PCAPanel extends EmbmenuFrame implements Runnable,
         return;
       }
     }
-    pcaModel = new PCAModel(seqstrings, seqs, nucleotide);
+    pcaModel = new PCAModel(seqstrings, seqs, nucleotide,
+            SimilarityParams.SeqSpace);
 
     rc = new RotatableCanvas(av);
     embedMenuIfNeeded(rc);
@@ -116,6 +118,7 @@ public class PCAPanel extends EmbmenuFrame implements Runnable,
   /**
    * DOCUMENT ME!
    */
+  @Override
   public void run()
   {
     // TODO progress indicator
@@ -164,6 +167,7 @@ public class PCAPanel extends EmbmenuFrame implements Runnable,
     rc.paint(rc.getGraphics());
   }
 
+  @Override
   public void actionPerformed(ActionEvent evt)
   {
     if (evt.getSource() == inputData)
@@ -183,6 +187,7 @@ public class PCAPanel extends EmbmenuFrame implements Runnable,
     }
   }
 
+  @Override
   public void itemStateChanged(ItemEvent evt)
   {
     if (evt.getSource() == xCombobox)
index 3f0c37f..57a7422 100644 (file)
@@ -21,6 +21,7 @@
 package jalview.gui;
 
 import jalview.analysis.scoremodels.ScoreModels;
+import jalview.analysis.scoremodels.SimilarityParams;
 import jalview.api.analysis.ScoreModelI;
 import jalview.api.analysis.ViewBasedAnalysisI;
 import jalview.bin.Cache;
@@ -83,15 +84,23 @@ public class PCAPanel extends GPCAPanel implements Runnable,
    * @param s
    *          DOCUMENT ME!
    */
-  public PCAPanel(AlignmentPanel ap)
+  public PCAPanel(AlignmentPanel alignPanel)
   {
     super();
-    this.av = ap.av;
-    this.ap = ap;
+    this.av = alignPanel.av;
+    this.ap = alignPanel;
 
     progressBar = new ProgressBar(statusPanel, statusBar);
 
-    boolean sameLength = true;
+    addInternalFrameListener(new InternalFrameAdapter()
+    {
+      @Override
+      public void internalFrameClosed(InternalFrameEvent e)
+      {
+        close_actionPerformed();
+      }
+    });
+
     boolean selected = av.getSelectionGroup() != null
             && av.getSelectionGroup().getSize() > 0;
     AlignmentView seqstrings = av.getAlignmentView(selected);
@@ -105,19 +114,10 @@ public class PCAPanel extends GPCAPanel implements Runnable,
     {
       seqs = av.getSelectionGroup().getSequencesInOrder(av.getAlignment());
     }
-    SeqCigar sq[] = seqstrings.getSequences();
-    int length = sq[0].getWidth();
 
-    for (int i = 0; i < seqs.length; i++)
-    {
-      if (sq[i].getWidth() != length)
-      {
-        sameLength = false;
-        break;
-      }
-    }
-
-    if (!sameLength)
+    // TODO can we allow PCA on unaligned data given choice of
+    // similarity measure parameters?
+    if (!checkAligned(seqstrings))
     {
       JvOptionPane.showMessageDialog(Desktop.desktop,
               MessageManager.getString("label.pca_sequences_not_aligned"),
@@ -127,25 +127,39 @@ public class PCAPanel extends GPCAPanel implements Runnable,
       return;
     }
 
-    addInternalFrameListener(new InternalFrameAdapter()
-    {
-      @Override
-      public void internalFrameClosed(InternalFrameEvent e)
-      {
-        close_actionPerformed();
-      }
-    });
-
-    pcaModel = new PCAModel(seqstrings, seqs, nucleotide);
+    pcaModel = new PCAModel(seqstrings, seqs, nucleotide,
+            SimilarityParams.SeqSpace);
     PaintRefresher.Register(this, av.getSequenceSetId());
 
-    rc = new RotatableCanvas(ap);
+    rc = new RotatableCanvas(alignPanel);
     this.getContentPane().add(rc, BorderLayout.CENTER);
     Thread worker = new Thread(this);
     worker.start();
   }
 
   /**
+   * Answers true if all sequences have the same aligned length, else false
+   * 
+   * @param seqstrings
+   * @return
+   */
+  protected boolean checkAligned(AlignmentView seqstrings)
+  {
+    SeqCigar sq[] = seqstrings.getSequences();
+    int length = sq[0].getWidth();
+    boolean sameLength = true;
+    for (int i = 0; i < sq.length; i++)
+    {
+      if (sq[i].getWidth() != length)
+      {
+        sameLength = false;
+        break;
+      }
+    }
+    return sameLength;
+  }
+
+  /**
    * Ensure references to potentially very large objects (the PCA matrices) are
    * nulled when the frame is closed
    */
index fa4b747..324c69a 100644 (file)
@@ -24,6 +24,7 @@ import jalview.analysis.PCA;
 import jalview.analysis.scoremodels.ScoreModels;
 import jalview.api.RotatableCanvasI;
 import jalview.api.analysis.ScoreModelI;
+import jalview.api.analysis.SimilarityParamsI;
 import jalview.datamodel.AlignmentView;
 import jalview.datamodel.SequenceI;
 import jalview.datamodel.SequencePoint;
@@ -51,13 +52,26 @@ public class PCAModel
 
   private boolean jvCalcMode = true;
 
-  public PCAModel(AlignmentView seqstrings2, SequenceI[] seqs2,
-          boolean nucleotide2)
+  private SimilarityParamsI similarityParams;
+
+  /**
+   * Constructor given sequence data and score calculation parameter options.
+   * The initial state is to compute PCA using a default score model (BLOSUM62
+   * for peptide, DNA for nucleotide).
+   * 
+   * @param seqData
+   * @param sqs
+   * @param nuc
+   * @param params
+   */
+  public PCAModel(AlignmentView seqData, SequenceI[] sqs, boolean nuc,
+          SimilarityParamsI params)
   {
-    seqstrings = seqstrings2;
-    seqs = seqs2;
-    nucleotide = nucleotide2;
+    seqstrings = seqData;
+    seqs = sqs;
+    nucleotide = nuc;
     scoreModel = ScoreModels.getInstance().getDefaultModel(!nucleotide);
+    similarityParams = params;
   }
 
   public boolean isJvCalcMode()
@@ -67,7 +81,7 @@ public class PCAModel
 
   public void run()
   {
-    pca = new PCA(seqstrings, scoreModel);
+    pca = new PCA(seqstrings, scoreModel, similarityParams);
     pca.setJvCalcMode(jvCalcMode);
     pca.run();