Merge branch 'develop' into menard
[jalview.git] / src / jalview / io / FastaFile.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 java.io.*;
21
22 import javax.xml.parsers.ParserConfigurationException;
23
24 import org.xml.sax.SAXException;
25
26 import fr.orsay.lri.varna.exceptions.ExceptionFileFormatOrSyntax;
27 import fr.orsay.lri.varna.exceptions.ExceptionLoadingFailed;
28 import fr.orsay.lri.varna.exceptions.ExceptionPermissionDenied;
29 import fr.orsay.lri.varna.exceptions.ExceptionUnmatchedClosingParentheses;
30
31 import jalview.datamodel.*;
32
33 /**
34  * DOCUMENT ME!
35  * 
36  * @author $author$
37  * @version $Revision$
38  */
39 public class FastaFile extends AlignFile
40 {
41   /**
42    * Length of a sequence line
43    */
44   int len = 72;
45
46   StringBuffer out;
47
48   /**
49    * Creates a new FastaFile object.
50    */
51   public FastaFile()
52   {
53   }
54
55   /**
56    * Creates a new FastaFile object.
57    * 
58    * @param inFile
59    *          DOCUMENT ME!
60    * @param type
61    *          DOCUMENT ME!
62    * 
63    * @throws IOException
64    *           DOCUMENT ME!
65  * @throws SAXException 
66  * @throws ParserConfigurationException 
67  * @throws ExceptionFileFormatOrSyntax 
68  * @throws ExceptionLoadingFailed 
69  * @throws ExceptionPermissionDenied 
70  * @throws InterruptedException 
71  * @throws ExceptionUnmatchedClosingParentheses 
72    */
73   public FastaFile(String inFile, String type) throws IOException, ExceptionFileFormatOrSyntax, ParserConfigurationException, SAXException, ExceptionPermissionDenied, ExceptionLoadingFailed, InterruptedException, ExceptionUnmatchedClosingParentheses
74   {
75     super(inFile, type);
76   }
77
78   public FastaFile(FileParse source) throws IOException, ExceptionFileFormatOrSyntax, ParserConfigurationException, SAXException, ExceptionPermissionDenied, ExceptionLoadingFailed, InterruptedException, ExceptionUnmatchedClosingParentheses
79   {
80     super(source);
81   }
82
83   /**
84    * DOCUMENT ME!
85    * 
86    * @throws IOException
87    *           DOCUMENT ME!
88    */
89   public void parse() throws IOException
90   {
91     StringBuffer sb = new StringBuffer();
92     boolean firstLine = true;
93
94     String line;
95     Sequence seq = null;
96
97     boolean annotation = false;
98
99     while ((line = nextLine()) != null)
100     {
101       line = line.trim();
102       if (line.length() > 0)
103       {
104         if (line.charAt(0) == '>')
105         {
106           if (line.startsWith(">#_"))
107           {
108             if (annotation)
109             {
110               Annotation[] anots = new Annotation[sb.length()];
111               String anotString = sb.toString();
112               for (int i = 0; i < sb.length(); i++)
113               {
114                 anots[i] = new Annotation(anotString.substring(i, i + 1),
115                         null, ' ', 0);
116               }
117               AlignmentAnnotation aa = new AlignmentAnnotation(seq
118                       .getName().substring(2), seq.getDescription(), anots);
119
120               annotations.addElement(aa);
121             }
122           }
123           else
124           {
125             annotation = false;
126           }
127
128           if (!firstLine)
129           {
130             seq.setSequence(sb.toString());
131
132             if (!annotation)
133             {
134               seqs.addElement(seq);
135             }
136           }
137
138           seq = parseId(line.substring(1));
139           firstLine = false;
140
141           sb = new StringBuffer();
142
143           if (line.startsWith(">#_"))
144           {
145             annotation = true;
146           }
147         }
148         else
149         {
150           sb.append(line);
151         }
152       }
153     }
154
155     if (annotation)
156     {
157       Annotation[] anots = new Annotation[sb.length()];
158       String anotString = sb.toString();
159       for (int i = 0; i < sb.length(); i++)
160       {
161         anots[i] = new Annotation(anotString.substring(i, i + 1), null,
162                 ' ', 0);
163       }
164       AlignmentAnnotation aa = new AlignmentAnnotation(seq.getName()
165               .substring(2), seq.getDescription(), anots);
166
167       annotations.addElement(aa);
168     }
169
170     else if (!firstLine)
171     {
172       seq.setSequence(sb.toString());
173       seqs.addElement(seq);
174     }
175   }
176
177   /**
178    * called by AppletFormatAdapter to generate an annotated alignment, rather
179    * than bare sequences.
180    * 
181    * @param al
182    */
183   public void addAnnotations(Alignment al)
184   {
185     addProperties(al);
186     for (int i = 0; i < annotations.size(); i++)
187     {
188       AlignmentAnnotation aa = (AlignmentAnnotation) annotations
189               .elementAt(i);
190       aa.setPadGaps(true, al.getGapCharacter());
191       al.addAnnotation(aa);
192     }
193   }
194
195   /**
196    * DOCUMENT ME!
197    * 
198    * @param s
199    *          DOCUMENT ME!
200    * @param len
201    *          DOCUMENT ME!
202    * @param gaps
203    *          DOCUMENT ME!
204    * @param displayId
205    *          DOCUMENT ME!
206    * 
207    * @return DOCUMENT ME!
208    */
209   public String print(SequenceI[] s)
210   {
211     out = new StringBuffer();
212     int i = 0;
213
214     while ((i < s.length) && (s[i] != null))
215     {
216       out.append(">" + printId(s[i]));
217       if (s[i].getDescription() != null)
218       {
219         out.append(" " + s[i].getDescription());
220       }
221
222       out.append(newline);
223
224       int nochunks = (s[i].getLength() / len) + 1;
225
226       for (int j = 0; j < nochunks; j++)
227       {
228         int start = j * len;
229         int end = start + len;
230
231         if (end < s[i].getLength())
232         {
233           out.append(s[i].getSequenceAsString(start, end) + newline);
234         }
235         else if (start < s[i].getLength())
236         {
237           out.append(s[i].getSequenceAsString(start, s[i].getLength())
238                   + newline);
239         }
240       }
241
242       i++;
243     }
244
245     return out.toString();
246   }
247
248   /**
249    * DOCUMENT ME!
250    * 
251    * @return DOCUMENT ME!
252    */
253   public String print()
254   {
255     return print(getSeqsAsArray());
256   }
257 }