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