6c1a3431d9cf2f12e8c05e905a5b7bc83e32ad49
[jalview.git] / src / jalview / io / AlignFile.java
1 /*
2  * Jalview - A Sequence Alignment Editor and Viewer (Version 2.8)
3  * Copyright (C) 2012 J Procter, AM Waterhouse, LM Lui, J Engelhardt, 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     {
86       seqs.get(i).setIndex(i);
87     }
88   }
89
90   /**
91    * Attempt to read from the position where some other parsing process left
92    * off.
93    * 
94    * @param source
95    * @throws IOException
96    */
97   public AlignFile(FileParse source) throws IOException
98   {
99     super(source);
100     initData();
101     parse();
102     // sets the index of each sequence in the alignment
103     for (int i = 0, c = seqs.size(); i < c; i++)
104     {
105       seqs.get(i).setIndex(i);
106     }
107   }
108
109   /**
110    * Return the seqs Vector
111    */
112   public Vector<SequenceI> getSeqs()
113   {
114     return seqs;
115   }
116
117   /**
118    * Return the Sequences in the seqs Vector as an array of Sequences
119    */
120   public SequenceI[] getSeqsAsArray()
121   {
122     SequenceI[] s = new SequenceI[seqs.size()];
123
124     for (int i = 0; i < seqs.size(); i++)
125     {
126       s[i] = (SequenceI) seqs.elementAt(i);
127     }
128
129     return s;
130   }
131
132   /**
133    * called by AppletFormatAdapter to generate an annotated alignment, rather
134    * than bare sequences.
135    * 
136    * @param al
137    */
138   public void addAnnotations(Alignment al)
139   {
140     addProperties(al);
141     for (int i = 0; i < annotations.size(); i++)
142     {
143       // detect if annotations.elementAt(i) rna secondary structure
144       // if so then do:
145       /*
146        * SequenceFeature[] pairArray =
147        * Rna.GetBasePairsFromAlignmentAnnotation(annotations.elementAt(i));
148        * Rna.HelixMap(pairArray);
149        */
150       AlignmentAnnotation an = (AlignmentAnnotation) annotations
151               .elementAt(i);
152       an.validateRangeAndDisplay();
153       al.addAnnotation(an);
154     }
155
156   }
157
158   /**
159    * Add any additional information extracted from the file to the alignment
160    * properties.
161    * 
162    * @note implicitly called by addAnnotations()
163    * @param al
164    */
165   public void addProperties(Alignment al)
166   {
167     if (properties != null && properties.size() > 0)
168     {
169       Enumeration keys = properties.keys();
170       Enumeration vals = properties.elements();
171       while (keys.hasMoreElements())
172       {
173         al.setProperty(keys.nextElement(), vals.nextElement());
174       }
175     }
176   }
177
178   /**
179    * Store a non-null key-value pair in a hashtable used to set alignment
180    * properties note: null keys will raise an error, null values will result in
181    * the key/value pair being silently ignored.
182    * 
183    * @param key
184    *          - non-null key object
185    * @param value
186    *          - non-null value
187    */
188   protected void setAlignmentProperty(Object key, Object value)
189   {
190     if (key == null)
191     {
192       throw new Error(
193               "Implementation error: Cannot have null alignment property key.");
194     }
195     if (value == null)
196     {
197       return; // null properties are ignored.
198     }
199     if (properties == null)
200     {
201       properties = new Hashtable();
202     }
203     properties.put(key, value);
204   }
205
206   protected Object getAlignmentProperty(Object key)
207   {
208     if (properties != null && key != null)
209     {
210       return properties.get(key);
211     }
212     return null;
213   }
214
215   /**
216    * Initialise objects to store sequence data in.
217    */
218   protected void initData()
219   {
220     seqs = new Vector();
221     annotations = new Vector();
222   }
223
224   /**
225    * DOCUMENT ME!
226    * 
227    * @param s
228    *          DOCUMENT ME!
229    */
230   protected void setSeqs(SequenceI[] s)
231   {
232     seqs = new Vector();
233
234     for (int i = 0; i < s.length; i++)
235     {
236       seqs.addElement(s[i]);
237     }
238   }
239
240   /**
241    * This method must be implemented to parse the contents of the file.
242    */
243   public abstract void parse() throws IOException;
244
245   /**
246    * Print out in alignment file format the Sequences in the seqs Vector.
247    */
248   public abstract String print();
249
250   public void addJVSuffix(boolean b)
251   {
252     jvSuffix = b;
253   }
254
255   /**
256    * A general parser for ids.
257    * 
258    * @String id Id to be parsed
259    */
260   Sequence parseId(String id)
261   {
262     Sequence seq = null;
263     id = id.trim();
264     int space = id.indexOf(" ");
265     if (space > -1)
266     {
267       seq = new Sequence(id.substring(0, space), "");
268       seq.setDescription(id.substring(space + 1));
269     }
270     else
271     {
272       seq = new Sequence(id, "");
273     }
274
275     return seq;
276   }
277
278   /**
279    * Creates the output id. Adds prefix Uniprot format source|id And suffix
280    * Jalview /start-end
281    * 
282    * @String id Id to be parsed
283    */
284   String printId(SequenceI seq)
285   {
286     return seq.getDisplayId(jvSuffix);
287   }
288
289   /**
290    * vector of String[] treeName, newickString pairs
291    */
292   Vector newickStrings = null;
293
294   protected void addNewickTree(String treeName, String newickString)
295   {
296     if (newickStrings == null)
297     {
298       newickStrings = new Vector();
299     }
300     newickStrings.addElement(new String[]
301     { treeName, newickString });
302   }
303
304   protected int getTreeCount()
305   {
306     if (newickStrings == null)
307     {
308       return 0;
309     }
310     return newickStrings.size();
311   }
312
313 }