hideSequence hide all before recalc consensus
[jalview.git] / src / jalview / gui / AlignViewport.java
1  /*
2  * Jalview - A Sequence Alignment Editor and Viewer
3  * Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * as published by the Free Software Foundation; either version 2
8  * of the License, or (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
18  */
19 package jalview.gui;
20
21 import jalview.analysis.*;
22
23 import jalview.bin.*;
24
25 import jalview.datamodel.*;
26
27 import jalview.schemes.*;
28
29 import java.awt.*;
30
31 import java.util.*;
32
33
34 /**
35  * DOCUMENT ME!
36  *
37  * @author $author$
38  * @version $Revision$
39  */
40 public class AlignViewport
41 {
42     int startRes;
43     int endRes;
44     int startSeq;
45     int endSeq;
46     boolean showJVSuffix = true;
47     boolean showText = true;
48     boolean showColourText = false;
49     boolean showBoxes = true;
50     boolean wrapAlignment = false;
51     boolean renderGaps = true;
52     boolean showSequenceFeatures = false;
53     boolean showAnnotation = true;
54     boolean showConservation = true;
55     boolean showQuality = true;
56     boolean showIdentity = true;
57     boolean colourAppliesToAllGroups = true;
58     ColourSchemeI globalColourScheme = null;
59     boolean conservationColourSelected = false;
60     boolean abovePIDThreshold = false;
61     SequenceGroup selectionGroup;
62     int charHeight;
63     int charWidth;
64     boolean validCharWidth;
65     int wrappedWidth;
66     Font font;
67     AlignmentI alignment;
68     ColumnSelection colSel = new ColumnSelection();
69     int threshold;
70     int increment;
71     NJTree currentTree = null;
72     boolean scaleAboveWrapped = false;
73     boolean scaleLeftWrapped = true;
74     boolean scaleRightWrapped = true;
75     boolean hasHiddenColumns = false;
76     boolean hasHiddenRows = false;
77     boolean showHiddenMarkers = true;
78
79     boolean cursorMode = false;
80
81     // The following vector holds the features which are
82     // currently visible, in the correct order or rendering
83     Hashtable featuresDisplayed = null;
84
85
86     /** DOCUMENT ME!! */
87     public Vector vconsensus;
88     AlignmentAnnotation consensus;
89     AlignmentAnnotation conservation;
90     AlignmentAnnotation quality;
91     boolean autoCalculateConsensus = true;
92
93     /** DOCUMENT ME!! */
94     public int ConsPercGaps = 25; // JBPNote : This should be a scalable property!
95
96     // JBPNote Prolly only need this in the applet version.
97     private java.beans.PropertyChangeSupport changeSupport = new java.beans.PropertyChangeSupport(this);
98
99     boolean ignoreGapsInConsensusCalculation = false;
100
101     boolean isDataset = false;
102
103     boolean antiAlias = false;
104
105     boolean padGaps = false;
106
107
108     public AlignViewport(AlignmentI al, boolean dataset)
109     {
110       isDataset = dataset;
111       setAlignment(al);
112       init();
113     }
114     /**
115      * Creates a new AlignViewport object.
116      *
117      * @param al DOCUMENT ME!
118      */
119     public AlignViewport(AlignmentI al)
120     {
121         setAlignment(al);
122         init();
123     }
124     /**
125      * Create a new AlignViewport with hidden regions
126      * @param al AlignmentI
127      * @param hiddenColumns ColumnSelection
128      */
129     public AlignViewport(AlignmentI al, ColumnSelection hiddenColumns) {
130       setAlignment(al);
131       if (hiddenColumns!=null) {
132         this.colSel = hiddenColumns;
133         if (hiddenColumns.getHiddenColumns() != null)
134           hasHiddenColumns = true;
135       }
136       init();
137     }
138
139     void init()
140     {
141         this.startRes = 0;
142         this.endRes = alignment.getWidth() - 1;
143         this.startSeq = 0;
144         this.endSeq = alignment.getHeight() - 1;
145
146       antiAlias = Cache.getDefault("ANTI_ALIAS", false);
147
148       showJVSuffix = Cache.getDefault("SHOW_JVSUFFIX", true);
149       showAnnotation = Cache.getDefault("SHOW_ANNOTATIONS", true);
150       showConservation = Cache.getDefault("SHOW_CONSERVATION", true);
151
152       showQuality = Cache.getDefault("SHOW_QUALITY", true);
153       showIdentity = Cache.getDefault("SHOW_IDENTITY", true);
154
155       autoCalculateConsensus = Cache.getDefault("AUTO_CALC_CONSENSUS", true);
156
157       padGaps = Cache.getDefault("PAD_GAPS", false);
158
159        String fontName = Cache.getDefault("FONT_NAME", "SansSerif");
160        String fontStyle = Cache.getDefault("FONT_STYLE", Font.PLAIN + "") ;
161        String fontSize = Cache.getDefault("FONT_SIZE", "10");
162
163        int style = 0;
164
165        if (fontStyle.equals("bold"))
166        {
167          style = 1;
168        }
169        else if (fontStyle.equals("italic"))
170        {
171          style = 2;
172        }
173
174        setFont(new Font(fontName, style, Integer.parseInt(fontSize)));
175
176
177        alignment.setGapCharacter( Cache.getDefault("GAP_SYMBOL", "-").charAt(0) );
178
179
180         // We must set conservation and consensus before setting colour,
181         // as Blosum and Clustal require this to be done
182         if(vconsensus==null && !isDataset)
183         {
184           updateConservation();
185           updateConsensus();
186         }
187
188         if (jalview.bin.Cache.getProperty("DEFAULT_COLOUR") != null)
189         {
190           globalColourScheme = ColourSchemeProperty.getColour(alignment,
191               jalview.bin.Cache.getProperty("DEFAULT_COLOUR"));
192
193             if (globalColourScheme instanceof UserColourScheme)
194             {
195                 globalColourScheme = UserDefinedColours.loadDefaultColours();
196                 ((UserColourScheme)globalColourScheme).setThreshold(0, getIgnoreGapsConsensus());
197             }
198
199             if (globalColourScheme != null)
200             {
201                 globalColourScheme.setConsensus(vconsensus);
202             }
203         }
204     }
205
206
207
208     /**
209      * DOCUMENT ME!
210      *
211      * @param b DOCUMENT ME!
212      */
213     public void setShowSequenceFeatures(boolean b)
214     {
215         showSequenceFeatures = b;
216     }
217
218     public boolean getShowSequenceFeatures()
219     {
220       return showSequenceFeatures;
221     }
222
223     /**
224      * DOCUMENT ME!
225      */
226     public void updateConservation()
227     {
228       if(alignment.isNucleotide())
229           return;
230
231       try{
232         Conservation cons = new jalview.analysis.Conservation("All",
233             jalview.schemes.ResidueProperties.propHash, 3,
234             alignment.getSequences(), 0, alignment.getWidth() - 1);
235         cons.calculate();
236         cons.verdict(false, ConsPercGaps);
237         cons.findQuality();
238
239         int alWidth = alignment.getWidth();
240         Annotation[] annotations = new Annotation[alWidth];
241         Annotation[] qannotations = new Annotation[alWidth];
242         String sequence = cons.getConsSequence().getSequence();
243         float minR;
244         float minG;
245         float minB;
246         float maxR;
247         float maxG;
248         float maxB;
249         minR = 0.3f;
250         minG = 0.0f;
251         minB = 0f;
252         maxR = 1.0f - minR;
253         maxG = 0.9f - minG;
254         maxB = 0f - minB; // scalable range for colouring both Conservation and Quality
255
256         float min = 0f;
257         float max = 11f;
258         float qmin = cons.qualityRange[0].floatValue();
259         float qmax = cons.qualityRange[1].floatValue();
260
261         for (int i = 0; i < alWidth; i++)
262         {
263           float value = 0;
264
265           try
266           {
267             value = Integer.parseInt(sequence.charAt(i) + "");
268           }
269           catch (Exception ex)
270           {
271             if (sequence.charAt(i) == '*')
272             {
273               value = 11;
274             }
275
276             if (sequence.charAt(i) == '+')
277             {
278               value = 10;
279             }
280           }
281
282           float vprop = value - min;
283           vprop /= max;
284           annotations[i] = new Annotation(sequence.charAt(i) + "",
285                                           String.valueOf(value), ' ', value,
286                                           new Color(minR + (maxR * vprop),
287               minG + (maxG * vprop),
288               minB + (maxB * vprop)));
289
290           // Quality calc
291           value = ( (Double) cons.quality.get(i)).floatValue();
292           vprop = value - qmin;
293           vprop /= qmax;
294           qannotations[i] = new Annotation(" ", String.valueOf(value), ' ',
295                                            value,
296                                            new Color(minR + (maxR * vprop),
297               minG + (maxG * vprop),
298               minB + (maxB * vprop)));
299         }
300
301         if (conservation == null)
302         {
303           conservation = new AlignmentAnnotation("Conservation",
304                                                  "Conservation of total alignment less than " +
305                                                  ConsPercGaps + "% gaps",
306                                                  annotations, 0f, // cons.qualityRange[0].floatValue(),
307                                                  11f, // cons.qualityRange[1].floatValue()
308                                                  AlignmentAnnotation.BAR_GRAPH);
309
310           if (showConservation)
311           {
312             alignment.addAnnotation(conservation);
313           }
314
315           quality = new AlignmentAnnotation("Quality",
316                                             "Alignment Quality based on Blosum62 scores",
317                                             qannotations,
318                                             cons.qualityRange[0].floatValue(),
319                                             cons.qualityRange[1].floatValue(),
320                                             AlignmentAnnotation.BAR_GRAPH);
321
322           if (showQuality)
323           {
324             alignment.addAnnotation(quality);
325           }
326         }
327         else
328         {
329           conservation.annotations = annotations;
330           quality.annotations = qannotations;
331           quality.graphMax = cons.qualityRange[1].floatValue();
332         }
333       }
334       catch (OutOfMemoryError error)
335       {
336         javax.swing.SwingUtilities.invokeLater(new Runnable()
337         {
338           public void run()
339           {
340             javax.swing.JOptionPane.showInternalMessageDialog(Desktop.desktop,
341                 "Out of memory calculating conservation!!"
342                 +
343                 "\nSee help files for increasing Java Virtual Machine memory."
344                 , "Out of memory",
345                 javax.swing.JOptionPane.WARNING_MESSAGE);
346           }
347         });
348
349         System.out.println("Conservation calculation: " + error);
350         System.gc();
351
352       }
353     }
354
355     /**
356      * DOCUMENT ME!
357      */
358     public void updateConsensus()
359     {
360       try{
361         Annotation[] annotations = new Annotation[alignment.getWidth()];
362
363         // this routine prevents vconsensus becoming a new object each time
364         // consenus is calculated. Important for speed of Blosum62
365         // and PID colouring of alignment
366         if (vconsensus == null)
367         {
368           vconsensus = alignment.getAAFrequency();
369         }
370         else
371         {
372           Vector temp = alignment.getAAFrequency();
373           vconsensus.clear();
374
375           Enumeration e = temp.elements();
376
377           while (e.hasMoreElements())
378           {
379             vconsensus.add(e.nextElement());
380           }
381         }
382
383         Hashtable hash = null;
384
385         for (int i = 0; i < alignment.getWidth(); i++)
386         {
387           hash = (Hashtable) vconsensus.elementAt(i);
388
389           float value = 0;
390           if (ignoreGapsInConsensusCalculation)
391             value = ( (Float) hash.get("pid_nogaps")).floatValue();
392           else
393             value = ( (Float) hash.get("pid_gaps")).floatValue();
394
395           String maxRes = hash.get("maxResidue").toString();
396           String mouseOver = hash.get("maxResidue") + " ";
397
398           if (maxRes.length() > 1)
399           {
400             mouseOver = "[" + maxRes + "] ";
401             maxRes = "+";
402           }
403
404           mouseOver += ( (int) value + "%");
405           annotations[i] = new Annotation(maxRes, mouseOver, ' ', value);
406         }
407
408         if (consensus == null)
409         {
410           consensus = new AlignmentAnnotation("Consensus", "PID",
411                                               annotations, 0f, 100f,AlignmentAnnotation.BAR_GRAPH);
412
413           if (showIdentity)
414           {
415             alignment.addAnnotation(consensus);
416           }
417         }
418         else
419         {
420           consensus.annotations = annotations;
421         }
422
423         if (globalColourScheme != null)
424           globalColourScheme.setConsensus(vconsensus);
425
426       }catch(OutOfMemoryError error)
427       {
428         javax.swing.SwingUtilities.invokeLater(new Runnable()
429         {
430           public void run()
431           {
432             javax.swing.JOptionPane.showInternalMessageDialog(Desktop.desktop,
433                 "Out of memory calculating consensus!!"
434                 +
435                 "\nSee help files for increasing Java Virtual Machine memory."
436                 , "Out of memory",
437                 javax.swing.JOptionPane.WARNING_MESSAGE);
438           }
439         });
440
441
442         System.out.println("Consensus calculation: " + error);
443         System.gc();
444       }
445
446     }
447     /**
448      * get the consensus sequence as displayed under the PID consensus annotation row.
449      * @return consensus sequence as a new sequence object
450      */
451     public SequenceI getConsensusSeq() {
452       if (consensus==null)
453         updateConsensus();
454       if (consensus==null)
455         return null;
456       StringBuffer seqs=new StringBuffer();
457       for (int i=0; i<consensus.annotations.length; i++) {
458         if (consensus.annotations[i]!=null) {
459           if (consensus.annotations[i].description.charAt(0) == '[')
460             seqs.append(consensus.annotations[i].description.charAt(1));
461           else
462             seqs.append(consensus.annotations[i].displayCharacter);
463         }
464       }
465       SequenceI sq = new Sequence("Consensus", seqs.toString());
466       sq.setDescription("Percentage Identity Consensus "+((ignoreGapsInConsensusCalculation) ? " without gaps" : ""));
467       return sq;
468     }
469     /**
470      * DOCUMENT ME!
471      *
472      * @return DOCUMENT ME!
473      */
474     public SequenceGroup getSelectionGroup()
475     {
476         return selectionGroup;
477     }
478
479     /**
480      * DOCUMENT ME!
481      *
482      * @param sg DOCUMENT ME!
483      */
484     public void setSelectionGroup(SequenceGroup sg)
485     {
486         selectionGroup = sg;
487     }
488
489     /**
490      * DOCUMENT ME!
491      *
492      * @return DOCUMENT ME!
493      */
494     public boolean getConservationSelected()
495     {
496         return conservationColourSelected;
497     }
498
499     /**
500      * DOCUMENT ME!
501      *
502      * @param b DOCUMENT ME!
503      */
504     public void setConservationSelected(boolean b)
505     {
506         conservationColourSelected = b;
507     }
508
509     /**
510      * DOCUMENT ME!
511      *
512      * @return DOCUMENT ME!
513      */
514     public boolean getAbovePIDThreshold()
515     {
516         return abovePIDThreshold;
517     }
518
519     /**
520      * DOCUMENT ME!
521      *
522      * @param b DOCUMENT ME!
523      */
524     public void setAbovePIDThreshold(boolean b)
525     {
526         abovePIDThreshold = b;
527     }
528
529     /**
530      * DOCUMENT ME!
531      *
532      * @return DOCUMENT ME!
533      */
534     public int getStartRes()
535     {
536         return startRes;
537     }
538
539     /**
540      * DOCUMENT ME!
541      *
542      * @return DOCUMENT ME!
543      */
544     public int getEndRes()
545     {
546         return endRes;
547     }
548
549     /**
550      * DOCUMENT ME!
551      *
552      * @return DOCUMENT ME!
553      */
554     public int getStartSeq()
555     {
556         return startSeq;
557     }
558
559     /**
560      * DOCUMENT ME!
561      *
562      * @param cs DOCUMENT ME!
563      */
564     public void setGlobalColourScheme(ColourSchemeI cs)
565     {
566         globalColourScheme = cs;
567     }
568
569     /**
570      * DOCUMENT ME!
571      *
572      * @return DOCUMENT ME!
573      */
574     public ColourSchemeI getGlobalColourScheme()
575     {
576         return globalColourScheme;
577     }
578
579     /**
580      * DOCUMENT ME!
581      *
582      * @param res DOCUMENT ME!
583      */
584     public void setStartRes(int res)
585     {
586         this.startRes = res;
587     }
588
589     /**
590      * DOCUMENT ME!
591      *
592      * @param seq DOCUMENT ME!
593      */
594     public void setStartSeq(int seq)
595     {
596         this.startSeq = seq;
597     }
598
599     /**
600      * DOCUMENT ME!
601      *
602      * @param res DOCUMENT ME!
603      */
604     public void setEndRes(int res)
605     {
606         if (res > (alignment.getWidth() - 1))
607         {
608             // log.System.out.println(" Corrected res from " + res + " to maximum " + (alignment.getWidth()-1));
609             res = alignment.getWidth() - 1;
610         }
611
612         if (res < 0)
613         {
614             res = 0;
615         }
616
617         this.endRes = res;
618     }
619
620     /**
621      * DOCUMENT ME!
622      *
623      * @param seq DOCUMENT ME!
624      */
625     public void setEndSeq(int seq)
626     {
627         if (seq > alignment.getHeight())
628         {
629             seq = alignment.getHeight();
630         }
631
632         if (seq < 0)
633         {
634             seq = 0;
635         }
636
637         this.endSeq = seq;
638     }
639
640     /**
641      * DOCUMENT ME!
642      *
643      * @return DOCUMENT ME!
644      */
645     public int getEndSeq()
646     {
647         return endSeq;
648     }
649
650     /**
651      * DOCUMENT ME!
652      *
653      * @param f DOCUMENT ME!
654      */
655     public void setFont(Font f)
656     {
657         font = f;
658
659         Container c = new Container();
660
661         java.awt.FontMetrics fm = c.getFontMetrics(font);
662         setCharHeight(fm.getHeight());
663         setCharWidth(fm.charWidth('M'));
664         validCharWidth = true;
665     }
666
667     /**
668      * DOCUMENT ME!
669      *
670      * @return DOCUMENT ME!
671      */
672     public Font getFont()
673     {
674         return font;
675     }
676
677     /**
678      * DOCUMENT ME!
679      *
680      * @param w DOCUMENT ME!
681      */
682     public void setCharWidth(int w)
683     {
684         this.charWidth = w;
685     }
686
687     /**
688      * DOCUMENT ME!
689      *
690      * @return DOCUMENT ME!
691      */
692     public int getCharWidth()
693     {
694         return charWidth;
695     }
696
697     /**
698      * DOCUMENT ME!
699      *
700      * @param h DOCUMENT ME!
701      */
702     public void setCharHeight(int h)
703     {
704         this.charHeight = h;
705     }
706
707     /**
708      * DOCUMENT ME!
709      *
710      * @return DOCUMENT ME!
711      */
712     public int getCharHeight()
713     {
714         return charHeight;
715     }
716
717     /**
718      * DOCUMENT ME!
719      *
720      * @param w DOCUMENT ME!
721      */
722     public void setWrappedWidth(int w)
723     {
724         this.wrappedWidth = w;
725     }
726
727     /**
728      * DOCUMENT ME!
729      *
730      * @return DOCUMENT ME!
731      */
732     public int getWrappedWidth()
733     {
734         return wrappedWidth;
735     }
736
737
738     /**
739      * DOCUMENT ME!
740      *
741      * @return DOCUMENT ME!
742      */
743     public AlignmentI getAlignment()
744     {
745         return alignment;
746     }
747
748     /**
749      * DOCUMENT ME!
750      *
751      * @param align DOCUMENT ME!
752      */
753     public void setAlignment(AlignmentI align)
754     {
755         this.alignment = align;
756     }
757
758     /**
759      * DOCUMENT ME!
760      *
761      * @param state DOCUMENT ME!
762      */
763     public void setWrapAlignment(boolean state)
764     {
765         wrapAlignment = state;
766     }
767
768     /**
769      * DOCUMENT ME!
770      *
771      * @param state DOCUMENT ME!
772      */
773     public void setShowText(boolean state)
774     {
775         showText = state;
776     }
777
778     /**
779      * DOCUMENT ME!
780      *
781      * @param state DOCUMENT ME!
782      */
783     public void setRenderGaps(boolean state)
784     {
785         renderGaps = state;
786     }
787
788     /**
789      * DOCUMENT ME!
790      *
791      * @return DOCUMENT ME!
792      */
793     public boolean getColourText()
794     {
795         return showColourText;
796     }
797
798     /**
799      * DOCUMENT ME!
800      *
801      * @param state DOCUMENT ME!
802      */
803     public void setColourText(boolean state)
804     {
805         showColourText = state;
806     }
807
808     /**
809      * DOCUMENT ME!
810      *
811      * @param state DOCUMENT ME!
812      */
813     public void setShowBoxes(boolean state)
814     {
815         showBoxes = state;
816     }
817
818     /**
819      * DOCUMENT ME!
820      *
821      * @return DOCUMENT ME!
822      */
823     public boolean getWrapAlignment()
824     {
825         return wrapAlignment;
826     }
827
828     /**
829      * DOCUMENT ME!
830      *
831      * @return DOCUMENT ME!
832      */
833     public boolean getShowText()
834     {
835         return showText;
836     }
837
838     /**
839      * DOCUMENT ME!
840      *
841      * @return DOCUMENT ME!
842      */
843     public boolean getShowBoxes()
844     {
845         return showBoxes;
846     }
847
848     /**
849      * DOCUMENT ME!
850      *
851      * @return DOCUMENT ME!
852      */
853     public char getGapCharacter()
854     {
855         return getAlignment().getGapCharacter();
856     }
857
858     /**
859      * DOCUMENT ME!
860      *
861      * @param gap DOCUMENT ME!
862      */
863     public void setGapCharacter(char gap)
864     {
865         if (getAlignment() != null)
866         {
867             getAlignment().setGapCharacter(gap);
868         }
869     }
870
871     /**
872      * DOCUMENT ME!
873      *
874      * @param thresh DOCUMENT ME!
875      */
876     public void setThreshold(int thresh)
877     {
878         threshold = thresh;
879     }
880
881     /**
882      * DOCUMENT ME!
883      *
884      * @return DOCUMENT ME!
885      */
886     public int getThreshold()
887     {
888         return threshold;
889     }
890
891     /**
892      * DOCUMENT ME!
893      *
894      * @param inc DOCUMENT ME!
895      */
896     public void setIncrement(int inc)
897     {
898         increment = inc;
899     }
900
901     /**
902      * DOCUMENT ME!
903      *
904      * @return DOCUMENT ME!
905      */
906     public int getIncrement()
907     {
908         return increment;
909     }
910
911
912     /**
913      * DOCUMENT ME!
914      *
915      * @return DOCUMENT ME!
916      */
917     public ColumnSelection getColumnSelection()
918     {
919         return colSel;
920     }
921
922
923     /**
924      * DOCUMENT ME!
925      *
926      * @param tree DOCUMENT ME!
927      */
928     public void setCurrentTree(NJTree tree)
929     {
930         currentTree = tree;
931     }
932
933     /**
934      * DOCUMENT ME!
935      *
936      * @return DOCUMENT ME!
937      */
938     public NJTree getCurrentTree()
939     {
940         return currentTree;
941     }
942
943     /**
944      * DOCUMENT ME!
945      *
946      * @param b DOCUMENT ME!
947      */
948     public void setColourAppliesToAllGroups(boolean b)
949     {
950         colourAppliesToAllGroups = b;
951     }
952
953     /**
954      * DOCUMENT ME!
955      *
956      * @return DOCUMENT ME!
957      */
958     public boolean getColourAppliesToAllGroups()
959     {
960         return colourAppliesToAllGroups;
961     }
962
963     /**
964      * DOCUMENT ME!
965      *
966      * @return DOCUMENT ME!
967      */
968     public boolean getShowJVSuffix()
969     {
970         return showJVSuffix;
971     }
972
973     /**
974      * DOCUMENT ME!
975      *
976      * @param b DOCUMENT ME!
977      */
978     public void setShowJVSuffix(boolean b)
979     {
980         showJVSuffix = b;
981     }
982
983
984     /**
985      * DOCUMENT ME!
986      *
987      * @return DOCUMENT ME!
988      */
989     public boolean getShowAnnotation()
990     {
991         return showAnnotation;
992     }
993
994     /**
995      * DOCUMENT ME!
996      *
997      * @param b DOCUMENT ME!
998      */
999     public void setShowAnnotation(boolean b)
1000     {
1001         showAnnotation = b;
1002     }
1003
1004     /**
1005      * DOCUMENT ME!
1006      *
1007      * @return DOCUMENT ME!
1008      */
1009     public boolean getScaleAboveWrapped()
1010     {
1011         return scaleAboveWrapped;
1012     }
1013
1014     /**
1015      * DOCUMENT ME!
1016      *
1017      * @return DOCUMENT ME!
1018      */
1019     public boolean getScaleLeftWrapped()
1020     {
1021         return scaleLeftWrapped;
1022     }
1023
1024     /**
1025      * DOCUMENT ME!
1026      *
1027      * @return DOCUMENT ME!
1028      */
1029     public boolean getScaleRightWrapped()
1030     {
1031         return scaleRightWrapped;
1032     }
1033
1034     /**
1035      * DOCUMENT ME!
1036      *
1037      * @param b DOCUMENT ME!
1038      */
1039     public void setScaleAboveWrapped(boolean b)
1040     {
1041         scaleAboveWrapped = b;
1042     }
1043
1044     /**
1045      * DOCUMENT ME!
1046      *
1047      * @param b DOCUMENT ME!
1048      */
1049     public void setScaleLeftWrapped(boolean b)
1050     {
1051         scaleLeftWrapped = b;
1052     }
1053
1054     /**
1055      * DOCUMENT ME!
1056      *
1057      * @param b DOCUMENT ME!
1058      */
1059     public void setScaleRightWrapped(boolean b)
1060     {
1061         scaleRightWrapped = b;
1062     }
1063
1064     /**
1065      * Property change listener for changes in alignment
1066      *
1067      * @param listener DOCUMENT ME!
1068      */
1069     public void addPropertyChangeListener(
1070         java.beans.PropertyChangeListener listener)
1071     {
1072         changeSupport.addPropertyChangeListener(listener);
1073     }
1074
1075     /**
1076      * DOCUMENT ME!
1077      *
1078      * @param listener DOCUMENT ME!
1079      */
1080     public void removePropertyChangeListener(
1081         java.beans.PropertyChangeListener listener)
1082     {
1083         changeSupport.removePropertyChangeListener(listener);
1084     }
1085
1086     /**
1087      * Property change listener for changes in alignment
1088      *
1089      * @param prop DOCUMENT ME!
1090      * @param oldvalue DOCUMENT ME!
1091      * @param newvalue DOCUMENT ME!
1092      */
1093     public void firePropertyChange(String prop, Object oldvalue, Object newvalue)
1094     {
1095         changeSupport.firePropertyChange(prop, oldvalue, newvalue);
1096     }
1097
1098     public void setIgnoreGapsConsensus(boolean b)
1099     {
1100       ignoreGapsInConsensusCalculation = b;
1101       updateConsensus();
1102       if(globalColourScheme!=null)
1103       {
1104         globalColourScheme.setThreshold(globalColourScheme.getThreshold(), ignoreGapsInConsensusCalculation);
1105       }
1106     }
1107
1108     public boolean getIgnoreGapsConsensus()
1109     {
1110      return ignoreGapsInConsensusCalculation;
1111     }
1112
1113     public void setDataset(boolean b)
1114     {
1115       isDataset = b;
1116     }
1117
1118     public boolean isDataset()
1119     {
1120       return isDataset;
1121     }
1122
1123
1124     public void hideSelectedColumns()
1125     {
1126       if (colSel.size() < 1)
1127         return;
1128
1129       colSel.hideSelectedColumns();
1130       setSelectionGroup(null);
1131
1132       hasHiddenColumns = true;
1133     }
1134
1135
1136     public void hideColumns(int start, int end)
1137     {
1138       if(start==end)
1139         colSel.hideColumns(start);
1140       else
1141         colSel.hideColumns(start, end);
1142
1143       hasHiddenColumns = true;
1144     }
1145
1146     public void hideAllSelectedSeqs()
1147     {
1148       if (selectionGroup == null)
1149         return;
1150
1151       SequenceI[] seqs = selectionGroup.getSequencesInOrder(alignment);
1152
1153       hideSequence(seqs);
1154
1155       setSelectionGroup(null);
1156     }
1157
1158     public void hideSequence(SequenceI [] seq)
1159     {
1160       if(seq!=null)
1161       {
1162         for (int i = 0; i < seq.length; i++)
1163           alignment.getHiddenSequences().hideSequence(seq[i]);
1164
1165         hasHiddenRows = true;
1166         firePropertyChange("alignment", null, alignment.getSequences());
1167       }
1168     }
1169
1170     public void showSequence(int index)
1171     {
1172       Vector tmp = alignment.getHiddenSequences().showSequence(index);
1173       if(tmp.size()>0)
1174       {
1175         if(selectionGroup==null)
1176         {
1177           selectionGroup = new SequenceGroup();
1178           selectionGroup.setEndRes(alignment.getWidth()-1);
1179         }
1180
1181         for (int t = 0; t < tmp.size(); t++)
1182         {
1183           selectionGroup.addSequence(
1184               (SequenceI) tmp.elementAt(t), false
1185               );
1186         }
1187         firePropertyChange("alignment", null, alignment.getSequences());
1188       }
1189
1190       if(alignment.getHiddenSequences().getSize()<1)
1191         hasHiddenRows = false;
1192     }
1193
1194     public void showColumn(int col)
1195     {
1196       colSel.revealHiddenColumns(col);
1197       if(colSel.getHiddenColumns()==null)
1198         hasHiddenColumns = false;
1199     }
1200
1201     public void showAllHiddenColumns()
1202     {
1203       colSel.revealAllHiddenColumns();
1204       hasHiddenColumns = false;
1205     }
1206
1207     public void showAllHiddenSeqs()
1208     {
1209       if(alignment.getHiddenSequences().getSize()>0)
1210       {
1211         if(selectionGroup==null)
1212         {
1213           selectionGroup = new SequenceGroup();
1214           selectionGroup.setEndRes(alignment.getWidth()-1);
1215         }
1216         Vector tmp = alignment.getHiddenSequences().showAll();
1217         for(int t=0; t<tmp.size(); t++)
1218         {
1219           selectionGroup.addSequence(
1220               (SequenceI)tmp.elementAt(t), false
1221               );
1222         }
1223         firePropertyChange("alignment", null, alignment.getSequences());
1224         hasHiddenRows = false;
1225       }
1226     }
1227
1228     public void invertColumnSelection()
1229     {
1230       int column;
1231       for(int i=0; i<alignment.getWidth(); i++)
1232       {
1233         column = i;
1234
1235         if(colSel.contains(column))
1236           colSel.removeElement(column);
1237         else
1238           colSel.addElement(column);
1239
1240       }
1241
1242     }
1243
1244     public int adjustForHiddenSeqs(int alignmentIndex)
1245     {
1246       return alignment.getHiddenSequences().adjustForHiddenSeqs(alignmentIndex);
1247     }
1248
1249     /**
1250      * This method returns the a new SequenceI [] with
1251      * the selection sequence and start and end points adjusted
1252      * @return String[]
1253      */
1254     public SequenceI[] getSelectionAsNewSequence()
1255     {
1256       SequenceI[] sequences;
1257
1258       if (selectionGroup == null)
1259         sequences = alignment.getSequencesArray();
1260       else
1261         sequences = selectionGroup.getSelectionAsNewSequences(alignment);
1262
1263       return sequences;
1264     }
1265
1266     /**
1267      * This method returns the visible alignment as text, as
1268      * seen on the GUI, ie if columns are hidden they will not
1269      * be returned in the result.
1270      * Use this for calculating trees, PCA, redundancy etc on views
1271      * which contain hidden columns.
1272      * @return String[]
1273      */
1274     public jalview.datamodel.CigarArray getViewAsCigars(boolean selectedRegionOnly)
1275     {
1276       CigarArray selection=null;
1277       SequenceI [] seqs= null;
1278       int i, iSize;
1279       int start = 0, end = 0;
1280       if(selectedRegionOnly && selectionGroup!=null)
1281       {
1282         iSize = selectionGroup.getSize(false);
1283         seqs = selectionGroup.getSequencesInOrder(alignment);
1284         start = selectionGroup.getStartRes();
1285         end = selectionGroup.getEndRes(); // inclusive for start and end in SeqCigar constructor
1286       }
1287       else
1288       {
1289         iSize = alignment.getHeight();
1290         seqs = alignment.getSequencesArray();
1291         end = alignment.getWidth()-1;
1292       }
1293       SeqCigar[] selseqs = new SeqCigar[iSize];
1294       for(i=0; i<iSize; i++)
1295       {
1296         selseqs[i] = new SeqCigar(seqs[i], start, end);
1297       }
1298       selection=new CigarArray(selseqs);
1299       // now construct the CigarArray operations
1300       if (hasHiddenColumns) {
1301         Vector regions = colSel.getHiddenColumns();
1302         int [] region;
1303         int hideStart, hideEnd;
1304         int last=start;
1305         for (int j = 0; last<end & j < regions.size(); j++)
1306         {
1307           region = (int[]) regions.elementAt(j);
1308           hideStart = region[0];
1309           hideEnd = region[1];
1310           // edit hidden regions to selection range
1311           if(hideStart<last) {
1312             if (hideEnd > last)
1313             {
1314               hideStart = last;
1315             } else
1316               continue;
1317           }
1318
1319           if (hideStart>end)
1320             break;
1321
1322           if (hideEnd>end)
1323             hideEnd=end;
1324
1325           if (hideStart>hideEnd)
1326             break;
1327           /**
1328            * form operations...
1329            */
1330           if (last<hideStart)
1331             selection.addOperation(CigarArray.M, hideStart-last);
1332           selection.addOperation(CigarArray.D, 1+hideEnd-hideStart);
1333           last = hideEnd+1;
1334         }
1335         // Final match if necessary.
1336         if (last<end)
1337           selection.addOperation(CigarArray.M, end-last);
1338       } else {
1339         selection.addOperation(CigarArray.M, end-start);
1340       }
1341       return selection;
1342     }
1343     /**
1344      * return a compact representation of the current alignment selection to
1345      * pass to an analysis function
1346      * @param selectedOnly boolean true to just return the selected view
1347      * @return AlignmentView
1348      */
1349     jalview.datamodel.AlignmentView getAlignmentView(boolean selectedOnly) {
1350       // JBPNote:
1351       // this is here because the AlignmentView constructor modifies the CigarArray
1352       // object. Refactoring of Cigar and alignment view representation should
1353       // be done to remove redundancy.
1354       CigarArray aligview = getViewAsCigars(selectedOnly);
1355       if (aligview!=null)
1356         return new AlignmentView(aligview);
1357       return null;
1358     }
1359     /**
1360      * This method returns the visible alignment as text, as
1361      * seen on the GUI, ie if columns are hidden they will not
1362      * be returned in the result.
1363      * Use this for calculating trees, PCA, redundancy etc on views
1364      * which contain hidden columns.
1365      * @return String[]
1366      */
1367     public String [] getViewAsString(boolean selectedRegionOnly)
1368     {
1369       String [] selection = null;
1370       SequenceI [] seqs= null;
1371       int i, iSize;
1372       int start = 0, end = 0;
1373       if(selectedRegionOnly && selectionGroup!=null)
1374       {
1375         iSize = selectionGroup.getSize(false);
1376         seqs = selectionGroup.getSequencesInOrder(alignment);
1377         start = selectionGroup.getStartRes();
1378         end = selectionGroup.getEndRes()+1;
1379       }
1380       else
1381       {
1382         iSize = alignment.getHeight();
1383         seqs = alignment.getSequencesArray();
1384         end = alignment.getWidth();
1385       }
1386
1387       selection = new String[iSize];
1388       if (hasHiddenColumns) {
1389         selection = colSel.getVisibleSequenceStrings(start, end, seqs);
1390       } else {
1391         for(i=0; i<iSize; i++)
1392         {
1393           selection[i] = seqs[i].getSequence(start, end);
1394         }
1395
1396       }
1397       return selection;
1398     }
1399
1400     public boolean getShowHiddenMarkers()
1401     {
1402       return showHiddenMarkers;
1403     }
1404
1405     public void setShowHiddenMarkers(boolean show)
1406     {
1407       showHiddenMarkers = show;
1408     }
1409 }