JAL-4134 column grouping model and methods moved to their own object held by by Conta...
[jalview.git] / src / jalview / datamodel / GroupSet.java
1 package jalview.datamodel;
2
3 import java.awt.Color;
4 import java.util.ArrayList;
5 import java.util.Arrays;
6 import java.util.BitSet;
7 import java.util.HashMap;
8 import java.util.List;
9
10 import jalview.analysis.AverageDistanceEngine;
11 import jalview.bin.Console;
12
13 public class GroupSet implements GroupSetI
14 {
15   List<BitSet> groups = Arrays.asList();
16
17   public GroupSet(GroupSet grps)
18   {
19     abs=grps.abs;
20     colorMap=new HashMap<BitSet, Color>(grps.colorMap);
21     groups=new ArrayList<BitSet>(grps.groups);
22     newick=grps.newick;
23     thresh=grps.thresh;
24     treeType=grps.treeType;
25   }
26
27   public GroupSet()
28   {
29     // TODO Auto-generated constructor stub
30   }
31
32   public GroupSet(boolean abs2, float thresh2, List<BitSet> groups2,
33           String treeType2, String newick2)
34   {
35     abs = abs2;
36     thresh = thresh2;
37     groups = groups2;
38     treeType = treeType2;
39     newick=newick2;
40   }
41
42   @Override
43   public boolean hasGroups()
44   {
45     return groups != null;
46   }
47
48   String newick = null;
49
50   @Override
51   public String getNewick()
52   {
53     return newick;
54   }
55
56   @Override
57   public boolean hasTree()
58   {
59     return newick != null && newick.length() > 0;
60   }
61
62   boolean abs=false;
63
64   double thresh=0;
65
66   String treeType = null;
67
68   @Override
69   public void updateGroups(List<BitSet> colGroups)
70   {
71     if (colGroups != null)
72     {
73       groups = colGroups;
74     }
75   }
76
77   @Override
78   public BitSet getGroupsFor(int column)
79   {
80     if (groups != null)
81     {
82       for (BitSet gp : groups)
83       {
84         if (gp.get(column))
85         {
86           return gp;
87         }
88       }
89     }
90     // return singleton set;
91     BitSet bs = new BitSet();
92     bs.set(column);
93     return bs;
94   }
95
96   HashMap<BitSet, Color> colorMap = new HashMap<>();
97
98   @Override
99   public Color getColourForGroup(BitSet bs)
100   {
101     if (bs == null)
102     {
103       return Color.white;
104     }
105     Color groupCol = colorMap.get(bs);
106     if (groupCol == null)
107     {
108       return Color.white;
109     }
110     return groupCol;
111   }
112
113   @Override
114   public void setColorForGroup(BitSet bs, Color color)
115   {
116     colorMap.put(bs, color);
117   }
118
119   @Override
120   public void restoreGroups(List<BitSet> newgroups, String treeMethod,
121           String tree, double thresh2)
122   {
123     treeType = treeMethod;
124     groups = newgroups;
125     thresh = thresh2;
126     newick = tree;
127
128   }
129
130   @Override
131   public boolean hasCutHeight()
132   {
133     return groups != null && thresh != 0;
134   }
135
136   @Override
137   public double getCutHeight()
138   {
139     return thresh;
140   }
141
142   @Override
143   public String getTreeMethod()
144   {
145     return treeType;
146   }
147
148   public static GroupSet makeGroups(ContactMatrixI matrix, float thresh,
149           boolean abs)
150   {
151     AverageDistanceEngine clusterer = new AverageDistanceEngine(null, null,
152             matrix);
153     double height = clusterer.findHeight(clusterer.getTopNode());
154     String newick = new jalview.io.NewickFile(clusterer.getTopNode(), false,
155             true).print();
156     String treeType = "UPGMA";
157     Console.trace("Newick string\n" + newick);
158
159     List<BinaryNode> nodegroups;
160     if (abs ? height > thresh : 0 < thresh && thresh < 1)
161     {
162       float cut = abs ? (float) (thresh / height) : thresh;
163       Console.debug("Threshold " + cut + " for height=" + height);
164
165       nodegroups = clusterer.groupNodes(cut);
166     }
167     else
168     {
169       nodegroups = new ArrayList<BinaryNode>();
170       nodegroups.add(clusterer.getTopNode());
171     }
172     List<BitSet> groups = new ArrayList<>();
173     for (BinaryNode root : nodegroups)
174     {
175       BitSet gpset = new BitSet();
176       for (BinaryNode leaf : clusterer.findLeaves(root))
177       {
178         gpset.set((Integer) leaf.element());
179       }
180       groups.add(gpset);
181     }
182     GroupSet grps = new GroupSet(abs,thresh,groups,treeType, newick);
183     return grps;
184   }
185
186   @Override
187   public List<BitSet> getGroups()
188   {
189     return groups;
190   }
191 }