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