JAL-2428 separate TreeModel from TreeBuilder/NJTree/AverageDistanceTree
[jalview.git] / src / jalview / analysis / AverageDistanceTree.java
1 package jalview.analysis;
2
3 import jalview.api.analysis.ScoreModelI;
4 import jalview.api.analysis.SimilarityParamsI;
5 import jalview.datamodel.SequenceNode;
6 import jalview.viewmodel.AlignmentViewport;
7
8 public class AverageDistanceTree extends TreeBuilder
9 {
10   /**
11    * Constructor
12    * 
13    * @param av
14    * @param sm
15    * @param scoreParameters
16    */
17   public AverageDistanceTree(AlignmentViewport av, ScoreModelI sm,
18           SimilarityParamsI scoreParameters)
19   {
20     super(av, sm, scoreParameters);
21   }
22
23   /**
24    * Calculates and saves the distance between the combination of cluster(i) and
25    * cluster(j) and all other clusters. An average of the distances from
26    * cluster(i) and cluster(j) is calculated, weighted by the sizes of each
27    * cluster.
28    * 
29    * @param i
30    * @param j
31    */
32   @Override
33   protected void findClusterDistance(int i, int j)
34   {
35     int noi = clusters.elementAt(i).cardinality();
36     int noj = clusters.elementAt(j).cardinality();
37
38     // New distances from cluster i to others
39     double[] newdist = new double[noseqs];
40
41     for (int l = 0; l < noseqs; l++)
42     {
43       if ((l != i) && (l != j))
44       {
45         newdist[l] = ((distances.getValue(i, l) * noi) + (distances
46                 .getValue(j, l) * noj)) / (noi + noj);
47       }
48       else
49       {
50         newdist[l] = 0;
51       }
52     }
53
54     for (int ii = 0; ii < noseqs; ii++)
55     {
56       distances.setValue(i, ii, newdist[ii]);
57       distances.setValue(ii, i, newdist[ii]);
58       System.out.println(String.format(
59               "findClusterDistance(%d, %d) newdist to %d is %f", i, j, ii,
60               newdist[ii]));
61     }
62   }
63
64   /**
65    * Returns the minimum distance between two clusters, and also sets the
66    * indices of the clusters in fields mini and minj
67    * 
68    * @return DOCUMENT ME!
69    */
70   @Override
71   protected double findMinDistance()
72   {
73     double min = Double.MAX_VALUE;
74
75     for (int i = 0; i < (noseqs - 1); i++)
76     {
77       for (int j = i + 1; j < noseqs; j++)
78       {
79         if (!done.get(i) && !done.get(j))
80         {
81           if (distances.getValue(i, j) < min)
82           {
83             mini = i;
84             minj = j;
85
86             min = distances.getValue(i, j);
87           }
88         }
89       }
90     }
91     System.out.println("findMinDistance found " + min + " at " + mini + ","
92             + minj);
93     return min;
94   }
95
96   /**
97    * DOCUMENT ME!
98    * 
99    * @param tmpi
100    *          DOCUMENT ME!
101    * @param tmpj
102    *          DOCUMENT ME!
103    * @param dist
104    *          DOCUMENT ME!
105    */
106   @Override
107   protected void findNewDistances(SequenceNode tmpi, SequenceNode tmpj,
108           double dist)
109   {
110     double ih = 0;
111     double jh = 0;
112
113     SequenceNode sni = tmpi;
114     SequenceNode snj = tmpj;
115
116     while (sni != null)
117     {
118       ih = ih + sni.dist;
119       sni = (SequenceNode) sni.left();
120     }
121
122     while (snj != null)
123     {
124       jh = jh + snj.dist;
125       snj = (SequenceNode) snj.left();
126     }
127
128     tmpi.dist = ((dist / 2) - ih);
129     tmpj.dist = ((dist / 2) - jh);
130     System.out.println("findNewDistances set tmpi to " + tmpi.dist
131             + ", tmpj to " + tmpj.dist);
132   }
133
134 }