JAL-1632 first cut of Tree chooser dialog and ScoreModels singleton
authorgmungoc <g.m.carstairs@dundee.ac.uk>
Mon, 13 Feb 2017 09:01:54 +0000 (09:01 +0000)
committergmungoc <g.m.carstairs@dundee.ac.uk>
Mon, 13 Feb 2017 09:01:54 +0000 (09:01 +0000)
12 files changed:
resources/lang/Messages.properties
src/jalview/analysis/AlignSeq.java
src/jalview/analysis/PCA.java
src/jalview/analysis/scoremodels/ScoreMatrix.java [moved from src/jalview/schemes/ScoreMatrix.java with 96% similarity]
src/jalview/analysis/scoremodels/ScoreModels.java [new file with mode: 0644]
src/jalview/api/analysis/ScoreModelI.java
src/jalview/datamodel/BinarySequence.java
src/jalview/gui/AlignFrame.java
src/jalview/gui/TreeChooser.java [new file with mode: 0644]
src/jalview/jbgui/GAlignFrame.java
src/jalview/schemes/ResidueProperties.java
test/jalview/schemes/ScoreMatrixPrinter.java

index f720f39..7d540f9 100644 (file)
@@ -78,7 +78,7 @@ action.scale_left = Scale Left
 action.scale_right = Scale Right
 action.by_tree_order = By Tree Order
 action.sort = Sort
-action.calculate_tree = Calculate Tree
+action.calculate_tree = Calculate Tree...
 action.help = Help
 action.by_annotation = By Annotation...
 action.invert_sequence_selection = Invert Sequence Selection
index 86bf721..061a0a1 100755 (executable)
  */
 package jalview.analysis;
 
+import jalview.analysis.scoremodels.ScoreMatrix;
 import jalview.datamodel.AlignmentAnnotation;
 import jalview.datamodel.AlignmentI;
 import jalview.datamodel.Mapping;
 import jalview.datamodel.Sequence;
 import jalview.datamodel.SequenceI;
 import jalview.schemes.ResidueProperties;
-import jalview.schemes.ScoreMatrix;
 import jalview.util.Comparison;
 import jalview.util.Format;
 import jalview.util.MapList;
index eaea7bf..41dbcc0 100755 (executable)
  */
 package jalview.analysis;
 
+import jalview.analysis.scoremodels.ScoreMatrix;
 import jalview.datamodel.BinarySequence;
 import jalview.datamodel.BinarySequence.InvalidSequenceTypeException;
 import jalview.math.Matrix;
 import jalview.schemes.ResidueProperties;
-import jalview.schemes.ScoreMatrix;
 
 import java.io.PrintStream;
 
similarity index 96%
rename from src/jalview/schemes/ScoreMatrix.java
rename to src/jalview/analysis/scoremodels/ScoreMatrix.java
index 5e5fa8d..41aef82 100644 (file)
  * along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
  * The Jalview Authors are detailed in the 'AUTHORS' file.
  */
-package jalview.schemes;
+package jalview.analysis.scoremodels;
 
-import jalview.analysis.scoremodels.PairwiseSeqScoreModel;
 import jalview.api.analysis.ScoreModelI;
+import jalview.schemes.ResidueProperties;
 
 public class ScoreMatrix extends PairwiseSeqScoreModel implements
         ScoreModelI
@@ -53,7 +53,7 @@ public class ScoreMatrix extends PairwiseSeqScoreModel implements
    * @param type
    *          0 for Protein, 1 for NA
    */
-  ScoreMatrix(String name, int[][] matrix, int type)
+  public ScoreMatrix(String name, int[][] matrix, int type)
   {
     this.matrix = matrix;
     this.type = type;
@@ -89,6 +89,7 @@ public class ScoreMatrix extends PairwiseSeqScoreModel implements
     return getPairwiseScore(A1.charAt(0), A2.charAt(0));
   }
 
+  @Override
   public int getPairwiseScore(char c, char d)
   {
     int pog = 0;
@@ -112,6 +113,7 @@ public class ScoreMatrix extends PairwiseSeqScoreModel implements
   /**
    * pretty print the matrix
    */
+  @Override
   public String toString()
   {
     return outputMatrix(false);
diff --git a/src/jalview/analysis/scoremodels/ScoreModels.java b/src/jalview/analysis/scoremodels/ScoreModels.java
new file mode 100644 (file)
index 0000000..4fa6396
--- /dev/null
@@ -0,0 +1,68 @@
+package jalview.analysis.scoremodels;
+
+import jalview.api.analysis.ScoreModelI;
+import jalview.schemes.ResidueProperties;
+
+import java.util.Map;
+import java.util.TreeMap;
+
+/**
+ * A class that can register and serve instances of ScoreModelI
+ */
+public class ScoreModels
+{
+  private static ScoreModels instance = new ScoreModels();
+
+  private Map<String, ScoreModelI> models;
+
+  public static ScoreModels getInstance()
+  {
+    return instance;
+  }
+
+  /**
+   * Private constructor to enforce use of singleton. Registers Jalview's
+   * "built-in" score models:
+   * <ul>
+   * <li>BLOSUM62</li>
+   * <li>PAM250</li>
+   * <li>DNA</li>
+   * <li>Sequence Feature Similarity</li>
+   * <li>Percentage Identity</li>
+   * </ul>
+   */
+  private ScoreModels()
+  {
+    /*
+     * using TreeMap keeps models ordered alphabetically by name
+     */
+    models = new TreeMap<String, ScoreModelI>(String.CASE_INSENSITIVE_ORDER);
+    registerScoreModel(new ScoreMatrix("BLOSUM62",
+            ResidueProperties.BLOSUM62, 0));
+    registerScoreModel(new ScoreMatrix("PAM250", ResidueProperties.PAM250,
+            0));
+    registerScoreModel(new ScoreMatrix("DNA", ResidueProperties.DNA, 1));
+    registerScoreModel(new FeatureScoreModel());
+    registerScoreModel(new PIDScoreModel());
+  }
+
+  public Iterable<String> getModelNames()
+  {
+    return models.keySet();
+  }
+
+  public ScoreModelI forName(String s)
+  {
+    return models.get(s);
+  }
+
+  public void registerScoreModel(ScoreModelI sm)
+  {
+    ScoreModelI sm2 = models.get(sm.getName());
+    if (sm2 != null)
+    {
+      System.err.println("Warning: replacing score model " + sm2.getName());
+    }
+    models.put(sm.getName(), sm);
+  }
+}
index 31a1c32..332bba5 100644 (file)
@@ -29,8 +29,20 @@ public interface ScoreModelI
 
   String getName();
 
+  /**
+   * Answers true if this model is applicable for nucleotide data (so should be
+   * shown in menus in that context)
+   * 
+   * @return
+   */
   boolean isDNA();
 
+  /**
+   * Answers true if this model is applicable for peptide data (so should be
+   * shown in menus in that context)
+   * 
+   * @return
+   */
   boolean isProtein();
 
 }
index ed57dce..a959cc7 100755 (executable)
@@ -20,8 +20,8 @@
  */
 package jalview.datamodel;
 
+import jalview.analysis.scoremodels.ScoreMatrix;
 import jalview.schemes.ResidueProperties;
-import jalview.schemes.ScoreMatrix;
 
 /**
  * Encode a sequence as a numeric vector using either classic residue binary
index b5fc817..d6dfd9d 100644 (file)
@@ -82,7 +82,6 @@ import jalview.jbgui.GAlignFrame;
 import jalview.schemes.ColourSchemeI;
 import jalview.schemes.ColourSchemes;
 import jalview.schemes.ResidueColourScheme;
-import jalview.schemes.ResidueProperties;
 import jalview.schemes.TCoffeeColourScheme;
 import jalview.util.MessageManager;
 import jalview.viewmodel.AlignmentViewport;
@@ -360,7 +359,15 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
 
     setMenusFromViewport(viewport);
     buildSortByAnnotationScoresMenu();
-    buildTreeMenu();
+    calculateTree.addActionListener(new ActionListener()
+    {
+
+      @Override
+      public void actionPerformed(ActionEvent e)
+      {
+        new TreeChooser(AlignFrame.this);
+      }
+    });
     buildColourMenu();
 
     if (Desktop.desktop != null)
@@ -3580,54 +3587,6 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
   /**
    * DOCUMENT ME!
    * 
-   * @param e
-   *          DOCUMENT ME!
-   */
-  @Override
-  public void averageDistanceTreeMenuItem_actionPerformed(ActionEvent e)
-  {
-    newTreePanel("AV", "PID", "Average distance tree using PID");
-  }
-
-  /**
-   * DOCUMENT ME!
-   * 
-   * @param e
-   *          DOCUMENT ME!
-   */
-  @Override
-  public void neighbourTreeMenuItem_actionPerformed(ActionEvent e)
-  {
-    newTreePanel("NJ", "PID", "Neighbour joining tree using PID");
-  }
-
-  /**
-   * DOCUMENT ME!
-   * 
-   * @param e
-   *          DOCUMENT ME!
-   */
-  @Override
-  protected void njTreeBlosumMenuItem_actionPerformed(ActionEvent e)
-  {
-    newTreePanel("NJ", "BL", "Neighbour joining tree using BLOSUM62");
-  }
-
-  /**
-   * DOCUMENT ME!
-   * 
-   * @param e
-   *          DOCUMENT ME!
-   */
-  @Override
-  protected void avTreeBlosumMenuItem_actionPerformed(ActionEvent e)
-  {
-    newTreePanel("AV", "BL", "Average distance tree using BLOSUM62");
-  }
-
-  /**
-   * DOCUMENT ME!
-   * 
    * @param type
    *          DOCUMENT ME!
    * @param pwType
@@ -3834,48 +3793,10 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
    * call. Listeners are added to remove the menu item when the treePanel is
    * closed, and adjust the tree leaf to sequence mapping when the alignment is
    * modified.
-   * 
-   * @param treePanel
-   *          Displayed tree window.
-   * @param title
-   *          SortBy menu item title.
    */
   @Override
-  public void buildTreeMenu()
+  public void buildTreeSortMenu()
   {
-    calculateTree.removeAll();
-    // build the calculate menu
-
-    for (final String type : new String[] { "NJ", "AV" })
-    {
-      String treecalcnm = MessageManager.getString("label.tree_calc_"
-              + type.toLowerCase());
-      for (final String pwtype : ResidueProperties.scoreMatrices.keySet())
-      {
-        JMenuItem tm = new JMenuItem();
-        ScoreModelI sm = ResidueProperties.scoreMatrices.get(pwtype);
-        if (sm.isDNA() == viewport.getAlignment().isNucleotide()
-                || sm.isProtein() == !viewport.getAlignment()
-                        .isNucleotide())
-        {
-          String smn = MessageManager.getStringOrReturn(
-                  "label.score_model_", sm.getName());
-          final String title = MessageManager.formatMessage(
-                  "label.treecalc_title", treecalcnm, smn);
-          tm.setText(title);//
-          tm.addActionListener(new java.awt.event.ActionListener()
-          {
-            @Override
-            public void actionPerformed(ActionEvent e)
-            {
-              newTreePanel(type, pwtype, title);
-            }
-          });
-          calculateTree.add(tm);
-        }
-
-      }
-    }
     sortByTreeMenu.removeAll();
 
     List<Component> comps = PaintRefresher.components.get(viewport
@@ -5699,6 +5620,17 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
 
     ColourMenuHelper.setColourSelected(colourMenu, schemeName);
   }
+
+  public void newTreePanel(String treeType, ScoreModelI sm)
+  {
+    String treecalcnm = MessageManager.getString("label.tree_calc_"
+            + treeType.toLowerCase());
+    String smn = MessageManager.getStringOrReturn("label.score_model_",
+            sm.getName());
+    final String ttl = MessageManager.formatMessage("label.treecalc_title",
+            treecalcnm, smn);
+    newTreePanel(treeType, sm.getName(), ttl);
+  }
 }
 
 class PrintThread extends Thread
diff --git a/src/jalview/gui/TreeChooser.java b/src/jalview/gui/TreeChooser.java
new file mode 100644 (file)
index 0000000..338fbb8
--- /dev/null
@@ -0,0 +1,176 @@
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ 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 jalview.analysis.scoremodels.ScoreModels;
+import jalview.api.analysis.ScoreModelI;
+import jalview.util.MessageManager;
+
+import java.awt.Color;
+import java.awt.FlowLayout;
+import java.awt.Font;
+import java.awt.event.ActionEvent;
+
+import javax.swing.ButtonGroup;
+import javax.swing.JButton;
+import javax.swing.JComboBox;
+import javax.swing.JInternalFrame;
+import javax.swing.JLayeredPane;
+import javax.swing.JPanel;
+import javax.swing.JRadioButton;
+
+/**
+ * A dialog to allow a user to select and action Tree calculation options
+ */
+public class TreeChooser extends JPanel
+{
+  private static final Font VERDANA_11PT = new Font("Verdana", 0, 11);
+
+  AlignFrame af;
+
+  JRadioButton neighbourJoining;
+
+  JRadioButton averageDistance;
+
+  JComboBox<String> matrixNames;
+
+  private JInternalFrame frame;
+
+  private ButtonGroup treeTypes;
+
+  /**
+   * Constructor
+   * 
+   * @param af
+   */
+  public TreeChooser(AlignFrame alignFrame)
+  {
+    this.af = alignFrame;
+    init();
+  }
+
+  void init()
+  {
+    frame = new JInternalFrame();
+    frame.setContentPane(this);
+    this.setBackground(Color.white);
+
+    neighbourJoining = new JRadioButton(
+            MessageManager.getString("label.tree_calc_nj"));
+    neighbourJoining.setOpaque(false);
+    averageDistance = new JRadioButton(
+            MessageManager.getString("label.tree_calc_av"));
+    treeTypes = new ButtonGroup();
+    treeTypes.add(neighbourJoining);
+    treeTypes.add(averageDistance);
+    neighbourJoining.setSelected(true);
+
+    matrixNames = new JComboBox<String>();
+    ScoreModels scoreModels = ScoreModels.getInstance();
+    for (String scoreType : scoreModels.getModelNames())
+    {
+      ScoreModelI sm = scoreModels.forName(scoreType);
+      if (sm.isDNA() == af.getViewport().getAlignment().isNucleotide()
+              || sm.isProtein() == !af.getViewport().getAlignment()
+                      .isNucleotide())
+      {
+        matrixNames.addItem(sm.getName());
+      }
+    }
+
+    JButton ok = new JButton(MessageManager.getString("action.ok"));
+    ok.setFont(VERDANA_11PT);
+    ok.addActionListener(new java.awt.event.ActionListener()
+    {
+      @Override
+      public void actionPerformed(ActionEvent e)
+      {
+        ok_actionPerformed(e);
+      }
+    });
+
+    JButton cancel = new JButton(MessageManager.getString("action.cancel"));
+    cancel.setFont(VERDANA_11PT);
+    cancel.addActionListener(new java.awt.event.ActionListener()
+    {
+      @Override
+      public void actionPerformed(ActionEvent e)
+      {
+        cancel_actionPerformed(e);
+      }
+    });
+
+    JPanel p1 = new JPanel();
+    p1.setOpaque(false);
+    p1.add(neighbourJoining);
+    p1.add(averageDistance);
+    this.add(p1);
+    JPanel p2 = new JPanel(new FlowLayout(FlowLayout.LEFT));
+    p2.setOpaque(false);
+    p2.add(matrixNames, FlowLayout.LEFT);
+    this.add(p2);
+    JPanel p3 = new JPanel();
+    p3.setOpaque(false);
+    p3.add(ok);
+    p3.add(cancel);
+    this.add(p3);
+
+    Desktop.addInternalFrame(frame,
+            MessageManager.getString("label.choose_tree"),
+              400, 200, false);
+
+    frame.setLayer(JLayeredPane.PALETTE_LAYER);
+  }
+
+  /**
+   * Open and calculate the selected tree on 'OK'
+   * 
+   * @param e
+   */
+  protected void ok_actionPerformed(ActionEvent e)
+  {
+    try
+    {
+      frame.setClosed(true);
+      String treeType = neighbourJoining.isSelected() ? "NJ" : "AV";
+      ScoreModelI sm = ScoreModels.getInstance().forName(
+              matrixNames.getSelectedItem().toString());
+      af.newTreePanel(treeType, sm);
+    } catch (Exception ex)
+    {
+    }
+  }
+
+  /**
+   * Closes dialog on cancel
+   * 
+   * @param e
+   */
+  protected void cancel_actionPerformed(ActionEvent e)
+  {
+    try
+    {
+      frame.setClosed(true);
+    } catch (Exception ex)
+    {
+    }
+  }
+}
index b39f4a8..97dcfa0 100755 (executable)
@@ -129,7 +129,7 @@ public class GAlignFrame extends JInternalFrame
 
   protected JMenu sort = new JMenu();
 
-  protected JMenu calculateTree = new JMenu();
+  protected JMenuItem calculateTree = new JMenuItem();
 
   protected JCheckBoxMenuItem padGapsMenuitem = new JCheckBoxMenuItem();
 
@@ -533,26 +533,6 @@ public class GAlignFrame extends JInternalFrame
         PCAMenuItem_actionPerformed(e);
       }
     });
-    JMenuItem averageDistanceTreeMenuItem = new JMenuItem(
-            MessageManager.getString("label.average_distance_identity"));
-    averageDistanceTreeMenuItem.addActionListener(new ActionListener()
-    {
-      @Override
-      public void actionPerformed(ActionEvent e)
-      {
-        averageDistanceTreeMenuItem_actionPerformed(e);
-      }
-    });
-    JMenuItem neighbourTreeMenuItem = new JMenuItem(
-            MessageManager.getString("label.neighbour_joining_identity"));
-    neighbourTreeMenuItem.addActionListener(new ActionListener()
-    {
-      @Override
-      public void actionPerformed(ActionEvent e)
-      {
-        neighbourTreeMenuItem_actionPerformed(e);
-      }
-    });
 
     this.getContentPane().setLayout(new BorderLayout());
     alignFrameMenuBar.setFont(new java.awt.Font("Verdana", 0, 11));
@@ -563,27 +543,6 @@ public class GAlignFrame extends JInternalFrame
     outputTextboxMenu.setText(MessageManager
             .getString("label.out_to_textbox"));
 
-
-    JMenuItem avDistanceTreeBlosumMenuItem = new JMenuItem(
-            MessageManager.getString("label.average_distance_blosum62"));
-    avDistanceTreeBlosumMenuItem.addActionListener(new ActionListener()
-    {
-      @Override
-      public void actionPerformed(ActionEvent e)
-      {
-        avTreeBlosumMenuItem_actionPerformed(e);
-      }
-    });
-    JMenuItem njTreeBlosumMenuItem = new JMenuItem(
-            MessageManager.getString("label.neighbour_blosum62"));
-    njTreeBlosumMenuItem.addActionListener(new ActionListener()
-    {
-      @Override
-      public void actionPerformed(ActionEvent e)
-      {
-        njTreeBlosumMenuItem_actionPerformed(e);
-      }
-    });
     annotationPanelMenuItem.setActionCommand("");
     annotationPanelMenuItem.setText(MessageManager
             .getString("label.show_annotations"));
@@ -1203,7 +1162,7 @@ public class GAlignFrame extends JInternalFrame
       @Override
       public void menuSelected(MenuEvent e)
       {
-        buildTreeMenu();
+        buildTreeSortMenu();
       }
 
       @Override
@@ -2327,22 +2286,10 @@ public class GAlignFrame extends JInternalFrame
   {
   }
 
-  protected void averageDistanceTreeMenuItem_actionPerformed(ActionEvent e)
-  {
-  }
-
   protected void neighbourTreeMenuItem_actionPerformed(ActionEvent e)
   {
   }
 
-  protected void njTreeBlosumMenuItem_actionPerformed(ActionEvent e)
-  {
-  }
-
-  protected void avTreeBlosumMenuItem_actionPerformed(ActionEvent e)
-  {
-  }
-
   protected void conservationMenuItem_actionPerformed(boolean selected)
   {
   }
@@ -2627,7 +2574,7 @@ public class GAlignFrame extends JInternalFrame
 
   }
 
-  public void buildTreeMenu()
+  public void buildTreeSortMenu()
   {
 
   }
index 406814a..c774ebf 100755 (executable)
@@ -22,6 +22,7 @@ package jalview.schemes;
 
 import jalview.analysis.scoremodels.FeatureScoreModel;
 import jalview.analysis.scoremodels.PIDScoreModel;
+import jalview.analysis.scoremodels.ScoreMatrix;
 import jalview.api.analysis.ScoreModelI;
 
 import java.awt.Color;
@@ -477,7 +478,7 @@ public class ResidueProperties
 
   // public static final double hydmax = 1.38;
   // public static final double hydmin = -2.53;
-  private static final int[][] BLOSUM62 = {
+  public static final int[][] BLOSUM62 = {
       { 4, -1, -2, -2, 0, -1, -1, 0, -2, -1, -1, -1, -1, -2, -1, 1, 0, -3,
           -2, 0, -2, -1, 0, -4 },
       { -1, 5, 0, -2, -3, 1, 0, -2, 0, -3, -2, 2, -1, -3, -2, -1, -1, -3,
@@ -527,7 +528,7 @@ public class ResidueProperties
       { -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4,
           -4, -4, -4, -4, -4, -4, 1 }, };
 
-  static final int[][] PAM250 = {
+  public static final int[][] PAM250 = {
       { 2, -2, 0, 0, -2, 0, 0, 1, -1, -1, -2, -1, -1, -3, 1, 1, 1, -6, -3,
           0, 0, 0, 0, -8 },
       { -2, 6, 0, -1, -4, 1, -1, -3, 2, -2, -3, 3, 0, -4, 0, 0, -1, 2, -4,
@@ -603,7 +604,8 @@ public class ResidueProperties
   // treats T and U identically. R and Y weak equivalence with AG and CTU.
   // N matches any other base weakly
   //
-  static final int[][] DNA = { { 10, -8, -8, -8, -8, 1, 1, 1, -8, 1, 1 }, // A
+  public static final int[][] DNA = {
+      { 10, -8, -8, -8, -8, 1, 1, 1, -8, 1, 1 }, // A
       { -8, 10, -8, -8, -8, 1, 1, -8, 1, 1, 1 }, // C
       { -8, -8, 10, -8, -8, 1, 1, 1, -8, 1, 1 }, // G
       { -8, -8, -8, 10, 10, 1, 1, -8, 1, 1, 1 }, // T
@@ -1252,7 +1254,8 @@ public class ResidueProperties
     // scoreMatrices.put("Conservation EnhPos", new
     // ScoreMatrix("Conservation EnhPos",propMatrixEpos,0));
     scoreMatrices.put("PID", new PIDScoreModel());
-    scoreMatrices.put("Displayed Features", new FeatureScoreModel());
+    scoreMatrices.put("Sequence Feature Similarity",
+            new FeatureScoreModel());
   }
 
   private ResidueProperties()
index a743163..4e7755c 100644 (file)
@@ -20,6 +20,7 @@
  */
 package jalview.schemes;
 
+import jalview.analysis.scoremodels.ScoreMatrix;
 import jalview.api.analysis.ScoreModelI;
 import jalview.gui.JvOptionPane;