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