aaa8a6118ae3c12ffb14f1ac4610708aff932fdd
[jalview.git] / src / jalview / renderer / ContactMapRenderer.java
1 /**
2  * 
3  */
4 package jalview.renderer;
5
6 import jalview.api.AlignViewportI;
7 import jalview.datamodel.AlignmentAnnotation;
8 import jalview.datamodel.Annotation;
9 import jalview.datamodel.ColumnSelection;
10 import jalview.datamodel.ContactListI;
11 import jalview.datamodel.ContactRange;
12 import jalview.datamodel.HiddenColumns;
13 import jalview.renderer.api.AnnotationRowRendererI;
14
15 import java.awt.Color;
16 import java.awt.Graphics;
17
18 /**
19  * @author jprocter
20  *
21  */
22 public class ContactMapRenderer implements AnnotationRowRendererI
23 {
24
25   @Override
26   public void renderRow(Graphics g, int charWidth, int charHeight,
27           boolean hasHiddenColumns, AlignViewportI viewport, HiddenColumns hiddenColumns,
28           ColumnSelection columnSelection, AlignmentAnnotation _aa,
29           Annotation[] aa_annotations, int sRes, int eRes, float min,
30           float max, int y)
31   {
32     if (sRes > aa_annotations.length)
33     {
34       return;
35     }
36     eRes = Math.min(eRes, aa_annotations.length);
37
38     int x = 0, y2 = y;
39
40     g.setColor(Color.pink);
41
42     g.drawLine(x, y2, (eRes - sRes) * charWidth, y2);
43
44     int column;
45     int aaMax = aa_annotations.length - 1;
46     while (x < eRes - sRes)
47     {
48       column = sRes + x;
49       if (hasHiddenColumns)
50       {
51         column = hiddenColumns.visibleToAbsoluteColumn(column);
52       }
53
54       if (column > aaMax)
55       {
56         break;
57       }
58
59       if (aa_annotations[column] == null)
60       {
61         x++;
62         continue;
63       }
64       if (_aa.sequenceRef != null)
65       {
66         // get the sequence position for the column
67         column = _aa.sequenceRef.findPosition(column) - 1;
68       }
69       ContactListI contacts = viewport.getContactList(_aa, column);
70       if (contacts == null)
71       {
72         return;
73       }
74       int contact_height = contacts.getContactHeight();
75       // fractional pixel height to render each contact cell
76       double pixels_per_contact = ((double) _aa.graphHeight)
77                       / (double) contact_height;
78       // fractional number of contacts covering each pixel
79       double contacts_per_pixel = 1d/pixels_per_contact;
80       // number of contacts to render at a time
81       int step = (pixels_per_contact<1) ? (int) Math.floor(contacts_per_pixel) : (int) Math.ceil(pixels_per_contact);
82       
83       int pixels_step = (int) Math.ceil(step*pixels_per_contact);
84       int cstart, cend = -1;
85       for (int ht = y2, eht = y2 - _aa.graphHeight; ht >= eht; ht -= pixels_step)
86       {
87         cstart = cend + 1;
88         cend = (int) Math.min(contact_height, cstart + step);
89         // TODO show maximum colour for range - sort of done
90         // also need a 'getMaxPosForRange(start,end)'
91         g.setColor(getColorForRange(min, max, contacts, cstart, cend));
92
93         if (pixels_step>1)
94         {
95           g.fillRect(x * charWidth, ht, charWidth, 1 + (int) pixels_step);
96         }
97         else
98         {
99           g.drawLine(x * charWidth, ht, (x + 1) * charWidth, ht);
100         }
101       }
102       x++;
103     }
104
105   }
106
107   Color minColor = Color.white, maxColor = Color.magenta;
108
109
110   Color shadeFor(float min, float max, float value)
111   {
112     return jalview.util.ColorUtils.getGraduatedColour(value, 0, minColor,
113             max, maxColor);
114   }
115
116   public Color getColorForRange(float min, float max, ContactListI cl,
117           int i, int j)
118   {
119     ContactRange cr = cl.getRangeFor(i, j);
120     // average for moment - probably more interested in maxIntProj though
121     return shadeFor(min, max, (float) cr.getMean());
122   }
123
124 }