GPL license added
[jalview.git] / src / jalview / appletgui / AlignViewport.java
1 /*\r
2 * Jalview - A Sequence Alignment Editor and Viewer\r
3 * Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
4 *\r
5 * This program is free software; you can redistribute it and/or\r
6 * modify it under the terms of the GNU General Public License\r
7 * as published by the Free Software Foundation; either version 2\r
8 * of the License, or (at your option) any later version.\r
9 *\r
10 * This program is distributed in the hope that it will be useful,\r
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
13 * GNU General Public License for more details.\r
14 *\r
15 * You should have received a copy of the GNU General Public License\r
16 * along with this program; if not, write to the Free Software\r
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
18 */\r
19 \r
20 package jalview.appletgui;\r
21 \r
22 import java.awt.*;\r
23 import jalview.bin.*;\r
24 import jalview.analysis.*;\r
25 import jalview.datamodel.*;\r
26 import jalview.schemes.*;\r
27 import java.util.*;\r
28 \r
29 public class AlignViewport\r
30 {\r
31   int startRes;\r
32   int endRes;\r
33 \r
34   int startSeq;\r
35   int endSeq;\r
36 \r
37   boolean showFullId = true;\r
38   boolean showText=true;\r
39   boolean showColourText=false;\r
40   boolean showBoxes=true;\r
41   boolean wrapAlignment=false;\r
42   boolean renderGaps = true;\r
43   boolean showSequenceFeatures = false;\r
44   boolean showAnnotation = true;\r
45   boolean showConservation = true;\r
46   boolean showQuality = true;\r
47   boolean showConsensus = true;\r
48 \r
49   boolean colourAppliesToAllGroups = true;\r
50   ColourSchemeI globalColourScheme = null;\r
51   boolean conservationColourSelected = false;\r
52   boolean abovePIDThreshold = false;\r
53 \r
54   SequenceGroup selectionGroup = new SequenceGroup();\r
55 \r
56   int             charHeight;\r
57   int             charWidth;\r
58   int             chunkWidth;\r
59   int             chunkHeight;\r
60 \r
61   Font            font = new Font("SansSerif",Font.PLAIN,10);\r
62   AlignmentI      alignment;\r
63 \r
64   ColumnSelection colSel = new ColumnSelection();\r
65 \r
66   int threshold;\r
67   int increment;\r
68 \r
69   NJTree currentTree = null;\r
70 \r
71   boolean scaleAboveWrapped = true;\r
72   boolean scaleLeftWrapped  = true;\r
73   boolean scaleRightWrapped = true;\r
74 \r
75   public AlignViewport(AlignmentI al, JalviewLite applet)\r
76   {\r
77     setAlignment(al);\r
78     this.startRes = 0;\r
79     this.endRes = al.getWidth()-1;\r
80     this.startSeq = 0;\r
81     this.endSeq = al.getHeight()-1;\r
82     setFont(font);\r
83 \r
84 \r
85     if(applet!=null)\r
86     {\r
87       String param = applet.getParameter("showFullId");\r
88       if (param != null)\r
89         showFullId = Boolean.valueOf(param).booleanValue();\r
90 \r
91       param = applet.getParameter("showAnnotation");\r
92       if (param != null)\r
93         showAnnotation = Boolean.valueOf(param).booleanValue();\r
94 \r
95       param = applet.getParameter("showConservation");\r
96       if (param != null)\r
97         showConservation = Boolean.valueOf(param).booleanValue();\r
98 \r
99       param = applet.getParameter("showQuality");\r
100       if (param != null)\r
101         showQuality = Boolean.valueOf(param).booleanValue();\r
102 \r
103       param = applet.getParameter("showConsensus");\r
104       if (param != null)\r
105         showConsensus = Boolean.valueOf(param).booleanValue();\r
106     }\r
107     // We must set conservation and consensus before setting colour,\r
108     // as Blosum and Clustal require this to be done\r
109     updateConservation();\r
110     updateConsensus();\r
111 \r
112     if(applet!=null && applet.getParameter("defaultColour")!=null)\r
113     {\r
114       globalColourScheme = ColourSchemeProperty.getColour(alignment,\r
115           applet.getParameter("defaultColour"));\r
116       if(globalColourScheme!=null)\r
117         globalColourScheme.setConsensus( vconsensus );\r
118    }\r
119  }\r
120 \r
121 \r
122  public void showSequenceFeatures(boolean b)\r
123  {\r
124    showSequenceFeatures = b;\r
125  }\r
126 \r
127   public Vector vconsensus;\r
128   AlignmentAnnotation consensus;\r
129   AlignmentAnnotation conservation;\r
130   AlignmentAnnotation quality;\r
131 \r
132   public int ConsPercGaps = 25; // JBPNote : This should be a scalable property!\r
133 \r
134   public void updateConservation()\r
135   {\r
136     Conservation cons = new jalview.analysis.Conservation("All",\r
137         jalview.schemes.ResidueProperties.propHash, 3,\r
138         alignment.getSequences(), 0,\r
139         alignment.getWidth()-1);\r
140     cons.calculate();\r
141     cons.verdict(false, ConsPercGaps);\r
142     cons.findQuality();\r
143     int alWidth = alignment.getWidth();\r
144     Annotation [] annotations = new Annotation[alWidth];\r
145     Annotation [] qannotations = new Annotation[alWidth];\r
146     String sequence = cons.getConsSequence().getSequence();\r
147     float minR,minG,minB, maxR,maxG,maxB;\r
148     minR = 0.3f;\r
149     minG = 0.0f;\r
150     minB = 0f;\r
151     maxR = 1.0f-minR; maxG=0.9f-minG; maxB=0f-minB; // scalable range for colouring both Conservation and Quality\r
152     float min = 0f;\r
153     float max = 11f;\r
154     float qmin = cons.qualityRange[0].floatValue();\r
155     float qmax = cons.qualityRange[1].floatValue();\r
156 \r
157     for (int i = 0; i < alWidth; i++)\r
158     {\r
159       float value = 0;\r
160       try\r
161         {\r
162           value = Integer.parseInt(sequence.charAt(i) + "");\r
163         }\r
164       catch (Exception ex)\r
165         {\r
166           if (sequence.charAt(i) == '*') value = 11;\r
167           if (sequence.charAt(i) == '+') value = 10;\r
168         }\r
169       float vprop = value-min;\r
170       vprop/=max;\r
171 \r
172       annotations[i] = new Annotation(sequence.charAt(i) + "",\r
173                                       "", ' ', value, new Color(minR+maxR*vprop, minG+maxG*vprop, minB+maxB*vprop));\r
174       // Quality calc\r
175       value = ((Double) cons.quality.elementAt(i)).floatValue();\r
176       vprop = value - qmin;\r
177       vprop/=qmax;\r
178       qannotations[i] = new Annotation(" ",\r
179                                       String.valueOf(value), ' ', value, new Color(minR+maxR*vprop, minG+maxG*vprop, minB+maxB*vprop));\r
180     }\r
181 \r
182     if(conservation==null)\r
183     {\r
184       conservation = new AlignmentAnnotation("Conservation",\r
185                                              "Conservation of total alignment less than "+ConsPercGaps+"% gaps",\r
186                                              annotations,\r
187                                              0f, // cons.qualityRange[0].floatValue(),\r
188                                              11f, // cons.qualityRange[1].floatValue()\r
189                                              1);\r
190       if(showConservation)\r
191       alignment.addAnnotation(conservation);\r
192       quality = new AlignmentAnnotation("Quality",\r
193                                         "Alignment Quality based on Blosum62 scores",\r
194                                         qannotations,\r
195                                         cons.qualityRange[0].floatValue(),\r
196                                         cons.qualityRange[1].floatValue(),\r
197                                         1);\r
198       if(showQuality)\r
199         alignment.addAnnotation(quality);\r
200     }\r
201     else {\r
202       conservation.annotations = annotations;\r
203       quality.annotations = qannotations;\r
204       quality.graphMax = cons.qualityRange[1].floatValue();\r
205     }\r
206 \r
207 \r
208   }\r
209 \r
210   public void updateConsensus()\r
211   {\r
212     Annotation [] annotations = new Annotation[alignment.getWidth()];\r
213 \r
214     // this routine prevents vconsensus becoming a new object each time\r
215     // consenus is calculated. Important for speed of Blosum62\r
216     // and PID colouring of alignment\r
217     if(vconsensus == null)\r
218         vconsensus = alignment.getAAFrequency();\r
219     else\r
220     {\r
221         Vector temp = alignment.getAAFrequency();\r
222         vconsensus.removeAllElements();\r
223         Enumeration e = temp.elements();\r
224         while(e.hasMoreElements())\r
225         {\r
226           vconsensus.addElement(e.nextElement());\r
227         }\r
228     }\r
229     Hashtable hash = null;\r
230     for (int i = 0; i<alignment.getWidth(); i++)\r
231     {\r
232         hash = (Hashtable) vconsensus.elementAt(i);\r
233         float value = new Float(hash.get("maxCount").toString()).floatValue();\r
234         value /= new Float(hash.get("size").toString()).floatValue();\r
235 \r
236         value *= 100;\r
237         String maxRes = hash.get("maxResidue")+" ";\r
238         String mouseOver = hash.get("maxResidue")+" ";\r
239         if(maxRes.length()>2)\r
240         {\r
241           mouseOver = "["+maxRes+"] ";\r
242           maxRes = "+ ";\r
243         }\r
244 \r
245         mouseOver += (int)value+"%";\r
246         annotations[i] = new Annotation(maxRes, mouseOver, ' ', value);\r
247 \r
248     }\r
249 \r
250      if(consensus==null)\r
251      {\r
252        consensus = new AlignmentAnnotation("Consensus",\r
253                                            "PID", annotations, 0f, 100f, 1);\r
254        if(showConsensus)\r
255          alignment.addAnnotation(consensus);\r
256      }\r
257      else\r
258        consensus.annotations = annotations;\r
259 \r
260   }\r
261 \r
262 \r
263   public SequenceGroup getSelectionGroup()\r
264   {\r
265     return selectionGroup;\r
266   }\r
267 \r
268   public void setSelectionGroup(SequenceGroup sg)\r
269   {\r
270     selectionGroup = sg;\r
271   }\r
272 \r
273 \r
274  public boolean getConservationSelected()\r
275  {\r
276    return conservationColourSelected;\r
277  }\r
278 \r
279  public void setConservationSelected(boolean b)\r
280  {\r
281    conservationColourSelected = b;\r
282  }\r
283 \r
284  public boolean getAbovePIDThreshold()\r
285  {\r
286    return abovePIDThreshold;\r
287  }\r
288 \r
289  public void setAbovePIDThreshold(boolean b)\r
290  {\r
291    abovePIDThreshold = b;\r
292  }\r
293 \r
294   public int getStartRes() {\r
295     return startRes;\r
296   }\r
297 \r
298   public int getEndRes() {\r
299     return endRes;\r
300   }\r
301 \r
302   public int getStartSeq() {\r
303     return startSeq;\r
304   }\r
305 \r
306   public void setGlobalColourScheme(ColourSchemeI cs)\r
307   {\r
308      globalColourScheme = cs;\r
309   }\r
310 \r
311   public ColourSchemeI getGlobalColourScheme()\r
312   {\r
313     return globalColourScheme;\r
314   }\r
315 \r
316 \r
317   public void setStartRes(int res) {\r
318     this.startRes = res;\r
319   }\r
320   public void setStartSeq(int seq) {\r
321     this.startSeq = seq;\r
322   }\r
323   public void setEndRes(int res) {\r
324     if (res > alignment.getWidth()-1) {\r
325       // log.System.out.println(" Corrected res from " + res + " to maximum " + (alignment.getWidth()-1));\r
326        res = alignment.getWidth()-1;\r
327     }\r
328     if (res < 0) {\r
329       res = 0;\r
330     }\r
331     this.endRes = res;\r
332   }\r
333   public void setEndSeq(int seq) {\r
334     if (seq > alignment.getHeight()) {\r
335       seq = alignment.getHeight();\r
336     }\r
337     if (seq < 0) {\r
338       seq = 0;\r
339     }\r
340     this.endSeq = seq;\r
341   }\r
342   public int getEndSeq() {\r
343     return endSeq;\r
344   }\r
345 \r
346   public void setFont(Font f) {\r
347     font = f;\r
348     java.awt.Frame temp = new java.awt.Frame();\r
349     temp.addNotify();\r
350     java.awt.FontMetrics fm = temp.getGraphics().getFontMetrics(font);\r
351     setCharHeight(fm.getHeight());\r
352     setCharWidth(fm.charWidth('M'));\r
353   }\r
354 \r
355   public Font getFont() {\r
356     return font;\r
357   }\r
358   public void setCharWidth(int w) {\r
359     this.charWidth = w;\r
360   }\r
361   public int getCharWidth() {\r
362     return charWidth;\r
363   }\r
364   public void setCharHeight(int h) {\r
365     this.charHeight = h;\r
366   }\r
367   public int getCharHeight() {\r
368     return charHeight;\r
369   }\r
370   public void setChunkWidth(int w) {\r
371     this.chunkWidth = w;\r
372   }\r
373   public int getChunkWidth() {\r
374     return chunkWidth;\r
375   }\r
376   public void setChunkHeight(int h) {\r
377     this.chunkHeight = h;\r
378   }\r
379   public int getChunkHeight() {\r
380     return chunkHeight;\r
381   }\r
382   public AlignmentI getAlignment() {\r
383     return alignment;\r
384   }\r
385   public void setAlignment(AlignmentI align) {\r
386     this.alignment = align;\r
387   }\r
388 \r
389   public void setWrapAlignment(boolean state) {\r
390     wrapAlignment = state;\r
391   }\r
392   public void setShowText(boolean state) {\r
393     showText = state;\r
394   }\r
395 \r
396   public void setRenderGaps(boolean state){\r
397     renderGaps = state;\r
398   }\r
399 \r
400 \r
401   public boolean getColourText()\r
402   {\r
403     return showColourText;\r
404   }\r
405 \r
406   public void setColourText(boolean state)\r
407   {\r
408     showColourText = state;\r
409   }\r
410 \r
411   public void setShowBoxes(boolean state) {\r
412     showBoxes = state;\r
413   }\r
414 \r
415   public boolean getWrapAlignment() {\r
416       return wrapAlignment;\r
417   }\r
418   public boolean getShowText() {\r
419     return showText;\r
420   }\r
421   public boolean getShowBoxes() {\r
422     return showBoxes;\r
423   }\r
424 \r
425   public char getGapCharacter() {\r
426     return getAlignment().getGapCharacter();\r
427   }\r
428   public void setGapCharacter(char gap) {\r
429     if (getAlignment() != null) {\r
430       getAlignment().setGapCharacter(gap);\r
431     }\r
432   }\r
433   public void setThreshold(int thresh) {\r
434     threshold = thresh;\r
435   }\r
436   public int getThreshold() {\r
437     return threshold;\r
438   }\r
439   public void setIncrement(int inc) {\r
440     increment = inc;\r
441   }\r
442   public int getIncrement() {\r
443     return increment;\r
444   }\r
445   public int getIndex(int y) {\r
446     int y1     = 0;\r
447     int starty = getStartSeq();\r
448     int endy   = getEndSeq();\r
449 \r
450     for (int i = starty; i <= endy; i++) {\r
451       if (i < alignment.getHeight() && alignment.getSequenceAt(i) != null) {\r
452         int y2 = y1 + getCharHeight();\r
453 \r
454         if (y>=y1 && y <=y2) {\r
455           return i;\r
456         }\r
457         y1  = y2;\r
458       } else {\r
459         return -1;\r
460       }\r
461     }\r
462     return -1;\r
463   }\r
464 \r
465   public ColumnSelection getColumnSelection() {\r
466     return colSel;\r
467   }\r
468 \r
469   public void resetSeqLimits(int height) {\r
470     setEndSeq(height/getCharHeight());\r
471   }\r
472   public void setCurrentTree(NJTree tree) {\r
473       currentTree = tree;\r
474   }\r
475   public NJTree getCurrentTree() {\r
476     return currentTree;\r
477   }\r
478 \r
479 \r
480   public void setColourAppliesToAllGroups(boolean b)\r
481   {   colourAppliesToAllGroups = b; }\r
482 \r
483   public boolean getColourAppliesToAllGroups()\r
484   {return colourAppliesToAllGroups; }\r
485 \r
486   public boolean getShowFullId()\r
487   {\r
488     return showFullId;\r
489   }\r
490 \r
491   public void setShowFullId(boolean b)\r
492   {\r
493     showFullId = b;\r
494   }\r
495 \r
496   public boolean getShowAnnotation()\r
497   {\r
498     return showAnnotation;\r
499   }\r
500 \r
501   public void setShowAnnotation(boolean b)\r
502   {\r
503     showAnnotation = b;\r
504   }\r
505 \r
506   public boolean getScaleAboveWrapped()\r
507   { return scaleAboveWrapped;}\r
508 \r
509   public boolean getScaleLeftWrapped()\r
510   { return scaleLeftWrapped; }\r
511 \r
512   public boolean getScaleRightWrapped()\r
513   { return scaleRightWrapped; }\r
514 \r
515   public void setScaleAboveWrapped(boolean b)\r
516   { scaleAboveWrapped = b; }\r
517 \r
518   public void setScaleLeftWrapped(boolean b)\r
519   { scaleLeftWrapped = b; }\r
520 \r
521   public void setScaleRightWrapped(boolean b)\r
522   { scaleRightWrapped = b; }\r
523 \r
524 \r
525 }\r