*/
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;
import jalview.datamodel.SequenceNode;
import jalview.io.NewickFile;
import jalview.math.MatrixI;
+import jalview.viewmodel.AlignmentViewport;
import java.util.Enumeration;
import java.util.List;
*/
public class NJTree
{
- /*
- * 'methods'
- */
public static final String AVERAGE_DISTANCE = "AV";
public static final String NEIGHBOUR_JOINING = "NJ";
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;
int noClus;
- MatrixI distance;
+ MatrixI distances;
int mini;
*/
public NJTree(SequenceI[] seqs, NewickFile treefile)
{
- this.sequence = seqs;
+ this.sequences = seqs;
top = treefile.getTree();
/**
}
/**
- * 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)
{
MatrixI result = ((SimilarityScoreModelI) sm).findSimilarities(
seqData, SimilarityParams.Jalview);
result.reverseRange(true);
- distance = result;
+ distances = result;
}
makeLeaves();
*/
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;
{
// 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);
}
{
// 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]);
}
}
{
// 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
{
// 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]);
}
}
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);
}
}
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)
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);
}
}
}
{
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];
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");
}
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;
}
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());
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;
+ }
+
}