From 82de3ff949ae61b771136fbdb49baacc20e652fd Mon Sep 17 00:00:00 2001 From: gmungoc Date: Thu, 26 Apr 2018 13:02:12 +0100 Subject: [PATCH] JAL-2962 option to offer BLOSUM62 for nucleotide PCA --- src/jalview/gui/CalculationChooser.java | 95 ++++++++++++++++++------- test/jalview/gui/CalculationChooserTest.java | 98 ++++++++++++++++++++++++++ 2 files changed, 168 insertions(+), 25 deletions(-) create mode 100644 test/jalview/gui/CalculationChooserTest.java diff --git a/src/jalview/gui/CalculationChooser.java b/src/jalview/gui/CalculationChooser.java index f674c7e..f0d9521 100644 --- a/src/jalview/gui/CalculationChooser.java +++ b/src/jalview/gui/CalculationChooser.java @@ -25,6 +25,7 @@ import jalview.analysis.scoremodels.ScoreModels; import jalview.analysis.scoremodels.SimilarityParams; import jalview.api.analysis.ScoreModelI; import jalview.api.analysis.SimilarityParamsI; +import jalview.bin.Cache; import jalview.datamodel.SequenceGroup; import jalview.util.MessageManager; @@ -103,7 +104,7 @@ public class CalculationChooser extends JPanel final ComboBoxTooltipRenderer renderer = new ComboBoxTooltipRenderer(); - List tips = new ArrayList(); + List tips = new ArrayList<>(); /* * the most recently opened PCA results panel @@ -375,7 +376,7 @@ public class CalculationChooser extends JPanel */ protected JComboBox buildModelOptionsList() { - final JComboBox scoreModelsCombo = new JComboBox(); + final JComboBox scoreModelsCombo = new JComboBox<>(); scoreModelsCombo.setRenderer(renderer); /* @@ -418,39 +419,42 @@ public class CalculationChooser extends JPanel { Object curSel = comboBox.getSelectedItem(); toolTips.clear(); - DefaultComboBoxModel model = new DefaultComboBoxModel(); + DefaultComboBoxModel model = new DefaultComboBoxModel<>(); + + /* + * select the score models applicable to the alignment type + */ + boolean nucleotide = af.getViewport().getAlignment().isNucleotide(); + List models = getApplicableScoreModels(nucleotide, + pca.isSelected()); /* * now we can actually add entries to the combobox, * remembering their descriptions for tooltips */ - ScoreModels scoreModels = ScoreModels.getInstance(); boolean selectedIsPresent = false; - for (ScoreModelI sm : scoreModels.getModels()) + for (ScoreModelI sm : models) { - boolean nucleotide = af.getViewport().getAlignment().isNucleotide(); - if (sm.isDNA() && nucleotide || sm.isProtein() && !nucleotide) + if (curSel != null && sm.getName().equals(curSel)) + { + selectedIsPresent = true; + curSel = sm.getName(); + } + model.addElement(sm.getName()); + + /* + * tooltip is description if provided, else text lookup with + * fallback on the model name + */ + String tooltip = sm.getDescription(); + if (tooltip == null) { - if (curSel != null && sm.getName().equals(curSel)) - { - selectedIsPresent = true; - curSel = sm.getName(); - } - model.addElement(sm.getName()); - - /* - * tooltip is description if provided, else text lookup with - * fallback on the model name - */ - String tooltip = sm.getDescription(); - if (tooltip == null) - { - tooltip = MessageManager.getStringOrReturn("label.score_model_", - sm.getName()); - } - toolTips.add(tooltip); + tooltip = MessageManager.getStringOrReturn("label.score_model_", + sm.getName()); } + toolTips.add(tooltip); } + if (selectedIsPresent) { model.setSelectedItem(curSel); @@ -460,6 +464,47 @@ public class CalculationChooser extends JPanel } /** + * Builds a list of score models which are applicable for the alignment and + * calculation type (peptide or generic models for protein, nucleotide or + * generic models for nucleotide). + *

+ * As a special case, includes BLOSUM62 as an extra option for nucleotide PCA. + * This is for backwards compatibility with Jalview prior to 2.8 when BLOSUM62 + * was the only score matrix supported. This is included if property + * BLOSUM62_PCA_FOR_NUCLEOTIDE is set to true in the Jalview properties file. + * + * @param nucleotide + * @param forPca + * @return + */ + protected static List getApplicableScoreModels( + boolean nucleotide, boolean forPca) + { + List filtered = new ArrayList<>(); + + ScoreModels scoreModels = ScoreModels.getInstance(); + for (ScoreModelI sm : scoreModels.getModels()) + { + if (!nucleotide && sm.isProtein() || nucleotide && sm.isDNA()) + { + filtered.add(sm); + } + } + + /* + * special case: add BLOSUM62 as last option for nucleotide PCA, + * for backwards compatibility with Jalview < 2.8 (JAL-2962) + */ + if (nucleotide && forPca + && Cache.getDefault("BLOSUM62_PCA_FOR_NUCLEOTIDE", false)) + { + filtered.add(scoreModels.getBlosum62()); + } + + return filtered; + } + + /** * Open and calculate the selected tree or PCA on 'OK' */ protected void calculate_actionPerformed() diff --git a/test/jalview/gui/CalculationChooserTest.java b/test/jalview/gui/CalculationChooserTest.java new file mode 100644 index 0000000..6c2e777 --- /dev/null +++ b/test/jalview/gui/CalculationChooserTest.java @@ -0,0 +1,98 @@ +package jalview.gui; + +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertSame; + +import jalview.analysis.scoremodels.ScoreModels; +import jalview.api.analysis.ScoreModelI; +import jalview.bin.Cache; + +import java.util.List; + +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Test; + +public class CalculationChooserTest +{ + @BeforeClass(alwaysRun = true) + public void setUp() + { + // read-only Jalview properties + Cache.loadProperties("test/jalview/io/testProps.jvprops"); + Cache.applicationProperties.setProperty("BLOSUM62_PCA_FOR_NUCLEOTIDE", + Boolean.FALSE.toString()); + } + + @Test(groups = "Functional") + public void testGetApplicableScoreModels() + { + ScoreModels models = ScoreModels.getInstance(); + ScoreModelI blosum62 = models.getBlosum62(); + ScoreModelI pam250 = models.getPam250(); + ScoreModelI dna = models.getDefaultModel(false); + + /* + * peptide models for PCA + */ + List filtered = CalculationChooser + .getApplicableScoreModels(false, true); + assertEquals(filtered.size(), 4); + assertSame(filtered.get(0), blosum62); + assertSame(filtered.get(1), pam250); + assertEquals(filtered.get(2).getName(), "PID"); + assertEquals(filtered.get(3).getName(), "Sequence Feature Similarity"); + + /* + * peptide models for Tree are the same + */ + filtered = CalculationChooser.getApplicableScoreModels(false, false); + assertEquals(filtered.size(), 4); + assertSame(filtered.get(0), blosum62); + assertSame(filtered.get(1), pam250); + assertEquals(filtered.get(2).getName(), "PID"); + assertEquals(filtered.get(3).getName(), "Sequence Feature Similarity"); + + /* + * nucleotide models for PCA + */ + filtered = CalculationChooser.getApplicableScoreModels(true, true); + assertEquals(filtered.size(), 3); + assertSame(filtered.get(0), dna); + assertEquals(filtered.get(1).getName(), "PID"); + assertEquals(filtered.get(2).getName(), "Sequence Feature Similarity"); + + /* + * nucleotide models for Tree are the same + */ + filtered = CalculationChooser.getApplicableScoreModels(true, false); + assertEquals(filtered.size(), 3); + assertSame(filtered.get(0), dna); + assertEquals(filtered.get(1).getName(), "PID"); + assertEquals(filtered.get(2).getName(), "Sequence Feature Similarity"); + + /* + * enable inclusion of BLOSUM62 for nucleotide PCA (JAL-2962) + */ + Cache.applicationProperties.setProperty("BLOSUM62_PCA_FOR_NUCLEOTIDE", + Boolean.TRUE.toString()); + + /* + * nucleotide models for Tree are unchanged + */ + filtered = CalculationChooser.getApplicableScoreModels(true, false); + assertEquals(filtered.size(), 3); + assertSame(filtered.get(0), dna); + assertEquals(filtered.get(1).getName(), "PID"); + assertEquals(filtered.get(2).getName(), "Sequence Feature Similarity"); + + /* + * nucleotide models for PCA add BLOSUM62 as last option + */ + filtered = CalculationChooser.getApplicableScoreModels(true, true); + assertEquals(filtered.size(), 4); + assertSame(filtered.get(0), dna); + assertEquals(filtered.get(1).getName(), "PID"); + assertEquals(filtered.get(2).getName(), "Sequence Feature Similarity"); + assertSame(filtered.get(3), blosum62); + } +} -- 1.7.10.2