Merge branch 'releases/Release_2_11_3_Branch'
[jalview.git] / src / jalview / datamodel / ContactMatrixI.java
1 /*
2  * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3  * Copyright (C) $$Year-Rel$$ The Jalview Authors
4  * 
5  * This file is part of Jalview.
6  * 
7  * Jalview is free software: you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License 
9  * as published by the Free Software Foundation, either version 3
10  * of the License, or (at your option) any later version.
11  *  
12  * Jalview is distributed in the hope that it will be useful, but 
13  * WITHOUT ANY WARRANTY; without even the implied warranty 
14  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
15  * PURPOSE.  See the GNU General Public License for more details.
16  * 
17  * You should have received a copy of the GNU General Public License
18  * along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
19  * The Jalview Authors are detailed in the 'AUTHORS' file.
20  */
21 package jalview.datamodel;
22
23 import java.awt.Color;
24 import java.util.Arrays;
25 import java.util.BitSet;
26 import java.util.List;
27
28 import jalview.util.ColorUtils;
29 import jalview.ws.datamodel.MappableContactMatrixI;
30
31 public interface ContactMatrixI
32 {
33
34   ContactListI getContactList(int column);
35
36   float getMin();
37
38   float getMax();
39
40   String getAnnotDescr();
41
42   String getAnnotLabel();
43
44   /**
45    * string indicating how the contactMatrix should be rendered - stored in
46    * calcId
47    * 
48    * @return
49    */
50   String getType();
51
52   int getWidth();
53
54   int getHeight();
55
56   public GroupSetI getGroupSet();
57
58   /// proxy methods to simplify use of the interface
59   /// Mappable contact matrices can override these to perform mapping
60
61   default public boolean hasGroupSet()
62   {
63     return getGroupSet() != null;
64   }
65
66   default boolean hasGroups()
67   {
68     return hasGroupSet() && getGroupSet().hasGroups();
69   }
70
71   default BitSet getGroupsFor(int column)
72   {
73     if (!hasGroupSet())
74     {
75       BitSet colbitset = new BitSet();
76       colbitset.set(column);
77       return colbitset;
78     }
79     return getGroupSet().getGroupsFor(column);
80   }
81
82   default List<BitSet> getGroups()
83   {
84     if (!hasGroupSet())
85     {
86       return Arrays.asList();
87     }
88     return getGroupSet().getGroups();
89   }
90
91   default boolean hasTree()
92   {
93     return hasGroupSet() ? getGroupSet().hasTree() : false;
94   }
95
96   /**
97    * Newick representation of clustered matrix
98    * 
99    * @return null unless hasTree is true
100    */
101   default String getNewick()
102   {
103     return hasGroupSet() ? getGroupSet().getNewick() : null;
104   }
105
106   default String getTreeMethod()
107   {
108     return hasGroupSet() ? getGroupSet().getTreeMethod() : null;
109   }
110
111   default boolean hasCutHeight()
112   {
113     return hasGroupSet() ? getGroupSet().hasCutHeight() : false;
114   }
115
116   default double getCutHeight()
117   {
118     return hasGroupSet() ? getGroupSet().getCutHeight() : 0;
119   }
120
121   default void updateGroups(List<BitSet> colGroups)
122   {
123     if (hasGroupSet())
124     {
125       getGroupSet().updateGroups(colGroups);
126     }
127   }
128
129   default void setColorForGroup(BitSet bs, Color color)
130   {
131     if (hasGroupSet())
132     {
133       getGroupSet().setColorForGroup(bs, color);
134     }
135   }
136
137   default Color getColourForGroup(BitSet bs)
138   {
139     if (hasGroupSet())
140     {
141       return getGroupSet().getColourForGroup(bs);
142     }
143     else
144     {
145       return Color.white;
146     }
147   }
148
149   void setGroupSet(GroupSet makeGroups);
150
151   default void randomlyReColourGroups()
152   {
153     if (hasGroupSet())
154     {
155       GroupSetI groups = getGroupSet();
156       for (BitSet group : groups.getGroups())
157       {
158         groups.setColorForGroup(group, ColorUtils.getARandomColor());
159       }
160     }
161   }
162
163   default void transferGroupColorsTo(AlignmentAnnotation aa)
164   {
165     if (hasGroupSet())
166     {
167       GroupSetI groups = getGroupSet();
168       // stash colors in linked annotation row.
169       // doesn't work yet. TESTS!
170       int sstart = aa.sequenceRef != null ? aa.sequenceRef.getStart() - 1
171               : 0;
172       Annotation ae;
173       Color gpcol = null;
174       int[] seqpos = null;
175       for (BitSet gp : groups.getGroups())
176       {
177         gpcol = groups.getColourForGroup(gp);
178         for (int p = gp.nextSetBit(0); p >= 0
179                 && p < Integer.MAX_VALUE; p = gp.nextSetBit(p + 1))
180         {
181           if (this instanceof MappableContactMatrixI)
182           {
183             MappableContactMatrixI mcm = (MappableContactMatrixI) this;
184             seqpos = mcm.getMappedPositionsFor(aa.sequenceRef, p);
185             if (seqpos == null)
186             {
187               // no mapping for this column.
188               continue;
189             }
190             // TODO: handle ranges...
191             ae = aa.getAnnotationForPosition(seqpos[0]);
192           }
193           else
194           {
195             ae = aa.getAnnotationForPosition(p + sstart);
196           }
197           if (ae != null)
198           {
199             ae.colour = gpcol.brighter().darker();
200           }
201         }
202       }
203     }
204   }
205
206   /**
207    * look up the colour for a column in the associated contact matrix
208    * 
209    * @return Color.white or assigned colour
210    */
211   default Color getGroupColorForPosition(int column)
212   {
213     if (hasGroupSet())
214     {
215       GroupSetI groups = getGroupSet();
216       for (BitSet gp : groups.getGroups())
217       {
218         if (gp.get(column))
219         {
220           return groups.getColourForGroup(gp);
221         }
222       }
223     }
224     return Color.white;
225   }
226
227   /**
228    * direct access to column and row position of matrix
229    * 
230    * Implementations are allowed to throw RunTimeExceptions if _column/i are out
231    * of bounds
232    * 
233    * @param column
234    * @param row
235    * @return
236    */
237   double getElementAt(int column, int row);
238
239 }