JAL-1632 refactored NJTree constructor to include SimilarityParams
authorgmungoc <g.m.carstairs@dundee.ac.uk>
Mon, 27 Feb 2017 10:05:50 +0000 (10:05 +0000)
committergmungoc <g.m.carstairs@dundee.ac.uk>
Mon, 27 Feb 2017 10:05:50 +0000 (10:05 +0000)
src/jalview/analysis/NJTree.java
src/jalview/appletgui/TreePanel.java
src/jalview/gui/AlignFrame.java
src/jalview/gui/SeqPanel.java
src/jalview/gui/TreePanel.java

index 4ee0be9..cc0e473 100644 (file)
  */
 package jalview.analysis;
 
-import jalview.analysis.scoremodels.ScoreModels;
 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.datamodel.BinaryNode;
@@ -35,6 +35,7 @@ import jalview.datamodel.SequenceI;
 import jalview.datamodel.SequenceNode;
 import jalview.io.NewickFile;
 import jalview.math.MatrixI;
+import jalview.viewmodel.AlignmentViewport;
 
 import java.util.Enumeration;
 import java.util.List;
@@ -48,9 +49,6 @@ import java.util.Vector;
  */
 public class NJTree
 {
-  /*
-   * 'methods'
-   */
   public static final String AVERAGE_DISTANCE = "AV";
 
   public static final String NEIGHBOUR_JOINING = "NJ";
@@ -59,10 +57,12 @@ public class NJTree
 
   Vector<Cluster> cluster;
 
-  SequenceI[] sequence;
+  SequenceI[] sequences;
 
-  // SequenceData is a string representation of what the user
-  // sees. The display may contain hidden columns.
+  /* 
+   * SequenceData is a string representation of what the user
+   * sees. The display may contain hidden columns.
+   */
   public AlignmentView seqData = null;
 
   int[] done;
@@ -71,7 +71,7 @@ public class NJTree
 
   int noClus;
 
-  MatrixI distance;
+  MatrixI distances;
 
   int mini;
 
@@ -143,7 +143,7 @@ public class NJTree
    */
   public NJTree(SequenceI[] seqs, NewickFile treefile)
   {
-    this.sequence = seqs;
+    this.sequences = seqs;
     top = treefile.getTree();
 
     /**
@@ -214,71 +214,101 @@ public class NJTree
   }
 
   /**
-   * Creates a new NJTree object.
+   * Constructor given a viewport, tree type and score model
    * 
-   * @param sequence
-   *          DOCUMENT ME!
+   * @param av
+   *          the current alignment viewport
    * @param treeType
-   *          DOCUMENT ME!
-   * @param modelType
-   *          DOCUMENT ME!
-   * @param start
-   *          DOCUMENT ME!
-   * @param end
-   *          DOCUMENT ME!
+   *          NJ or AV
+   * @param sm
+   *          a distance or similarity score model to use to compute the tree
+   * @param scoreParameters TODO
    */
-  public NJTree(SequenceI[] sqs, AlignmentView seqView, String treeType,
-          String modelType, ScoreModelI sm, int start, int end)
+  public NJTree(AlignmentViewport av, String treeType, ScoreModelI sm, SimilarityParamsI scoreParameters)
   {
-    this.sequence = sqs;
-    this.node = new Vector<SequenceNode>();
+    // TODO handle type "FromFile" more elegantly
     if (!(treeType.equals(NEIGHBOUR_JOINING)))
     {
       treeType = AVERAGE_DISTANCE;
     }
     this.type = treeType;
-    this.pwtype = modelType;
+    int start, end;
+    boolean selview = av.getSelectionGroup() != null
+            && av.getSelectionGroup().getSize() > 1;
+    AlignmentView seqStrings = av.getAlignmentView(selview);
+    if (!selview)
+    {
+      start = 0;
+      end = av.getAlignment().getWidth();
+      this.sequences = av.getAlignment().getSequencesArray();
+    }
+    else
+    {
+      start = av.getSelectionGroup().getStartRes();
+      end = av.getSelectionGroup().getEndRes() + 1;
+      this.sequences = av.getSelectionGroup().getSequencesInOrder(
+              av.getAlignment());
+    }
+
+    init(seqStrings, start, end);
+
+    computeTree(sm, scoreParameters);
+  }
+
+  void init(AlignmentView seqView, int start, int end)
+  {
+    this.node = new Vector<SequenceNode>();
     if (seqView != null)
     {
       this.seqData = seqView;
     }
     else
     {
-      SeqCigar[] seqs = new SeqCigar[sequence.length];
-      for (int i = 0; i < sequence.length; i++)
+      SeqCigar[] seqs = new SeqCigar[sequences.length];
+      for (int i = 0; i < sequences.length; i++)
       {
-        seqs[i] = new SeqCigar(sequence[i], start, end);
+        seqs[i] = new SeqCigar(sequences[i], start, end);
       }
       CigarArray sdata = new CigarArray(seqs);
       sdata.addOperation(CigarArray.M, end - start + 1);
       this.seqData = new AlignmentView(sdata, start);
     }
 
-    if (sm == null && !(modelType.equals("PID")))
-    {
-      if (ScoreModels.getInstance().forName(modelType) == null)
-      {
-        modelType = "BLOSUM62";
-      }
-    }
-
-    int i = 0;
+    /*
+     * count the non-null sequences
+     */
+    noseqs = 0;
 
-    done = new int[sequence.length];
+    done = new int[sequences.length];
 
-    while ((i < sequence.length) && (sequence[i] != null))
+    for (SequenceI seq : sequences)
     {
-      done[i] = 0;
-      i++;
+      if (seq != null)
+      {
+        noseqs++;
+      }
     }
+  }
 
-    noseqs = i++;
-
-    // TODO pass choice of params from GUI in constructo
+  /**
+   * Calculates the tree using the given score model and parameters, and the
+   * configured tree type
+   * <p>
+   * If the score model computes pairwise distance scores, then these are used
+   * directly to derive the tree
+   * <p>
+   * If the score model computes similarity scores, then the range of the scores
+   * is reversed to give a distance measure, and this is used to derive the tree
+   * 
+   * @param sm
+   * @param scoreOptions
+   */
+  protected void computeTree(ScoreModelI sm, SimilarityParamsI scoreOptions)
+  {
     if (sm instanceof DistanceScoreModelI)
     {
-      distance = ((DistanceScoreModelI) sm).findDistances(seqData,
-              SimilarityParams.Jalview);
+      distances = ((DistanceScoreModelI) sm).findDistances(seqData,
+              scoreOptions);
     }
     else if (sm instanceof SimilarityScoreModelI)
     {
@@ -288,7 +318,7 @@ public class NJTree
       MatrixI result = ((SimilarityScoreModelI) sm).findSimilarities(
               seqData, SimilarityParams.Jalview);
       result.reverseRange(true);
-      distance = result;
+      distances = result;
     }
 
     makeLeaves();
@@ -468,7 +498,7 @@ public class NJTree
    */
   Cluster joinClusters(int i, int j)
   {
-    double dist = distance.getValue(i, j);
+    double dist = distances.getValue(i, j);
 
     int noi = cluster.elementAt(i).value.length;
     int noj = cluster.elementAt(j).value.length;
@@ -609,7 +639,7 @@ public class NJTree
       {
         // newdist[l] = ((distance[i][l] * noi) + (distance[j][l] * noj))
         // / (noi + noj);
-        newdist[l] = ((distance.getValue(i, l) * noi) + (distance.getValue(
+        newdist[l] = ((distances.getValue(i, l) * noi) + (distances.getValue(
                 j, l) * noj))
                 / (noi + noj);
       }
@@ -623,8 +653,8 @@ public class NJTree
     {
       // distance[i][ii] = newdist[ii];
       // distance[ii][i] = newdist[ii];
-      distance.setValue(i, ii, newdist[ii]);
-      distance.setValue(ii, i, newdist[ii]);
+      distances.setValue(i, ii, newdist[ii]);
+      distances.setValue(ii, i, newdist[ii]);
     }
   }
 
@@ -648,7 +678,7 @@ public class NJTree
       {
         // newdist[l] = ((distance[i][l] + distance[j][l]) - distance[i][j]) /
         // 2;
-        newdist[l] = (distance.getValue(i, l) + distance.getValue(j, l) - distance
+        newdist[l] = (distances.getValue(i, l) + distances.getValue(j, l) - distances
                 .getValue(i, j)) / 2;
       }
       else
@@ -661,8 +691,8 @@ public class NJTree
     {
       // distance[i][ii] = newdist[ii];
       // distance[ii][i] = newdist[ii];
-      distance.setValue(i, ii, newdist[ii]);
-      distance.setValue(ii, i, newdist[ii]);
+      distances.setValue(i, ii, newdist[ii]);
+      distances.setValue(ii, i, newdist[ii]);
     }
   }
 
@@ -685,7 +715,7 @@ public class NJTree
       if ((k != i) && (k != j) && (done[k] != 1))
       {
         // tmp = tmp + distance[i][k];
-        tmp = tmp + distance.getValue(i, k);
+        tmp = tmp + distances.getValue(i, k);
       }
     }
 
@@ -713,7 +743,7 @@ public class NJTree
         if ((done[i] != 1) && (done[j] != 1))
         {
           // float tmp = distance[i][j] - (findr(i, j) + findr(j, i));
-          double tmp = distance.getValue(i, j)
+          double tmp = distances.getValue(i, j)
                   - (findr(i, j) + findr(j, i));
 
           if (tmp < min)
@@ -746,13 +776,13 @@ public class NJTree
         if ((done[i] != 1) && (done[j] != 1))
         {
           // if (distance[i][j] < min)
-          if (distance.getValue(i, j) < min)
+          if (distances.getValue(i, j) < min)
           {
             mini = i;
             minj = j;
 
             // min = distance[i][j];
-            min = distance.getValue(i, j);
+            min = distances.getValue(i, j);
           }
         }
       }
@@ -772,8 +802,8 @@ public class NJTree
     {
       SequenceNode sn = new SequenceNode();
 
-      sn.setElement(sequence[i]);
-      sn.setName(sequence[i].getName());
+      sn.setElement(sequences[i]);
+      sn.setName(sequences[i].getName());
       node.addElement(sn);
 
       int[] value = new int[1];
@@ -1055,7 +1085,7 @@ public class NJTree
     String[] seqdatas = seqData.getSequenceStrings(gapChar);
     for (int i = 0; i < seqdatas.length; i++)
     {
-      sb.append(new jalview.util.Format("%-" + 15 + "s").form(sequence[i]
+      sb.append(new jalview.util.Format("%-" + 15 + "s").form(sequences[i]
               .getName()));
       sb.append(" " + seqdatas[i] + "\n");
     }
index 5b12fa6..7266665 100644 (file)
@@ -22,10 +22,11 @@ package jalview.appletgui;
 
 import jalview.analysis.NJTree;
 import jalview.analysis.scoremodels.ScoreModels;
+import jalview.analysis.scoremodels.SimilarityParams;
 import jalview.api.analysis.ScoreModelI;
 import jalview.api.analysis.ViewBasedAnalysisI;
+import jalview.bin.Cache;
 import jalview.datamodel.Alignment;
-import jalview.datamodel.AlignmentView;
 import jalview.datamodel.ColumnSelection;
 import jalview.datamodel.SequenceI;
 import jalview.io.NewickFile;
@@ -219,40 +220,8 @@ public class TreePanel extends EmbmenuFrame implements ActionListener,
       }
       else
       {
-        int start, end;
-        SequenceI[] seqs;
-        boolean selview = av.getSelectionGroup() != null
-                && av.getSelectionGroup().getSize() > 1;
-        AlignmentView seqStrings = av.getAlignmentView(selview);
-        if (!selview)
-        {
-          start = 0;
-          end = av.getAlignment().getWidth();
-          seqs = av.getAlignment().getSequencesArray();
-        }
-        else
-        {
-          start = av.getSelectionGroup().getStartRes();
-          end = av.getSelectionGroup().getEndRes() + 1;
-          seqs = av.getSelectionGroup().getSequencesInOrder(
-                  av.getAlignment());
-        }
-        ScoreModelI sm = ScoreModels.getInstance().forName(pwtype);
-        if (sm instanceof ViewBasedAnalysisI)
-        {
-          try
-          {
-            sm = sm.getClass().newInstance();
-            ((ViewBasedAnalysisI) sm)
-                    .configureFromAlignmentView(treeCanvas.ap);
-          } catch (Exception q)
-          {
-            System.err.println("Couldn't create a scoremodel instance for "
-                    + sm.getName());
-            q.printStackTrace();
-          }
-        }
-        tree = new NJTree(seqs, seqStrings, type, pwtype, sm, start, end);
+        ScoreModelI sm = configureScoreModel(pwtype);
+        tree = new NJTree(av, type, sm, SimilarityParams.Jalview);
       }
 
       tree.reCount(tree.getTopNode());
@@ -420,4 +389,29 @@ public class TreePanel extends EmbmenuFrame implements ActionListener,
     inputData.addActionListener(this);
   }
 
+  /**
+   * Gets the score model for the given name. If the score model is one that
+   * requires to get state data from the current view, allow it to do so
+   * 
+   * @param sm
+   * @return
+   */
+  protected ScoreModelI configureScoreModel(String modelName)
+  {
+    ScoreModelI sm = ScoreModels.getInstance().forName(modelName);
+    if (sm instanceof ViewBasedAnalysisI)
+    {
+      try
+      {
+        sm = sm.getClass().newInstance();
+        ((ViewBasedAnalysisI) sm).configureFromAlignmentView(treeCanvas.ap);
+      } catch (Exception q)
+      {
+        Cache.log.error("Couldn't create a scoremodel instance for "
+                + sm.getName());
+      }
+    }
+    return sm;
+  }
+
 }
index 1162c53..4fd80b2 100644 (file)
@@ -3983,12 +3983,6 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
     return ShowNewickTree(nf, title, 600, 500, 4, 5);
   }
 
-  public TreePanel ShowNewickTree(NewickFile nf, String title,
-          AlignmentView input)
-  {
-    return ShowNewickTree(nf, title, input, 600, 500, 4, 5);
-  }
-
   public TreePanel ShowNewickTree(NewickFile nf, String title, int w,
           int h, int x, int y)
   {
index 37b4852..c83dd16 100644 (file)
@@ -1668,7 +1668,7 @@ public class SeqPanel extends JPanel implements MouseListener,
    * 
    * @param evt
    * @param res
-   * @param sequence
+   * @param sequences
    */
   void showPopupMenu(MouseEvent evt)
   {
index 74dd29a..857e77c 100755 (executable)
@@ -23,6 +23,7 @@ package jalview.gui;
 import jalview.analysis.AlignmentSorter;
 import jalview.analysis.NJTree;
 import jalview.analysis.scoremodels.ScoreModels;
+import jalview.analysis.scoremodels.SimilarityParams;
 import jalview.api.analysis.ScoreModelI;
 import jalview.api.analysis.ViewBasedAnalysisI;
 import jalview.bin.Cache;
@@ -300,9 +301,8 @@ public class TreePanel extends GTreePanel
           seqs = av.getSelectionGroup().getSequencesInOrder(
                   av.getAlignment());
         }
-        ScoreModelI sm = ScoreModels.getInstance().forName(pwtype);
-        sm = configureScoreModel(sm);
-        tree = new NJTree(seqs, seqStrings, type, pwtype, sm, start, end);
+        ScoreModelI sm = configureScoreModel(pwtype);
+        tree = new NJTree(av, type, sm, SimilarityParams.Jalview);
         showDistances(true);
       }
 
@@ -883,14 +883,15 @@ public class TreePanel extends GTreePanel
   }
 
   /**
-   * If the score model is one that requires to get state data from the current
-   * view, allow it to do so
+   * Gets the score model for the given name. If the score model is one that
+   * requires to get state data from the current view, allow it to do so
    * 
    * @param sm
    * @return
    */
-  protected ScoreModelI configureScoreModel(ScoreModelI sm)
+  protected ScoreModelI configureScoreModel(String modelName)
   {
+    ScoreModelI sm = ScoreModels.getInstance().forName(modelName);
     if (sm instanceof ViewBasedAnalysisI)
     {
       try