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