fixed tree building exception when one residue or a single column of residues is...
[jalview.git] / src / jalview / appletgui / AlignViewport.java
1 /*\r
2  * Jalview - A Sequence Alignment Editor and Viewer\r
3  * Copyright (C) 2006 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.util.*;\r
23 \r
24 import java.awt.*;\r
25 \r
26 import jalview.analysis.*;\r
27 import jalview.bin.*;\r
28 import jalview.datamodel.*;\r
29 import jalview.schemes.*;\r
30 \r
31 public class AlignViewport\r
32 {\r
33   int startRes;\r
34   int endRes;\r
35 \r
36   int startSeq;\r
37   int endSeq;\r
38 \r
39 \r
40   boolean cursorMode = false;\r
41 \r
42   boolean showJVSuffix = true;\r
43   boolean showText = true;\r
44   boolean showColourText = false;\r
45   boolean showBoxes = true;\r
46   boolean wrapAlignment = false;\r
47   boolean renderGaps = true;\r
48   boolean showSequenceFeatures = false;\r
49   boolean showAnnotation = true;\r
50   boolean showConservation = true;\r
51   boolean showQuality = true;\r
52   boolean showConsensus = true;\r
53 \r
54   boolean colourAppliesToAllGroups = true;\r
55   ColourSchemeI globalColourScheme = null;\r
56   boolean conservationColourSelected = false;\r
57   boolean abovePIDThreshold = false;\r
58 \r
59   SequenceGroup selectionGroup;\r
60 \r
61   int charHeight;\r
62   int charWidth;\r
63   int wrappedWidth;\r
64 \r
65   Font font = new Font("SansSerif", Font.PLAIN, 10);\r
66   boolean validCharWidth = true;\r
67   AlignmentI alignment;\r
68 \r
69   ColumnSelection colSel = new ColumnSelection();\r
70 \r
71   int threshold;\r
72   int increment;\r
73 \r
74   NJTree currentTree = null;\r
75 \r
76   boolean scaleAboveWrapped = true;\r
77   boolean scaleLeftWrapped = true;\r
78   boolean scaleRightWrapped = true;\r
79 \r
80   // The following vector holds the features which are\r
81  // currently visible, in the correct order or rendering\r
82   Hashtable featuresDisplayed;\r
83 \r
84   boolean hasHiddenColumns = false;\r
85   boolean hasHiddenRows = false;\r
86   boolean showHiddenMarkers = true;\r
87 \r
88 \r
89   public Vector vconsensus;\r
90   AlignmentAnnotation consensus;\r
91   AlignmentAnnotation conservation;\r
92   AlignmentAnnotation quality;\r
93 \r
94   boolean autocalculateConsensus = true;\r
95 \r
96   public int ConsPercGaps = 25; // JBPNote : This should be a scalable property!\r
97 \r
98   private java.beans.PropertyChangeSupport changeSupport = new java.beans.PropertyChangeSupport(this);\r
99 \r
100   boolean ignoreGapsInConsensusCalculation = false;\r
101 \r
102   jalview.bin.JalviewLite applet;\r
103 \r
104   boolean MAC = false;\r
105 \r
106   public AlignViewport(AlignmentI al, JalviewLite applet)\r
107   {\r
108     this.applet = applet;\r
109     setAlignment(al);\r
110     this.startRes = 0;\r
111     this.endRes = al.getWidth() - 1;\r
112     this.startSeq = 0;\r
113     this.endSeq = al.getHeight() - 1;\r
114     setFont(font);\r
115 \r
116     if(System.getProperty("os.name").startsWith("Mac"))\r
117       MAC = true;\r
118 \r
119     if (applet != null)\r
120     {\r
121       String param = applet.getParameter("showFullId");\r
122       if (param != null)\r
123       {\r
124         showJVSuffix = Boolean.valueOf(param).booleanValue();\r
125       }\r
126 \r
127       param = applet.getParameter("showAnnotation");\r
128       if (param != null)\r
129       {\r
130         showAnnotation = Boolean.valueOf(param).booleanValue();\r
131       }\r
132 \r
133       param = applet.getParameter("showConservation");\r
134       if (param != null)\r
135       {\r
136         showConservation = Boolean.valueOf(param).booleanValue();\r
137       }\r
138 \r
139       param = applet.getParameter("showQuality");\r
140       if (param != null)\r
141       {\r
142         showQuality = Boolean.valueOf(param).booleanValue();\r
143       }\r
144 \r
145       param = applet.getParameter("showConsensus");\r
146       if (param != null)\r
147       {\r
148         showConsensus = Boolean.valueOf(param).booleanValue();\r
149       }\r
150     }\r
151     // We must set conservation and consensus before setting colour,\r
152     // as Blosum and Clustal require this to be done\r
153     updateConservation();\r
154     updateConsensus();\r
155 \r
156 \r
157     if (applet != null)\r
158     {\r
159       String colour = applet.getParameter("defaultColour");\r
160 \r
161       if(colour == null)\r
162       {\r
163         colour = applet.getParameter("userDefinedColour");\r
164         if(colour !=null)\r
165           colour = "User Defined";\r
166       }\r
167 \r
168       if(colour != null)\r
169       {\r
170         globalColourScheme = ColourSchemeProperty.getColour(alignment, colour);\r
171         if (globalColourScheme != null)\r
172         {\r
173           globalColourScheme.setConsensus(vconsensus);\r
174         }\r
175       }\r
176 \r
177       if(applet.getParameter("userDefinedColour")!=null)\r
178       {\r
179         ((UserColourScheme)globalColourScheme).parseAppletParameter(\r
180             applet.getParameter("userDefinedColour"));\r
181       }\r
182 \r
183 \r
184     }\r
185   }\r
186 \r
187   public void showSequenceFeatures(boolean b)\r
188   {\r
189     showSequenceFeatures = b;\r
190   }\r
191 \r
192   public boolean getShowSequenceFeatures()\r
193   {\r
194     return showSequenceFeatures;\r
195   }\r
196 \r
197 \r
198   public void updateConservation()\r
199   {\r
200     if(alignment.isNucleotide())\r
201           return;\r
202 \r
203     Conservation cons = new jalview.analysis.Conservation("All",\r
204         jalview.schemes.ResidueProperties.propHash, 3,\r
205         alignment.getSequences(), 0,\r
206         alignment.getWidth() - 1);\r
207     cons.calculate();\r
208     cons.verdict(false, ConsPercGaps);\r
209     cons.findQuality();\r
210     int alWidth = alignment.getWidth();\r
211     Annotation[] annotations = new Annotation[alWidth];\r
212     Annotation[] qannotations = new Annotation[alWidth];\r
213     String sequence = cons.getConsSequence().getSequence();\r
214     float minR, minG, minB, maxR, maxG, maxB;\r
215     minR = 0.3f;\r
216     minG = 0.0f;\r
217     minB = 0f;\r
218     maxR = 1.0f - minR;\r
219     maxG = 0.9f - minG;\r
220     maxB = 0f - minB; // scalable range for colouring both Conservation and Quality\r
221     float min = 0f;\r
222     float max = 11f;\r
223     float qmin = cons.qualityRange[0].floatValue();\r
224     float qmax = cons.qualityRange[1].floatValue();\r
225 \r
226     for (int i = 0; i < alWidth; i++)\r
227     {\r
228       float value = 0;\r
229       try\r
230       {\r
231         value = Integer.parseInt(sequence.charAt(i) + "");\r
232       }\r
233       catch (Exception ex)\r
234       {\r
235         if (sequence.charAt(i) == '*')\r
236         {\r
237           value = 11;\r
238         }\r
239         if (sequence.charAt(i) == '+')\r
240         {\r
241           value = 10;\r
242         }\r
243       }\r
244       float vprop = value - min;\r
245       vprop /= max;\r
246 \r
247       annotations[i] = new Annotation(sequence.charAt(i) + "",\r
248                                       "", ' ', value,\r
249                                       new Color(minR + maxR * vprop,\r
250                                                 minG + maxG * vprop,\r
251                                                 minB + maxB * vprop));\r
252       // Quality calc\r
253       value = ( (Double) cons.quality.elementAt(i)).floatValue();\r
254       vprop = value - qmin;\r
255       vprop /= qmax;\r
256       qannotations[i] = new Annotation(" ",\r
257                                        String.valueOf(value), ' ', value,\r
258                                        new\r
259                                        Color(minR + maxR * vprop,\r
260                                              minG + maxG * vprop,\r
261                                              minB + maxB * vprop));\r
262     }\r
263 \r
264     if (conservation == null)\r
265     {\r
266       conservation = new AlignmentAnnotation("Conservation",\r
267                                              "Conservation of total alignment less than " +\r
268                                              ConsPercGaps + "% gaps",\r
269                                              annotations,\r
270                                              0f, // cons.qualityRange[0].floatValue(),\r
271                                              11f, // cons.qualityRange[1].floatValue()\r
272                                              AlignmentAnnotation.BAR_GRAPH);\r
273       if (showConservation)\r
274       {\r
275         alignment.addAnnotation(conservation);\r
276       }\r
277       quality = new AlignmentAnnotation("Quality",\r
278                                         "Alignment Quality based on Blosum62 scores",\r
279                                         qannotations,\r
280                                         cons.qualityRange[0].floatValue(),\r
281                                         cons.qualityRange[1].floatValue(),\r
282                                         AlignmentAnnotation.BAR_GRAPH);\r
283       if (showQuality)\r
284       {\r
285         alignment.addAnnotation(quality);\r
286       }\r
287     }\r
288     else\r
289     {\r
290       conservation.annotations = annotations;\r
291       quality.annotations = qannotations;\r
292       quality.graphMax = cons.qualityRange[1].floatValue();\r
293     }\r
294 \r
295   }\r
296 \r
297   public void updateConsensus()\r
298   {\r
299     Annotation[] annotations = new Annotation[alignment.getWidth()];\r
300 \r
301     // this routine prevents vconsensus becoming a new object each time\r
302     // consenus is calculated. Important for speed of Blosum62\r
303     // and PID colouring of alignment\r
304     if (vconsensus == null)\r
305     {\r
306       vconsensus = alignment.getAAFrequency();\r
307     }\r
308     else\r
309     {\r
310       Vector temp = alignment.getAAFrequency();\r
311       vconsensus.removeAllElements();\r
312       Enumeration e = temp.elements();\r
313       while (e.hasMoreElements())\r
314       {\r
315         vconsensus.addElement(e.nextElement());\r
316       }\r
317     }\r
318     Hashtable hash = null;\r
319     for (int i = 0; i < alignment.getWidth(); i++)\r
320     {\r
321       hash = (Hashtable) vconsensus.elementAt(i);\r
322       float value = 0;\r
323       if(ignoreGapsInConsensusCalculation)\r
324         value = ((Float)hash.get("pid_nogaps")).floatValue();\r
325       else\r
326         value = ((Float)hash.get("pid_gaps")).floatValue();\r
327 \r
328       String maxRes = hash.get("maxResidue").toString();\r
329       String mouseOver = hash.get("maxResidue") + " ";\r
330       if (maxRes.length() > 1)\r
331       {\r
332         mouseOver = "[" + maxRes + "] ";\r
333         maxRes = "+";\r
334       }\r
335 \r
336 \r
337       mouseOver += (int) value + "%";\r
338       annotations[i] = new Annotation(maxRes, mouseOver, ' ', value);\r
339 \r
340     }\r
341 \r
342     if (consensus == null)\r
343     {\r
344       consensus = new AlignmentAnnotation("Consensus",\r
345                                           "PID", annotations, 0f, 100f, AlignmentAnnotation.BAR_GRAPH);\r
346       if (showConsensus)\r
347       {\r
348         alignment.addAnnotation(consensus);\r
349       }\r
350     }\r
351     else\r
352     {\r
353       consensus.annotations = annotations;\r
354     }\r
355 \r
356     if(globalColourScheme!=null)\r
357           globalColourScheme.setConsensus(vconsensus);\r
358 \r
359   }\r
360   /**\r
361    * get the consensus sequence as displayed under the PID consensus annotation row.\r
362    * @return consensus sequence as a new sequence object\r
363    */\r
364   /**\r
365    * get the consensus sequence as displayed under the PID consensus annotation row.\r
366    * @return consensus sequence as a new sequence object\r
367    */\r
368   public SequenceI getConsensusSeq() {\r
369     if (consensus==null)\r
370       updateConsensus();\r
371     if (consensus==null)\r
372       return null;\r
373     StringBuffer seqs=new StringBuffer();\r
374     for (int i=0; i<consensus.annotations.length; i++) {\r
375       if (consensus.annotations[i]!=null) {\r
376         if (consensus.annotations[i].description.charAt(0) == '[')\r
377           seqs.append(consensus.annotations[i].description.charAt(1));\r
378         else\r
379           seqs.append(consensus.annotations[i].displayCharacter);\r
380       }\r
381     }\r
382     SequenceI sq = new Sequence("Consensus", seqs.toString());\r
383     sq.setDescription("Percentage Identity Consensus "+((ignoreGapsInConsensusCalculation) ? " without gaps" : ""));\r
384     return sq;\r
385   }\r
386   public SequenceGroup getSelectionGroup()\r
387   {\r
388     return selectionGroup;\r
389   }\r
390 \r
391   public void setSelectionGroup(SequenceGroup sg)\r
392   {\r
393     selectionGroup = sg;\r
394   }\r
395 \r
396   public boolean getConservationSelected()\r
397   {\r
398     return conservationColourSelected;\r
399   }\r
400 \r
401   public void setConservationSelected(boolean b)\r
402   {\r
403     conservationColourSelected = b;\r
404   }\r
405 \r
406   public boolean getAbovePIDThreshold()\r
407   {\r
408     return abovePIDThreshold;\r
409   }\r
410 \r
411   public void setAbovePIDThreshold(boolean b)\r
412   {\r
413     abovePIDThreshold = b;\r
414   }\r
415 \r
416   public int getStartRes()\r
417   {\r
418     return startRes;\r
419   }\r
420 \r
421   public int getEndRes()\r
422   {\r
423     return endRes;\r
424   }\r
425 \r
426   public int getStartSeq()\r
427   {\r
428     return startSeq;\r
429   }\r
430 \r
431   public void setGlobalColourScheme(ColourSchemeI cs)\r
432   {\r
433     globalColourScheme = cs;\r
434   }\r
435 \r
436   public ColourSchemeI getGlobalColourScheme()\r
437   {\r
438     return globalColourScheme;\r
439   }\r
440 \r
441   public void setStartRes(int res)\r
442   {\r
443     this.startRes = res;\r
444   }\r
445 \r
446   public void setStartSeq(int seq)\r
447   {\r
448     this.startSeq = seq;\r
449   }\r
450 \r
451   public void setEndRes(int res)\r
452   {\r
453     if (res > alignment.getWidth() - 1)\r
454     {\r
455       // log.System.out.println(" Corrected res from " + res + " to maximum " + (alignment.getWidth()-1));\r
456       res = alignment.getWidth() - 1;\r
457     }\r
458     if (res < 0)\r
459     {\r
460       res = 0;\r
461     }\r
462     this.endRes = res;\r
463   }\r
464 \r
465   public void setEndSeq(int seq)\r
466   {\r
467     if (seq > alignment.getHeight())\r
468     {\r
469       seq = alignment.getHeight();\r
470     }\r
471     if (seq < 0)\r
472     {\r
473       seq = 0;\r
474     }\r
475     this.endSeq = seq;\r
476   }\r
477 \r
478   public int getEndSeq()\r
479   {\r
480     return endSeq;\r
481   }\r
482 \r
483   java.awt.Frame nullFrame;\r
484   public void setFont(Font f)\r
485   {\r
486     font = f;\r
487     if(nullFrame == null)\r
488     {\r
489       nullFrame = new java.awt.Frame();\r
490       nullFrame.addNotify();\r
491     }\r
492 \r
493     java.awt.FontMetrics fm = nullFrame.getGraphics().getFontMetrics(font);\r
494     setCharHeight(fm.getHeight());\r
495     charWidth = fm.charWidth('M');\r
496   }\r
497 \r
498   public Font getFont()\r
499   {\r
500     return font;\r
501   }\r
502 \r
503   public int getCharWidth()\r
504   {\r
505     return charWidth;\r
506   }\r
507 \r
508   public void setCharHeight(int h)\r
509   {\r
510     this.charHeight = h;\r
511   }\r
512 \r
513   public int getCharHeight()\r
514   {\r
515     return charHeight;\r
516   }\r
517 \r
518   public void setWrappedWidth(int w)\r
519   {\r
520     this.wrappedWidth = w;\r
521   }\r
522 \r
523   public int getwrappedWidth()\r
524   {\r
525     return wrappedWidth;\r
526   }\r
527 \r
528   public AlignmentI getAlignment()\r
529   {\r
530     return alignment;\r
531   }\r
532 \r
533   public void setAlignment(AlignmentI align)\r
534   {\r
535     this.alignment = align;\r
536   }\r
537 \r
538   public void setWrapAlignment(boolean state)\r
539   {\r
540     wrapAlignment = state;\r
541   }\r
542 \r
543   public void setShowText(boolean state)\r
544   {\r
545     showText = state;\r
546   }\r
547 \r
548   public void setRenderGaps(boolean state)\r
549   {\r
550     renderGaps = state;\r
551   }\r
552 \r
553   public boolean getColourText()\r
554   {\r
555     return showColourText;\r
556   }\r
557 \r
558   public void setColourText(boolean state)\r
559   {\r
560     showColourText = state;\r
561   }\r
562 \r
563   public void setShowBoxes(boolean state)\r
564   {\r
565     showBoxes = state;\r
566   }\r
567 \r
568   public boolean getWrapAlignment()\r
569   {\r
570     return wrapAlignment;\r
571   }\r
572 \r
573   public boolean getShowText()\r
574   {\r
575     return showText;\r
576   }\r
577 \r
578   public boolean getShowBoxes()\r
579   {\r
580     return showBoxes;\r
581   }\r
582 \r
583   public char getGapCharacter()\r
584   {\r
585     return getAlignment().getGapCharacter();\r
586   }\r
587 \r
588   public void setGapCharacter(char gap)\r
589   {\r
590     if (getAlignment() != null)\r
591     {\r
592       getAlignment().setGapCharacter(gap);\r
593     }\r
594   }\r
595 \r
596   public void setThreshold(int thresh)\r
597   {\r
598     threshold = thresh;\r
599   }\r
600 \r
601   public int getThreshold()\r
602   {\r
603     return threshold;\r
604   }\r
605 \r
606   public void setIncrement(int inc)\r
607   {\r
608     increment = inc;\r
609   }\r
610 \r
611   public int getIncrement()\r
612   {\r
613     return increment;\r
614   }\r
615 \r
616   public void setHiddenColumns(ColumnSelection colsel)\r
617   {\r
618     this.colSel = colsel;\r
619     if(colSel.getHiddenColumns()!=null)\r
620       hasHiddenColumns = true;\r
621   }\r
622 \r
623   public ColumnSelection getColumnSelection()\r
624   {\r
625     return colSel;\r
626   }\r
627 \r
628   public void resetSeqLimits(int height)\r
629   {\r
630     setEndSeq(height / getCharHeight());\r
631   }\r
632 \r
633   public void setCurrentTree(NJTree tree)\r
634   {\r
635     currentTree = tree;\r
636   }\r
637 \r
638   public NJTree getCurrentTree()\r
639   {\r
640     return currentTree;\r
641   }\r
642 \r
643   public void setColourAppliesToAllGroups(boolean b)\r
644   {\r
645     colourAppliesToAllGroups = b;\r
646   }\r
647 \r
648   public boolean getColourAppliesToAllGroups()\r
649   {\r
650     return colourAppliesToAllGroups;\r
651   }\r
652 \r
653   public boolean getShowJVSuffix()\r
654   {\r
655     return showJVSuffix;\r
656   }\r
657 \r
658   public void setShowJVSuffix(boolean b)\r
659   {\r
660     showJVSuffix = b;\r
661   }\r
662 \r
663   public boolean getShowAnnotation()\r
664   {\r
665     return showAnnotation;\r
666   }\r
667 \r
668   public void setShowAnnotation(boolean b)\r
669   {\r
670     showAnnotation = b;\r
671   }\r
672 \r
673   public boolean getScaleAboveWrapped()\r
674   {\r
675     return scaleAboveWrapped;\r
676   }\r
677 \r
678   public boolean getScaleLeftWrapped()\r
679   {\r
680     return scaleLeftWrapped;\r
681   }\r
682 \r
683   public boolean getScaleRightWrapped()\r
684   {\r
685     return scaleRightWrapped;\r
686   }\r
687 \r
688   public void setScaleAboveWrapped(boolean b)\r
689   {\r
690     scaleAboveWrapped = b;\r
691   }\r
692 \r
693   public void setScaleLeftWrapped(boolean b)\r
694   {\r
695     scaleLeftWrapped = b;\r
696   }\r
697 \r
698   public void setScaleRightWrapped(boolean b)\r
699   {\r
700     scaleRightWrapped = b;\r
701   }\r
702 \r
703   public void setIgnoreGapsConsensus(boolean b)\r
704   {\r
705     ignoreGapsInConsensusCalculation = b;\r
706     updateConsensus();\r
707     if (globalColourScheme!=null)\r
708     {\r
709       globalColourScheme.setThreshold(globalColourScheme.getThreshold(),\r
710           ignoreGapsInConsensusCalculation);\r
711 \r
712     }\r
713   }\r
714 \r
715   /**\r
716    * Property change listener for changes in alignment\r
717    *\r
718    * @param listener DOCUMENT ME!\r
719    */\r
720   public void addPropertyChangeListener(\r
721       java.beans.PropertyChangeListener listener)\r
722   {\r
723       changeSupport.addPropertyChangeListener(listener);\r
724   }\r
725 \r
726   /**\r
727    * DOCUMENT ME!\r
728    *\r
729    * @param listener DOCUMENT ME!\r
730    */\r
731   public void removePropertyChangeListener(\r
732       java.beans.PropertyChangeListener listener)\r
733   {\r
734       changeSupport.removePropertyChangeListener(listener);\r
735   }\r
736 \r
737   /**\r
738    * Property change listener for changes in alignment\r
739    *\r
740    * @param prop DOCUMENT ME!\r
741    * @param oldvalue DOCUMENT ME!\r
742    * @param newvalue DOCUMENT ME!\r
743    */\r
744   public void firePropertyChange(String prop, Object oldvalue, Object newvalue)\r
745   {\r
746       changeSupport.firePropertyChange(prop, oldvalue, newvalue);\r
747   }\r
748 \r
749 \r
750 \r
751   public boolean getIgnoreGapsConsensus()\r
752   {\r
753     return ignoreGapsInConsensusCalculation;\r
754   }\r
755   public void hideSelectedColumns()\r
756   {\r
757     if (colSel.size() < 1)\r
758       return;\r
759 \r
760     colSel.hideSelectedColumns();\r
761     setSelectionGroup(null);\r
762 \r
763     hasHiddenColumns = true;\r
764   }\r
765 \r
766   public void invertColumnSelection()\r
767   {\r
768     int column;\r
769     for (int i = 0; i < alignment.getWidth(); i++)\r
770     {\r
771       column = i;\r
772 \r
773       if (colSel.contains(column))\r
774         colSel.removeElement(column);\r
775       else\r
776         colSel.addElement(column);\r
777 \r
778     }\r
779   }\r
780 \r
781 \r
782   public void hideColumns(int start, int end)\r
783   {\r
784     if(start==end)\r
785       colSel.hideColumns(start);\r
786     else\r
787       colSel.hideColumns(start, end);\r
788 \r
789     hasHiddenColumns = true;\r
790   }\r
791 \r
792   public void hideAllSelectedSeqs()\r
793   {\r
794     if (selectionGroup == null)\r
795       return;\r
796 \r
797     SequenceI[] seqs = selectionGroup.getSequencesInOrder(alignment);\r
798 \r
799     hideSequence(seqs);\r
800 \r
801     setSelectionGroup(null);\r
802   }\r
803 \r
804   public void hideSequence(SequenceI [] seq)\r
805   {\r
806     if(seq!=null)\r
807     {\r
808       for (int i = 0; i < seq.length; i++)\r
809         alignment.getHiddenSequences().hideSequence(seq[i]);\r
810 \r
811       hasHiddenRows = true;\r
812       firePropertyChange("alignment", null, alignment.getSequences());\r
813     }\r
814   }\r
815 \r
816   public void showColumn(int col)\r
817   {\r
818     colSel.revealHiddenColumns(col);\r
819     if(colSel.getHiddenColumns()==null)\r
820       hasHiddenColumns = false;\r
821   }\r
822 \r
823   public void showAllHiddenColumns()\r
824   {\r
825     colSel.revealAllHiddenColumns();\r
826     hasHiddenColumns = false;\r
827   }\r
828 \r
829   public void showAllHiddenSeqs()\r
830   {\r
831     if(alignment.getHiddenSequences().getSize()>0)\r
832     {\r
833       if(selectionGroup==null)\r
834       {\r
835         selectionGroup = new SequenceGroup();\r
836         selectionGroup.setEndRes(alignment.getWidth()-1);\r
837       }\r
838       Vector tmp = alignment.getHiddenSequences().showAll();\r
839       for(int t=0; t<tmp.size(); t++)\r
840       {\r
841         selectionGroup.addSequence(\r
842             (SequenceI)tmp.elementAt(t), false\r
843             );\r
844       }\r
845       firePropertyChange("alignment", null, alignment.getSequences());\r
846       hasHiddenRows = false;\r
847     }\r
848   }\r
849 \r
850   public int adjustForHiddenSeqs(int alignmentIndex)\r
851   {\r
852     return alignment.getHiddenSequences().adjustForHiddenSeqs(alignmentIndex);\r
853   }\r
854 \r
855   /**\r
856    * This method returns the a new SequenceI [] with\r
857    * the selection sequence and start and end points adjusted\r
858    * @return String[]\r
859    */\r
860   public SequenceI[] getSelectionAsNewSequence()\r
861   {\r
862     SequenceI[] sequences;\r
863 \r
864     if (selectionGroup == null)\r
865       sequences = alignment.getSequencesArray();\r
866     else\r
867       sequences = selectionGroup.getSelectionAsNewSequences(alignment);\r
868 \r
869     return sequences;\r
870   }\r
871 \r
872   /**\r
873    * This method returns the visible alignment as text, as\r
874    * seen on the GUI, ie if columns are hidden they will not\r
875    * be returned in the result.\r
876    * Use this for calculating trees, PCA, redundancy etc on views\r
877    * which contain hidden columns.\r
878    * @return String[]\r
879    */\r
880   public jalview.datamodel.CigarArray getViewAsCigars(boolean selectedRegionOnly)\r
881   {\r
882     CigarArray selection=null;\r
883     SequenceI [] seqs= null;\r
884     int i, iSize;\r
885     int start = 0, end = 0;\r
886     if(selectedRegionOnly && selectionGroup!=null)\r
887     {\r
888       iSize = selectionGroup.getSize(false);\r
889       seqs = selectionGroup.getSequencesInOrder(alignment);\r
890       start = selectionGroup.getStartRes();\r
891       end = selectionGroup.getEndRes(); // inclusive for start and end in SeqCigar constructor\r
892     }\r
893     else\r
894     {\r
895       iSize = alignment.getHeight();\r
896       seqs = alignment.getSequencesArray();\r
897       end = alignment.getWidth()-1;\r
898     }\r
899     SeqCigar[] selseqs = new SeqCigar[iSize];\r
900     for(i=0; i<iSize; i++)\r
901     {\r
902       selseqs[i] = new SeqCigar(seqs[i], start, end);\r
903     }\r
904     selection=new CigarArray(selseqs);\r
905     // now construct the CigarArray operations\r
906     if (hasHiddenColumns) {\r
907       Vector regions = colSel.getHiddenColumns();\r
908       int [] region;\r
909       int hideStart, hideEnd;\r
910       int last=start;\r
911       for (int j = 0; last<end & j < regions.size(); j++)\r
912       {\r
913         region = (int[]) regions.elementAt(j);\r
914         hideStart = region[0];\r
915         hideEnd = region[1];\r
916         // edit hidden regions to selection range\r
917         if(hideStart<last) {\r
918           if (hideEnd > last)\r
919           {\r
920             hideStart = last;\r
921           } else\r
922             continue;\r
923         }\r
924 \r
925         if (hideStart>end)\r
926           break;\r
927 \r
928         if (hideEnd>end)\r
929           hideEnd=end;\r
930 \r
931         if (hideStart>hideEnd)\r
932           break;\r
933         /**\r
934          * form operations...\r
935          */\r
936         if (last<hideStart)\r
937           selection.addOperation(CigarArray.M, hideStart-last);\r
938         selection.addOperation(CigarArray.D, 1+hideEnd-hideStart);\r
939         last = hideEnd+1;\r
940       }\r
941       // Final match if necessary.\r
942       if (last<end)\r
943         selection.addOperation(CigarArray.M, end-last+1);\r
944     } else {\r
945       selection.addOperation(CigarArray.M, end-start+1);\r
946     }\r
947     return selection;\r
948   }\r
949   /**\r
950    * return a compact representation of the current alignment selection to\r
951    * pass to an analysis function\r
952    * @param selectedOnly boolean true to just return the selected view\r
953    * @return AlignmentView\r
954    */\r
955   jalview.datamodel.AlignmentView getAlignmentView(boolean selectedOnly) {\r
956     // JBPNote:\r
957     // this is here because the AlignmentView constructor modifies the CigarArray\r
958     // object. Refactoring of Cigar and alignment view representation should\r
959     // be done to remove redundancy.\r
960     CigarArray aligview = getViewAsCigars(selectedOnly);\r
961     if (aligview!=null)\r
962       return new AlignmentView(aligview);\r
963     return null;\r
964   }\r
965   /**\r
966    * This method returns the visible alignment as text, as\r
967    * seen on the GUI, ie if columns are hidden they will not\r
968    * be returned in the result.\r
969    * Use this for calculating trees, PCA, redundancy etc on views\r
970    * which contain hidden columns.\r
971    * @return String[]\r
972    */\r
973   public String [] getViewAsString(boolean selectedRegionOnly)\r
974   {\r
975     String [] selection = null;\r
976     SequenceI [] seqs= null;\r
977     int i, iSize;\r
978     int start = 0, end = 0;\r
979     if(selectedRegionOnly && selectionGroup!=null)\r
980     {\r
981       iSize = selectionGroup.getSize(false);\r
982       seqs = selectionGroup.getSequencesInOrder(alignment);\r
983       start = selectionGroup.getStartRes();\r
984       end = selectionGroup.getEndRes()+1;\r
985     }\r
986     else\r
987     {\r
988       iSize = alignment.getHeight();\r
989       seqs = alignment.getSequencesArray();\r
990       end = alignment.getWidth();\r
991     }\r
992 \r
993     selection = new String[iSize];\r
994 \r
995 \r
996     for(i=0; i<iSize; i++)\r
997     {\r
998       if (hasHiddenColumns)\r
999       {\r
1000            StringBuffer visibleSeq = new StringBuffer();\r
1001            Vector regions = colSel.getHiddenColumns();\r
1002 \r
1003            int blockStart = start, blockEnd=end;\r
1004            int [] region;\r
1005            int hideStart, hideEnd;\r
1006 \r
1007            for (int j = 0; j < regions.size(); j++)\r
1008            {\r
1009              region = (int[]) regions.elementAt(j);\r
1010              hideStart = region[0];\r
1011              hideEnd = region[1];\r
1012 \r
1013              if(hideStart < start)\r
1014              {\r
1015                continue;\r
1016              }\r
1017 \r
1018              blockStart = Math.min(blockStart, hideEnd+1);\r
1019              blockEnd = Math.min(blockEnd, hideStart);\r
1020 \r
1021              if(blockStart>blockEnd)\r
1022              {\r
1023                 break;\r
1024              }\r
1025 \r
1026 \r
1027              visibleSeq.append(seqs[i].getSequence(blockStart, blockEnd));\r
1028 \r
1029              blockStart = hideEnd+1;\r
1030              blockEnd = end;\r
1031            }\r
1032 \r
1033            if(end>blockStart)\r
1034              visibleSeq.append(seqs[i].getSequence(blockStart, end));\r
1035 \r
1036            selection[i] = visibleSeq.toString();\r
1037       }\r
1038       else\r
1039       {\r
1040         selection[i] = seqs[i].getSequence(start, end);\r
1041       }\r
1042     }\r
1043 \r
1044     return selection;\r
1045   }\r
1046 \r
1047   public boolean getShowHiddenMarkers()\r
1048   {\r
1049     return showHiddenMarkers;\r
1050   }\r
1051 \r
1052   public void setShowHiddenMarkers(boolean show)\r
1053   {\r
1054     showHiddenMarkers = show;\r
1055   }\r
1056 \r
1057 \r
1058 }\r