2 * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3 * Copyright (C) $$Year-Rel$$ The Jalview Authors
5 * This file is part of Jalview.
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.
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.
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.
21 package jalview.renderer;
23 import java.awt.Color;
24 import java.awt.Graphics;
26 import jalview.api.AlignViewportI;
27 import jalview.datamodel.AlignmentAnnotation;
28 import jalview.datamodel.Annotation;
29 import jalview.datamodel.ColumnSelection;
30 import jalview.datamodel.ContactListI;
31 import jalview.datamodel.ContactMatrixI;
32 import jalview.datamodel.ContactRange;
33 import jalview.datamodel.HiddenColumns;
34 import jalview.renderer.api.AnnotationRowRendererI;
40 public abstract class ContactMapRenderer implements AnnotationRowRendererI
43 * bean holding colours for shading
51 * shown when no data available from map
56 * shown for region not currently visible - should normally not see this
61 * linear shading scheme min/max
63 Color maxColor, minColor;
66 * linear shading scheme min/max for selected region
68 Color selMinColor, selMaxColor;
73 * - colour when no data available
75 * - colour if this row is hidden
77 * - colour for maximum value of contact
79 * - colour for minimum value of contact
81 * - min colour if the contact has been selected
83 * - max colour if contact is selected
85 public Shading(Color no_data, Color hidden, Color maxColor,
86 Color minColor, Color selMinColor, Color selMaxColor)
89 this.no_data = no_data;
91 this.maxColor = maxColor;
92 this.minColor = minColor;
93 this.selMinColor = selMinColor;
94 this.selMaxColor = selMaxColor;
102 * build an EBI-AlphaFold style renderer of PAE matrices
106 public static ContactMapRenderer newPAERenderer()
108 return new ContactMapRenderer()
111 public Shading getShade()
113 return new Shading(Color.pink, Color.red,
115 new Color(247, 252, 245), new Color(0, 68, 28),
116 new Color(28, 0, 68), new Color(245, 247, 252));
123 * @return instance of Shading used to initialise the renderer
125 public abstract Shading getShade();
127 public ContactMapRenderer()
129 this.shade = getShade();
133 public void renderRow(Graphics g, int charWidth, int charHeight,
134 boolean hasHiddenColumns, AlignViewportI viewport,
135 HiddenColumns hiddenColumns, ColumnSelection columnSelection,
136 AlignmentAnnotation _aa, Annotation[] aa_annotations, int sRes,
137 int eRes, float min, float max, int y)
139 if (sRes > aa_annotations.length)
143 eRes = Math.min(eRes, aa_annotations.length);
147 // uncomment below to render whole area of matrix as pink
148 // g.setColor(shade.no_data);
149 // g.fillRect(x, topY-_aa.height, (eRes - sRes) * charWidth,
152 boolean showGroups = _aa.isShowGroupsForContactMatrix();
154 int aaMax = aa_annotations.length - 1;
155 ContactMatrixI cm = viewport.getContactMatrix(_aa);
160 while (x < eRes - sRes)
163 if (hasHiddenColumns)
165 column = hiddenColumns.visibleToAbsoluteColumn(column);
167 // TODO: highlight columns selected
168 boolean colsel = false;
169 if (columnSelection != null)
171 colsel = columnSelection.contains(column);
179 if (aa_annotations[column] == null)
184 ContactListI contacts = viewport.getContactList(_aa, column);
185 if (contacts == null)
190 // ContactListI from viewport can map column -> group
191 Color gpcol = (cm == null) ? Color.white
192 : contacts.getColourForGroup(); // cm.getColourForGroup(cm.getGroupsFor(column));
193 // feature still in development - highlight or omit regions hidden in
194 // the alignment - currently marks them as red rows
195 boolean maskHiddenCols = false;
196 // TODO: optionally pass visible column mask to the ContactGeometry object
198 // only visible contacts to geometry
199 // Bean holding mapping from contact list to pixels
200 // TODO: allow bracketing/limiting of range on contacts to render (like
201 // visible column mask but more flexible?)
203 // COntactListI provides mapping for column -> cm-groupmapping
204 final ContactGeometry cgeom = new ContactGeometry(contacts,
207 for (int ht = 0, botY = topY
208 - _aa.height; ht < _aa.graphHeight; ht += cgeom.pixels_step)
210 ContactGeometry.contactInterval ci = cgeom.mapFor(ht);
211 // cstart = (int) Math.floor(((double) y2 - ht) * contacts_per_pixel);
212 // cend = (int) Math.min(contact_height,
213 // Math.ceil(cstart + contacts_per_pixel * pixels_step));
216 boolean rowsel = false;
217 boolean containsHidden = false;
218 if (columnSelection != null)
220 rowsel = cgeom.intersects(ci, columnSelection, hiddenColumns,
223 // TODO: show selected region
224 if (colsel || rowsel)
227 col = getSelectedColorForRange(min, max, contacts, ci.cStart,
229 if (colsel && rowsel)
231 col = new Color(col.getBlue(), col.getGreen(), col.getRed());
235 col = new Color(col.getBlue(), col.getBlue(), col.getBlue());
240 col = getColorForRange(min, max, contacts, ci.cStart, ci.cEnd);
246 if (showGroups && gpcol != null && gpcol != Color.white)
248 // todo - could overlay group as a transparent rectangle ?
249 col = new Color((int) ((col.getRed() + gpcol.getRed()) / 2f),
250 (int) ((col.getGreen() + gpcol.getGreen()) / 2f),
251 (int) ((col.getBlue() + gpcol.getBlue()) / 2f));
254 if (cgeom.pixels_step > 1)
256 g.fillRect(x * charWidth, botY + ht, charWidth,
261 g.drawLine(x * charWidth, botY + ht, (x + 1) * charWidth,
270 Color shadeFor(float min, float max, float value)
272 return jalview.util.ColorUtils.getGraduatedColour(value, 0,
273 shade.minColor, max, shade.maxColor);
276 public Color getColorForRange(float min, float max, ContactListI cl,
279 ContactRange cr = cl.getRangeFor(i, j);
280 // average for moment - probably more interested in maxIntProj though
281 return shadeFor(min, max, (float) cr.getMean());
284 public Color getSelectedColorForRange(float min, float max,
285 ContactListI cl, int i, int j)
287 ContactRange cr = cl.getRangeFor(i, j);
288 // average for moment - probably more interested in maxIntProj though
289 return jalview.util.ColorUtils.getGraduatedColour((float) cr.getMin(),
290 0, shade.selMinColor, max, shade.selMaxColor);