colourText = false
[jalview.git] / src / jalview / datamodel / SequenceGroup.java
1 /*
2  * Jalview - A Sequence Alignment Editor and Viewer
3  * Copyright (C) 2007 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.datamodel;
20
21 import java.util.*;
22
23 import java.awt.*;
24
25 import jalview.analysis.*;
26 import jalview.schemes.*;
27
28 /**
29  * DOCUMENT ME!
30  *
31  * @author $author$
32  * @version $Revision$
33  */
34 public class SequenceGroup
35 {
36   String groupName;
37   String description;
38   Conservation conserve;
39   Vector aaFrequency;
40   boolean displayBoxes = true;
41   boolean displayText = true;
42   boolean colourText = false;
43   private Vector sequences = new Vector();
44   int width = -1;
45
46   /** DOCUMENT ME!! */
47   public ColourSchemeI cs;
48   int startRes = 0;
49   int endRes = 0;
50   Color outlineColour = Color.black;
51   public int thresholdTextColour = 0;
52   public Color textColour = Color.black;
53   public Color textColour2 = Color.white;
54
55   /**
56    * Creates a new SequenceGroup object.
57    */
58   public SequenceGroup()
59   {
60     groupName = "JGroup:" + this.hashCode();
61   }
62
63   /**
64    * Creates a new SequenceGroup object.
65    *
66    * @param sequences DOCUMENT ME!
67    * @param groupName DOCUMENT ME!
68    * @param scheme DOCUMENT ME!
69    * @param displayBoxes DOCUMENT ME!
70    * @param displayText DOCUMENT ME!
71    * @param colourText DOCUMENT ME!
72    * @param start DOCUMENT ME!
73    * @param end DOCUMENT ME!
74    */
75   public SequenceGroup(Vector sequences, String groupName,
76                        ColourSchemeI scheme, boolean displayBoxes,
77                        boolean displayText,
78                        boolean colourText, int start, int end)
79   {
80     this.sequences = sequences;
81     this.groupName = groupName;
82     this.displayBoxes = displayBoxes;
83     this.displayText = displayText;
84     this.colourText = colourText;
85     this.cs = scheme;
86     startRes = start;
87     endRes = end;
88     recalcConservation();
89   }
90
91   public SequenceI[] getSelectionAsNewSequences(AlignmentI align)
92   {
93     int iSize = sequences.size();
94     SequenceI[] seqs = new SequenceI[iSize];
95     SequenceI[] inorder = getSequencesInOrder(align);
96
97     for (int i = 0; i < iSize; i++)
98     {
99       SequenceI seq = inorder[i];
100
101       seqs[i] = seq.getSubSequence(startRes, endRes+1);
102
103       seqs[i].setDescription(seq.getDescription());
104       seqs[i].setDBRef(seq.getDBRef());
105       seqs[i].setSequenceFeatures(seq.getSequenceFeatures());
106       if (seq.getDatasetSequence() != null)
107       {
108         seqs[i].setDatasetSequence(seq.getDatasetSequence());
109       }
110
111       if (seq.getAnnotation() != null)
112       {
113         for (int a = 0; a < seq.getAnnotation().length; a++)
114         {
115           AlignmentAnnotation newannot = new AlignmentAnnotation(seq.getAnnotation()[a]);
116           newannot.restrict(startRes, endRes);
117           newannot.setSequenceRef(seqs[i]);
118           newannot.adjustForAlignment();
119           seqs[i].addAlignmentAnnotation(newannot);
120         }
121       }
122     }
123
124     return seqs;
125
126   }
127
128   /**
129    * If sequence ends in gaps, the end residue can
130    * be correctly calculated here
131    * @param seq SequenceI
132    * @return int
133    */
134   public int findEndRes(SequenceI seq)
135   {
136     int eres = 0;
137     char ch;
138
139     for (int j = 0; j < endRes + 1 && j < seq.getLength(); j++)
140     {
141       ch = seq.getCharAt(j);
142       if (!jalview.util.Comparison.isGap( (ch)))
143       {
144         eres++;
145       }
146     }
147
148     if (eres > 0)
149     {
150       eres += seq.getStart() - 1;
151     }
152
153     return eres;
154   }
155
156   public Vector getSequences(Hashtable hiddenReps)
157   {
158     if (hiddenReps == null)
159     {
160       return sequences;
161     }
162     else
163     {
164       Vector allSequences = new Vector();
165       SequenceI seq, seq2;
166       for (int i = 0; i < sequences.size(); i++)
167       {
168         seq = (SequenceI) sequences.elementAt(i);
169         allSequences.addElement(seq);
170         if (hiddenReps.containsKey(seq))
171         {
172           SequenceGroup hsg = (SequenceGroup) hiddenReps.get(seq);
173           for (int h = 0; h < hsg.getSize(); h++)
174           {
175             seq2 = hsg.getSequenceAt(h);
176             if (seq2 != seq
177                 && !allSequences.contains(seq2))
178             {
179               allSequences.addElement(seq2);
180             }
181           }
182         }
183       }
184
185       return allSequences;
186     }
187   }
188
189   public SequenceI[] getSequencesAsArray(Hashtable hiddenReps)
190   {
191     Vector tmp = getSequences(hiddenReps);
192     if (tmp == null)
193     {
194       return null;
195     }
196     SequenceI[] result = new SequenceI[tmp.size()];
197     for (int i = 0; i < result.length; i++)
198     {
199       result[i] = (SequenceI) tmp.elementAt(i);
200     }
201
202     return result;
203   }
204
205   /**
206    * DOCUMENT ME!
207    *
208    * @param col DOCUMENT ME!
209    *
210    * @return DOCUMENT ME!
211    */
212   public boolean adjustForRemoveLeft(int col)
213   {
214     // return value is true if the group still exists
215     if (startRes >= col)
216     {
217       startRes = startRes - col;
218     }
219
220     if (endRes >= col)
221     {
222       endRes = endRes - col;
223
224       if (startRes > endRes)
225       {
226         startRes = 0;
227       }
228     }
229     else
230     {
231       // must delete this group!!
232       return false;
233     }
234
235     return true;
236   }
237
238   /**
239    * DOCUMENT ME!
240    *
241    * @param col DOCUMENT ME!
242    *
243    * @return DOCUMENT ME!
244    */
245   public boolean adjustForRemoveRight(int col)
246   {
247     if (startRes > col)
248     {
249       // delete this group
250       return false;
251     }
252
253     if (endRes >= col)
254     {
255       endRes = col;
256     }
257
258     return true;
259   }
260
261   /**
262    * DOCUMENT ME!
263    *
264    * @return DOCUMENT ME!
265    */
266   public String getName()
267   {
268     return groupName;
269   }
270
271   public String getDescription()
272   {
273     return description;
274   }
275
276   /**
277    * DOCUMENT ME!
278    *
279    * @param name DOCUMENT ME!
280    */
281   public void setName(String name)
282   {
283     groupName = name;
284   }
285
286   public void setDescription(String desc)
287   {
288     description = desc;
289   }
290
291   /**
292    * DOCUMENT ME!
293    *
294    * @return DOCUMENT ME!
295    */
296   public Conservation getConservation()
297   {
298     return conserve;
299   }
300
301   /**
302    * DOCUMENT ME!
303    *
304    * @param c DOCUMENT ME!
305    */
306   public void setConservation(Conservation c)
307   {
308     conserve = c;
309   }
310
311   /**
312    * DOCUMENT ME!
313    *
314    * @param s DOCUMENT ME!
315    * @param recalc DOCUMENT ME!
316    */
317   public void addSequence(SequenceI s, boolean recalc)
318   {
319     if (s != null && !sequences.contains(s))
320     {
321       sequences.addElement(s);
322     }
323
324     if (recalc)
325     {
326       recalcConservation();
327     }
328   }
329
330   /**
331    * DOCUMENT ME!
332    */
333   public void recalcConservation()
334   {
335     if (cs == null)
336     {
337       return;
338     }
339
340     try
341     {
342       cs.setConsensus(AAFrequency.calculate(sequences, startRes, endRes + 1));
343
344       if (cs instanceof ClustalxColourScheme)
345       {
346         ( (ClustalxColourScheme) cs).resetClustalX(sequences, getWidth());
347       }
348
349       if (cs.conservationApplied())
350       {
351         Conservation c = new Conservation(groupName,
352                                           ResidueProperties.propHash, 3,
353                                           sequences,
354                                           startRes, endRes + 1);
355         c.calculate();
356         c.verdict(false, 25);
357
358         cs.setConservation(c);
359
360         if (cs instanceof ClustalxColourScheme)
361         {
362           ( (ClustalxColourScheme) cs).resetClustalX(sequences,
363               getWidth());
364         }
365       }
366     }
367     catch (java.lang.OutOfMemoryError err)
368     {
369       System.out.println("Out of memory loading groups: " + err);
370     }
371
372   }
373
374   /**
375    * DOCUMENT ME!
376    *
377    * @param s DOCUMENT ME!
378    * @param recalc DOCUMENT ME!
379    */
380   public void addOrRemove(SequenceI s, boolean recalc)
381   {
382     if (sequences.contains(s))
383     {
384       deleteSequence(s, recalc);
385     }
386     else
387     {
388       addSequence(s, recalc);
389     }
390   }
391
392   /**
393    * DOCUMENT ME!
394    *
395    * @param s DOCUMENT ME!
396    * @param recalc DOCUMENT ME!
397    */
398   public void deleteSequence(SequenceI s, boolean recalc)
399   {
400     sequences.removeElement(s);
401
402     if (recalc)
403     {
404       recalcConservation();
405     }
406   }
407
408   /**
409    * DOCUMENT ME!
410    *
411    * @return DOCUMENT ME!
412    */
413   public int getStartRes()
414   {
415     return startRes;
416   }
417
418   /**
419    * DOCUMENT ME!
420    *
421    * @return DOCUMENT ME!
422    */
423   public int getEndRes()
424   {
425     return endRes;
426   }
427
428   /**
429    * DOCUMENT ME!
430    *
431    * @param i DOCUMENT ME!
432    */
433   public void setStartRes(int i)
434   {
435     startRes = i;
436   }
437
438   /**
439    * DOCUMENT ME!
440    *
441    * @param i DOCUMENT ME!
442    */
443   public void setEndRes(int i)
444   {
445     endRes = i;
446   }
447
448   /**
449    * DOCUMENT ME!
450    *
451    * @return DOCUMENT ME!
452    */
453   public int getSize()
454   {
455     return sequences.size();
456   }
457
458   /**
459    * DOCUMENT ME!
460    *
461    * @param i DOCUMENT ME!
462    *
463    * @return DOCUMENT ME!
464    */
465   public SequenceI getSequenceAt(int i)
466   {
467     return (SequenceI) sequences.elementAt(i);
468   }
469
470   /**
471    * DOCUMENT ME!
472    *
473    * @param state DOCUMENT ME!
474    */
475   public void setColourText(boolean state)
476   {
477     colourText = state;
478   }
479
480   /**
481    * DOCUMENT ME!
482    *
483    * @return DOCUMENT ME!
484    */
485   public boolean getColourText()
486   {
487     return colourText;
488   }
489
490   /**
491    * DOCUMENT ME!
492    *
493    * @param state DOCUMENT ME!
494    */
495   public void setDisplayText(boolean state)
496   {
497     displayText = state;
498   }
499
500   /**
501    * DOCUMENT ME!
502    *
503    * @return DOCUMENT ME!
504    */
505   public boolean getDisplayText()
506   {
507     return displayText;
508   }
509
510   /**
511    * DOCUMENT ME!
512    *
513    * @param state DOCUMENT ME!
514    */
515   public void setDisplayBoxes(boolean state)
516   {
517     displayBoxes = state;
518   }
519
520   /**
521    * DOCUMENT ME!
522    *
523    * @return DOCUMENT ME!
524    */
525   public boolean getDisplayBoxes()
526   {
527     return displayBoxes;
528   }
529
530   /**
531    * DOCUMENT ME!
532    *
533    * @return DOCUMENT ME!
534    */
535   public int getWidth()
536   {
537     // MC This needs to get reset when characters are inserted and deleted
538     if (sequences.size() > 0)
539     {
540       width = ( (SequenceI) sequences.elementAt(0)).getLength();
541     }
542
543     for (int i = 1; i < sequences.size(); i++)
544     {
545       SequenceI seq = (SequenceI) sequences.elementAt(i);
546
547       if (seq.getLength() > width)
548       {
549         width = seq.getLength();
550       }
551     }
552
553     return width;
554   }
555
556   /**
557    * DOCUMENT ME!
558    *
559    * @param c DOCUMENT ME!
560    */
561   public void setOutlineColour(Color c)
562   {
563     outlineColour = c;
564   }
565
566   /**
567    * DOCUMENT ME!
568    *
569    * @return DOCUMENT ME!
570    */
571   public Color getOutlineColour()
572   {
573     return outlineColour;
574   }
575
576   /**
577    *
578    * returns the sequences in the group ordered by the ordering given by al
579    *
580    * @param al Alignment
581    * @return SequenceI[]
582    */
583   public SequenceI[] getSequencesInOrder(AlignmentI al)
584   {
585     int sSize = sequences.size();
586     int alHeight = al.getHeight();
587
588     SequenceI[] seqs = new SequenceI[sSize];
589
590     int index = 0;
591     for (int i = 0; i < alHeight && index < sSize; i++)
592     {
593       if (sequences.contains(al.getSequenceAt(i)))
594       {
595         seqs[index++] = al.getSequenceAt(i);
596       }
597     }
598
599     return seqs;
600   }
601 }