4 package jalview.renderer;
7 import java.awt.Graphics;
8 import java.util.Iterator;
10 import jalview.api.AlignViewportI;
11 import jalview.datamodel.AlignmentAnnotation;
12 import jalview.datamodel.Annotation;
13 import jalview.datamodel.ColumnSelection;
14 import jalview.datamodel.ContactListI;
15 import jalview.datamodel.ContactRange;
16 import jalview.datamodel.HiddenColumns;
17 import jalview.renderer.api.AnnotationRowRendererI;
23 public abstract class ContactMapRenderer implements AnnotationRowRendererI
26 * bean holding colours for shading
33 * shown when no data available from map
37 * shown for region not currently visible - should normally not see this
41 * linear shading scheme min/max
43 Color maxColor, minColor;
46 * linear shading scheme min/max for selected region
48 Color selMinColor, selMaxColor;
50 public Shading(Color no_data, Color hidden, Color maxColor,
51 Color minColor, Color selMinColor, Color selMaxColor)
54 this.no_data = no_data;
56 this.maxColor = maxColor;
57 this.minColor = minColor;
58 this.selMinColor = selMinColor;
59 this.selMaxColor = selMaxColor;
67 * build an EBI-AlphaFold style renderer of PAE matrices
70 public static ContactMapRenderer newPAERenderer()
72 return new ContactMapRenderer()
75 public Shading getShade()
77 return new Shading(Color.pink, Color.red,
79 new Color(246, 252, 243), new Color(0, 60, 26),
80 new Color(26, 0, 60), new Color(243, 246, 252));
87 * @return instance of Shading used to initialise the renderer
89 public abstract Shading getShade();
91 public ContactMapRenderer()
93 this.shade = getShade();
97 public void renderRow(Graphics g, int charWidth, int charHeight,
98 boolean hasHiddenColumns, AlignViewportI viewport,
99 HiddenColumns hiddenColumns, ColumnSelection columnSelection,
100 AlignmentAnnotation _aa, Annotation[] aa_annotations, int sRes,
101 int eRes, float min, float max, int y)
103 if (sRes > aa_annotations.length)
107 eRes = Math.min(eRes, aa_annotations.length);
111 g.setColor(shade.no_data);
113 g.drawLine(x, y2, (eRes - sRes) * charWidth, y2);
116 int aaMax = aa_annotations.length - 1;
117 while (x < eRes - sRes)
120 if (hasHiddenColumns)
122 column = hiddenColumns.visibleToAbsoluteColumn(column);
124 // TODO: highlight columns selected
125 boolean colsel = false;
126 if (columnSelection != null)
128 colsel = columnSelection.contains(column);
136 if (aa_annotations[column] == null)
141 ContactListI contacts = viewport.getContactList(_aa, column);
142 if (contacts == null)
147 // feature still in development - highlight or omit regions hidden in
148 // the alignment - currently marks them as red rows
149 boolean maskHiddenCols = false;
150 // TODO: pass visible column mask to the ContactGeometry object so it maps
151 // only visible contacts to geometry
152 // Bean holding mapping from contact list to pixels
153 final ContactGeometry cgeom = new ContactGeometry(contacts,
156 for (int ht = y2, eht = y2
157 - _aa.graphHeight; ht >= eht; ht -= cgeom.pixels_step)
159 ContactGeometry.contactInterval ci = cgeom.mapFor(y2 - ht,
160 y2 - ht + cgeom.pixels_step);
161 // cstart = (int) Math.floor(((double) y2 - ht) * contacts_per_pixel);
162 // cend = (int) Math.min(contact_height,
163 // Math.ceil(cstart + contacts_per_pixel * pixels_step));
166 boolean rowsel = false, containsHidden = false;
167 if (columnSelection != null)
169 if (_aa.sequenceRef == null)
171 rowsel = columnSelection.intersects(ci.cStart, ci.cEnd);
175 // TODO check we have correctly mapped cstart to local sequence
177 int s = _aa.sequenceRef.findIndex(ci.cStart);
178 int e = _aa.sequenceRef.findIndex(ci.cEnd);
179 if (maskHiddenCols && hasHiddenColumns)
181 // TODO: turn into function and create test !!
182 Iterator<int[]> viscont = hiddenColumns
183 .getVisContigsIterator(s, e, false);
184 containsHidden = !viscont.hasNext();
186 if (s > 0 && s < _aa.sequenceRef.getLength())
188 rowsel = columnSelection.intersects(s, e);
193 // TODO: show selected region
194 if (colsel || rowsel)
197 col = getSelectedColorForRange(min, max, contacts, ci.cStart,
199 if (colsel && rowsel)
201 col = new Color(col.getBlue(), col.getGreen(), col.getRed());
205 col = new Color(col.getBlue(), col.getBlue(), col.getBlue());
210 col = getColorForRange(min, max, contacts, ci.cStart, ci.cEnd);
217 if (cgeom.pixels_step > 1)
219 g.fillRect(x * charWidth, ht, charWidth, 1 + cgeom.pixels_step);
223 g.drawLine(x * charWidth, ht, (x + 1) * charWidth, ht);
231 Color shadeFor(float min, float max, float value)
233 return jalview.util.ColorUtils.getGraduatedColour(value, 0, shade.minColor,
234 max, shade.maxColor);
237 public Color getColorForRange(float min, float max, ContactListI cl,
240 ContactRange cr = cl.getRangeFor(i, j);
241 // average for moment - probably more interested in maxIntProj though
242 return shadeFor(min, max, (float) cr.getMean());
245 public Color getSelectedColorForRange(float min, float max,
246 ContactListI cl, int i, int j)
248 ContactRange cr = cl.getRangeFor(i, j);
249 // average for moment - probably more interested in maxIntProj though
250 return jalview.util.ColorUtils.getGraduatedColour((float) cr.getMean(),
251 0, shade.selMinColor, max, shade.selMaxColor);