0d3bff603fef79c380bdba96c2709123e605a120
[jalview.git] / src / jalview / datamodel / ContactMatrixI.java
1 package jalview.datamodel;
2
3 import java.awt.Color;
4 import java.util.Arrays;
5 import java.util.BitSet;
6 import java.util.List;
7
8 import jalview.util.ColorUtils;
9 import jalview.ws.datamodel.MappableContactMatrixI;
10
11 public interface ContactMatrixI
12 {
13
14   ContactListI getContactList(int column);
15
16   float getMin();
17
18   float getMax();
19
20   String getAnnotDescr();
21
22   String getAnnotLabel();
23
24   /**
25    * string indicating how the contactMatrix should be rendered - stored in
26    * calcId
27    * 
28    * @return
29    */
30   String getType();
31
32   int getWidth();
33
34   int getHeight();
35
36   public GroupSetI getGroupSet();
37
38   /// proxy methods to simplify use of the interface
39   /// Mappable contact matrices can override these to perform mapping
40
41   default public boolean hasGroupSet()
42   {
43     return getGroupSet() != null;
44   }
45
46   default boolean hasGroups()
47   {
48     return hasGroupSet() && getGroupSet().hasGroups();
49   }
50
51   default BitSet getGroupsFor(int column)
52   {
53     if (!hasGroupSet())
54     {
55       BitSet colbitset = new BitSet();
56       colbitset.set(column);
57       return colbitset;
58     }
59     return getGroupSet().getGroupsFor(column);
60   }
61
62   default List<BitSet> getGroups()
63   {
64     if (!hasGroupSet())
65     {
66       return Arrays.asList();
67     }
68     return getGroupSet().getGroups();
69   }
70
71   default boolean hasTree()
72   {
73     return hasGroupSet() ? getGroupSet().hasTree() : false;
74   }
75
76   /**
77    * Newick representation of clustered matrix
78    * 
79    * @return null unless hasTree is true
80    */
81   default String getNewick()
82   {
83     return hasGroupSet() ? getGroupSet().getNewick() : null;
84   }
85
86   default String getTreeMethod()
87   {
88     return hasGroupSet() ? getGroupSet().getTreeMethod() : null;
89   }
90
91   default boolean hasCutHeight()
92   {
93     return hasGroupSet() ? getGroupSet().hasCutHeight() : false;
94   }
95
96   default double getCutHeight()
97   {
98     return hasGroupSet() ? getGroupSet().getCutHeight() : 0;
99   }
100
101   default void updateGroups(List<BitSet> colGroups)
102   {
103     if (hasGroupSet())
104     {
105       getGroupSet().updateGroups(colGroups);
106     }
107   }
108
109   default void setColorForGroup(BitSet bs, Color color)
110   {
111     if (hasGroupSet())
112     {
113       getGroupSet().setColorForGroup(bs, color);
114     }
115   }
116
117   default Color getColourForGroup(BitSet bs)
118   {
119     if (hasGroupSet())
120     {
121       return getGroupSet().getColourForGroup(bs);
122     }
123     else
124     {
125       return Color.white;
126     }
127   }
128
129   void setGroupSet(GroupSet makeGroups);
130
131   default void randomlyReColourGroups()
132   {
133     if (hasGroupSet())
134     {
135       GroupSetI groups = getGroupSet();
136       for (BitSet group : groups.getGroups())
137       {
138         groups.setColorForGroup(group, ColorUtils.getARandomColor());
139       }
140     }
141   }
142
143   default void transferGroupColorsTo(AlignmentAnnotation aa)
144   {
145     if (hasGroupSet())
146     {
147       GroupSetI groups = getGroupSet();
148       // stash colors in linked annotation row.
149       // doesn't work yet. TESTS!
150       int sstart = aa.sequenceRef != null ? aa.sequenceRef.getStart() - 1
151               : 0;
152       Annotation ae;
153       Color gpcol = null;
154       int[] seqpos = null;
155       for (BitSet gp : groups.getGroups())
156       {
157         gpcol = groups.getColourForGroup(gp);
158         for (int p = gp.nextSetBit(0); p >= 0
159                 && p < Integer.MAX_VALUE; p = gp.nextSetBit(p + 1))
160         {
161           if (this instanceof MappableContactMatrixI)
162           {
163             MappableContactMatrixI mcm = (MappableContactMatrixI) this;
164             seqpos = mcm.getMappedPositionsFor(aa.sequenceRef, p);
165             if (seqpos == null)
166             {
167               // no mapping for this column.
168               continue;
169             }
170             // TODO: handle ranges...
171             ae = aa.getAnnotationForPosition(seqpos[0]);
172           }
173           else
174           {
175             ae = aa.getAnnotationForPosition(p + sstart);
176           }
177           if (ae != null)
178           {
179             ae.colour = gpcol.brighter().darker();
180           }
181         }
182       }
183     }
184   }
185
186   /**
187    * look up the colour for a column in the associated contact matrix
188    * 
189    * @return Color.white or assigned colour
190    */
191   default Color getGroupColorForPosition(int column)
192   {
193     if (hasGroupSet())
194     {
195       GroupSetI groups = getGroupSet();
196       for (BitSet gp : groups.getGroups())
197       {
198         if (gp.get(column))
199         {
200           return groups.getColourForGroup(gp);
201         }
202       }
203     }
204     return Color.white;
205   }
206
207   /**
208    * direct access to column and row position of matrix
209    * 
210    * Implementations are allowed to throw RunTimeExceptions if _column/i are out
211    * of bounds
212    * 
213    * @param column
214    * @param row
215    * @return
216    */
217   double getElementAt(int column, int row);
218
219 }