JAL-1065 - Visualize T-Coffee quality scores for an alignment
[jalview.git] / src / jalview / io / AlignFile.java
1 /*
2  * Jalview - A Sequence Alignment Editor and Viewer (Version 2.7)
3  * Copyright (C) 2011 J Procter, AM Waterhouse, G Barton, M Clamp, S Searle
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 of the License, or (at your option) any later version.
10  * 
11  * Jalview is distributed in the hope that it will be useful, but 
12  * WITHOUT ANY WARRANTY; without even the implied warranty 
13  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
14  * PURPOSE.  See the GNU General Public License for more details.
15  * 
16  * You should have received a copy of the GNU General Public License along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
17  */
18 package jalview.io;
19
20 import jalview.datamodel.Alignment;
21 import jalview.datamodel.AlignmentAnnotation;
22 import jalview.datamodel.Sequence;
23 import jalview.datamodel.SequenceI;
24
25 import java.io.IOException;
26 import java.util.Enumeration;
27 import java.util.Hashtable;
28 import java.util.Vector;
29
30 /**
31  * DOCUMENT ME!
32  * 
33  * @author $author$
34  * @version $Revision$
35  */
36 public abstract class AlignFile extends FileParse
37 {
38   int noSeqs = 0;
39
40   int maxLength = 0;
41
42   /**
43    * Sequences to be added to form a new alignment.
44    */
45   protected Vector<SequenceI> seqs;
46
47   /**
48    * annotation to be added to generated alignment object
49    */
50   protected Vector annotations;
51
52   /**
53    * Properties to be added to generated alignment object
54    */
55   protected Hashtable properties;
56
57   long start;
58
59   long end;
60
61   boolean jvSuffix = true;
62
63   /**
64    * Creates a new AlignFile object.
65    */
66   public AlignFile()
67   {
68   }
69
70   /**
71    * Constructor which parses the data from a file of some specified type.
72    * 
73    * @param inFile
74    *          Filename to read from.
75    * @param type
76    *          What type of file to read from (File, URL)
77    */
78   public AlignFile(String inFile, String type) throws IOException
79   {
80     super(inFile, type);
81     initData();
82     parse();
83     // sets the index of each sequence in the alignment
84     for( int i=0,c=seqs.size(); i<c; i++ ) {  
85         seqs.get(i).setIndex(i);  
86     }
87   }
88
89   /**
90    * Attempt to read from the position where some other parsing process left
91    * off.
92    * 
93    * @param source
94    * @throws IOException
95    */
96   public AlignFile(FileParse source) throws IOException
97   {
98     super(source);
99     initData();
100     parse();
101     // sets the index of each sequence in the alignment
102     for( int i=0,c=seqs.size(); i<c; i++ ) {  
103         seqs.get(i).setIndex(i);  
104     }
105   }
106
107   /**
108    * Return the seqs Vector
109    */
110   public Vector<SequenceI> getSeqs()
111   {
112     return seqs;
113   }
114
115   /**
116    * Return the Sequences in the seqs Vector as an array of Sequences
117    */
118   public SequenceI[] getSeqsAsArray()
119   {
120     SequenceI[] s = new SequenceI[seqs.size()];
121
122     for (int i = 0; i < seqs.size(); i++)
123     {
124       s[i] = (SequenceI) seqs.elementAt(i);
125     }
126
127     return s;
128   }
129
130   /**
131    * called by AppletFormatAdapter to generate an annotated alignment, rather
132    * than bare sequences.
133    * 
134    * @param al
135    */
136   public void addAnnotations(Alignment al)
137   {
138     addProperties(al);
139     for (int i = 0; i < annotations.size(); i++)
140     {
141       al.addAnnotation((AlignmentAnnotation) annotations.elementAt(i));
142     }
143
144   }
145
146   /**
147    * Add any additional information extracted from the file to the alignment
148    * properties.
149    * 
150    * @note implicitly called by addAnnotations()
151    * @param al
152    */
153   public void addProperties(Alignment al)
154   {
155     if (properties != null && properties.size() > 0)
156     {
157       Enumeration keys = properties.keys();
158       Enumeration vals = properties.elements();
159       while (keys.hasMoreElements())
160       {
161         al.setProperty(keys.nextElement(), vals.nextElement());
162       }
163     }
164   }
165
166   /**
167    * Store a non-null key-value pair in a hashtable used to set alignment
168    * properties note: null keys will raise an error, null values will result in
169    * the key/value pair being silently ignored.
170    * 
171    * @param key
172    *          - non-null key object
173    * @param value
174    *          - non-null value
175    */
176   protected void setAlignmentProperty(Object key, Object value)
177   {
178     if (key == null)
179     {
180       throw new Error(
181               "Implementation error: Cannot have null alignment property key.");
182     }
183     if (value == null)
184     {
185       return; // null properties are ignored.
186     }
187     if (properties == null)
188     {
189       properties = new Hashtable();
190     }
191     properties.put(key, value);
192   }
193
194   protected Object getAlignmentProperty(Object key)
195   {
196     if (properties != null && key != null)
197     {
198       return properties.get(key);
199     }
200     return null;
201   }
202
203   /**
204    * Initialise objects to store sequence data in.
205    */
206   protected void initData()
207   {
208     seqs = new Vector();
209     annotations = new Vector();
210   }
211
212   /**
213    * DOCUMENT ME!
214    * 
215    * @param s
216    *          DOCUMENT ME!
217    */
218   protected void setSeqs(SequenceI[] s)
219   {
220     seqs = new Vector();
221
222     for (int i = 0; i < s.length; i++)
223     {
224       seqs.addElement(s[i]);
225     }
226   }
227
228   /**
229    * This method must be implemented to parse the contents of the file.
230    */
231   public abstract void parse() throws IOException;
232
233   /**
234    * Print out in alignment file format the Sequences in the seqs Vector.
235    */
236   public abstract String print();
237
238   public void addJVSuffix(boolean b)
239   {
240     jvSuffix = b;
241   }
242
243   /**
244    * A general parser for ids.
245    * 
246    * @String id Id to be parsed
247    */
248   Sequence parseId(String id)
249   {
250     Sequence seq = null;
251     id = id.trim();
252     int space = id.indexOf(" ");
253     if (space > -1)
254     {
255       seq = new Sequence(id.substring(0, space), "");
256       seq.setDescription(id.substring(space + 1));
257     }
258     else
259     {
260       seq = new Sequence(id, "");
261     }
262
263     return seq;
264   }
265
266   /**
267    * Creates the output id. Adds prefix Uniprot format source|id And suffix
268    * Jalview /start-end
269    * 
270    * @String id Id to be parsed
271    */
272   String printId(SequenceI seq)
273   {
274     return seq.getDisplayId(jvSuffix);
275   }
276
277   /**
278    * vector of String[] treeName, newickString pairs
279    */
280   Vector newickStrings = null;
281
282   protected void addNewickTree(String treeName, String newickString)
283   {
284     if (newickStrings == null)
285     {
286       newickStrings = new Vector();
287     }
288     newickStrings.addElement(new String[]
289     { treeName, newickString });
290   }
291
292   protected int getTreeCount()
293   {
294     if (newickStrings == null)
295     {
296       return 0;
297     }
298     return newickStrings.size();
299   }
300
301 }