JAL-2668 fix broken factory method for colour scheme
[jalview.git] / src / jalview / schemes / TCoffeeColourScheme.java
1 /*
2  * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3  * Copyright (C) $$Year-Rel$$ The Jalview Authors
4  * 
5  * This file is part of Jalview.
6  * 
7  * Jalview is free software: you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License 
9  * as published by the Free Software Foundation, either version 3
10  * of the License, or (at your option) any later version.
11  *  
12  * Jalview is distributed in the hope that it will be useful, but 
13  * WITHOUT ANY WARRANTY; without even the implied warranty 
14  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
15  * PURPOSE.  See the GNU General Public License for more details.
16  * 
17  * You should have received a copy of the GNU General Public License
18  * along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
19  * The Jalview Authors are detailed in the 'AUTHORS' file.
20  */
21 package jalview.schemes;
22
23 import jalview.datamodel.AlignmentAnnotation;
24 import jalview.datamodel.AlignmentI;
25 import jalview.datamodel.AnnotatedCollectionI;
26 import jalview.datamodel.Annotation;
27 import jalview.datamodel.SequenceCollectionI;
28 import jalview.datamodel.SequenceI;
29 import jalview.io.TCoffeeScoreFile;
30
31 import java.awt.Color;
32 import java.util.ArrayList;
33 import java.util.IdentityHashMap;
34 import java.util.List;
35 import java.util.Map;
36
37 /**
38  * Defines the color score for T-Coffee MSA
39  * <p>
40  * See http://tcoffee.org
41  * 
42  * 
43  * @author Paolo Di Tommaso
44  * 
45  */
46 public class TCoffeeColourScheme extends ResidueColourScheme
47 {
48   IdentityHashMap<SequenceI, Color[]> seqMap;
49
50   /**
51    * Default constructor (required for Class.newInstance())
52    */
53   public TCoffeeColourScheme()
54   {
55
56   }
57
58   /**
59    * the color scheme needs to look at the alignment to get and cache T-COFFEE
60    * scores
61    * 
62    * @param alignment
63    *          - annotated sequences to be searched
64    */
65   public TCoffeeColourScheme(AnnotatedCollectionI alignment)
66   {
67     alignmentChanged(alignment, null);
68   }
69
70   /**
71    * Finds the TCoffeeScore annotation (if any) for each sequence and notes the
72    * annotation colour for each column position. The colours are fixed for
73    * scores 0-9 and are set when annotation is parsed.
74    * 
75    * @see TCoffeeScoreFile#annotateAlignment(AlignmentI, boolean)
76    */
77   @Override
78   public void alignmentChanged(AnnotatedCollectionI alignment,
79           Map<SequenceI, SequenceCollectionI> hiddenReps)
80   {
81     // TODO: if sequences have been represented and they have scores, could
82     // compute an average sequence score for the representative
83
84     // assume only one set of TCOFFEE scores - but could have more than one
85     // potentially.
86     List<AlignmentAnnotation> annots = new ArrayList<AlignmentAnnotation>();
87     // Search alignment to get all tcoffee annotation and pick one set of
88     // annotation to use to colour seqs.
89     seqMap = new IdentityHashMap<SequenceI, Color[]>();
90     AnnotatedCollectionI alcontext = alignment instanceof AlignmentI
91             ? alignment
92             : alignment.getContext();
93     if (alcontext == null)
94     {
95       return;
96     }
97     int w = 0;
98     for (AlignmentAnnotation al : alcontext
99             .findAnnotation(TCoffeeScoreFile.TCOFFEE_SCORE))
100     {
101       if (al.sequenceRef != null && !al.belowAlignment)
102       {
103         annots.add(al);
104         if (w < al.annotations.length)
105         {
106           w = al.annotations.length;
107         }
108         Color[] scores = new Color[al.annotations.length];
109         int i = 0;
110         for (Annotation an : al.annotations)
111         {
112           scores[i++] = (an != null) ? an.colour : Color.white;
113         }
114         seqMap.put(al.sequenceRef, scores);
115       }
116     }
117     // TODO: compute average colour for each symbol type in each column - gives
118     // a second order colourscheme for colouring a sequence logo derived from
119     // the alignment (colour reflects quality of alignment for each residue
120     // class)
121   }
122
123   @Override
124   public Color findColour(char c, int j, SequenceI seq)
125   {
126     if (seqMap == null)
127     {
128       return Color.WHITE;
129     }
130     Color[] cols = seqMap.get(seq);
131     if (cols == null)
132     {
133       // see above TODO about computing a colour for each residue in each
134       // column: cc = _rcols[i][indexFor[c]];
135       return Color.white;
136     }
137
138     if (j < 0 || j >= cols.length)
139     {
140       return Color.white;
141     }
142     return cols[j];
143   }
144
145   @Override
146   public ColourSchemeI getInstance(AnnotatedCollectionI sg,
147           Map<SequenceI, SequenceCollectionI> hiddenRepSequences)
148   {
149     return new TCoffeeColourScheme(sg);
150   }
151
152   /**
153    * Answers true if the data has TCoffee score annotation
154    */
155   @Override
156   public boolean isApplicableTo(AnnotatedCollectionI ac)
157   {
158     AnnotatedCollectionI alcontext = ac instanceof AlignmentI ? ac
159             : ac.getContext();
160     if (alcontext == null)
161     {
162       return false;
163     }
164     Iterable<AlignmentAnnotation> anns = alcontext
165             .findAnnotation(TCoffeeScoreFile.TCOFFEE_SCORE);
166     return anns.iterator().hasNext();
167   }
168
169   @Override
170   public String getSchemeName()
171   {
172     return JalviewColourScheme.TCoffee.toString();
173   }
174
175   @Override
176   public boolean isSimple()
177   {
178     return false;
179   }
180 }