From 02c0b8687b9932f2b4fe0a9284a47875e0269a7e Mon Sep 17 00:00:00 2001 From: gmungoc Date: Mon, 27 Feb 2017 10:05:50 +0000 Subject: [PATCH] JAL-1632 refactored NJTree constructor to include SimilarityParams --- src/jalview/analysis/NJTree.java | 150 ++++++++++++++++++++-------------- src/jalview/appletgui/TreePanel.java | 64 +++++++-------- src/jalview/gui/AlignFrame.java | 6 -- src/jalview/gui/SeqPanel.java | 2 +- src/jalview/gui/TreePanel.java | 13 +-- 5 files changed, 127 insertions(+), 108 deletions(-) diff --git a/src/jalview/analysis/NJTree.java b/src/jalview/analysis/NJTree.java index 4ee0be9..cc0e473 100644 --- a/src/jalview/analysis/NJTree.java +++ b/src/jalview/analysis/NJTree.java @@ -20,10 +20,10 @@ */ 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; - 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(); + // 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(); 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 + *

+ * If the score model computes pairwise distance scores, then these are used + * directly to derive the tree + *

+ * 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"); } diff --git a/src/jalview/appletgui/TreePanel.java b/src/jalview/appletgui/TreePanel.java index 5b12fa6..7266665 100644 --- a/src/jalview/appletgui/TreePanel.java +++ b/src/jalview/appletgui/TreePanel.java @@ -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; + } + } diff --git a/src/jalview/gui/AlignFrame.java b/src/jalview/gui/AlignFrame.java index 1162c53..4fd80b2 100644 --- a/src/jalview/gui/AlignFrame.java +++ b/src/jalview/gui/AlignFrame.java @@ -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) { diff --git a/src/jalview/gui/SeqPanel.java b/src/jalview/gui/SeqPanel.java index 37b4852..c83dd16 100644 --- a/src/jalview/gui/SeqPanel.java +++ b/src/jalview/gui/SeqPanel.java @@ -1668,7 +1668,7 @@ public class SeqPanel extends JPanel implements MouseListener, * * @param evt * @param res - * @param sequence + * @param sequences */ void showPopupMenu(MouseEvent evt) { diff --git a/src/jalview/gui/TreePanel.java b/src/jalview/gui/TreePanel.java index 74dd29a..857e77c 100755 --- a/src/jalview/gui/TreePanel.java +++ b/src/jalview/gui/TreePanel.java @@ -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 -- 1.7.10.2