Merge branch 'develop' into features/JAL-2110_crossRefDuplications
[jalview.git] / src / jalview / io / FastaFile.java
1 /*
2  * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3  * Copyright (C) $$Year-Rel$$ 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
10  * of the License, or (at your option) any later version.
11  *  
12  * Jalview is distributed in the hope that it will be useful, but 
13  * WITHOUT ANY WARRANTY; without even the implied warranty 
14  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
15  * PURPOSE.  See the GNU General Public License for more details.
16  * 
17  * You should have received a copy of the GNU General Public License
18  * along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
19  * The Jalview Authors are detailed in the 'AUTHORS' file.
20  */
21 package jalview.io;
22
23 import jalview.datamodel.Alignment;
24 import jalview.datamodel.AlignmentAnnotation;
25 import jalview.datamodel.Annotation;
26 import jalview.datamodel.Sequence;
27 import jalview.datamodel.SequenceI;
28
29 import java.io.IOException;
30
31 /**
32  * DOCUMENT ME!
33  * 
34  * @author $author$
35  * @version $Revision$
36  */
37 public class FastaFile extends AlignFile
38 {
39   /**
40    * Length of a sequence line
41    */
42   int len = 72;
43
44   StringBuffer out;
45
46   /**
47    * Creates a new FastaFile object.
48    */
49   public FastaFile()
50   {
51   }
52
53   /**
54    * Creates a new FastaFile object.
55    * 
56    * @param inFile
57    *          DOCUMENT ME!
58    * @param type
59    *          DOCUMENT ME!
60    * 
61    * @throws IOException
62    *           DOCUMENT ME!
63    */
64   public FastaFile(String inFile, String type) throws IOException
65   {
66     super(inFile, type);
67   }
68
69   public FastaFile(FileParse source) throws IOException
70   {
71     super(source);
72   }
73
74   /**
75    * DOCUMENT ME!
76    * 
77    * @throws IOException
78    *           DOCUMENT ME!
79    */
80   @Override
81   public void parse() throws IOException
82   {
83     StringBuffer sb = new StringBuffer();
84     boolean firstLine = true;
85
86     String line, uline;
87     Sequence seq = null;
88
89     boolean annotation = false;
90
91     while ((uline = nextLine()) != null)
92     {
93       line = uline.trim();
94       if (line.length() > 0)
95       {
96         if (line.charAt(0) == '>')
97         {
98           if (line.startsWith(">#_"))
99           {
100             if (annotation)
101             {
102               annotations.addElement(makeAnnotation(seq, sb));
103             }
104           }
105           else
106           {
107             annotation = false;
108           }
109
110           if (!firstLine)
111           {
112             seq.setSequence(sb.toString());
113
114             if (!annotation)
115             {
116               seqs.addElement(seq);
117             }
118           }
119
120           seq = parseId(line.substring(1));
121           firstLine = false;
122
123           sb = new StringBuffer();
124
125           if (line.startsWith(">#_"))
126           {
127             annotation = true;
128           }
129         }
130         else
131         {
132           sb.append(annotation ? uline : line);
133         }
134       }
135     }
136
137     if (annotation)
138     {
139       annotations.addElement(makeAnnotation(seq, sb));
140     }
141
142     else if (!firstLine)
143     {
144       seq.setSequence(sb.toString());
145       seqs.addElement(seq);
146     }
147   }
148
149   private AlignmentAnnotation makeAnnotation(SequenceI seq, StringBuffer sb)
150   {
151     Annotation[] anots = new Annotation[sb.length()];
152     char cb;
153     for (int i = 0; i < anots.length; i++)
154     {
155       char cn = sb.charAt(i);
156       if (cn != ' ')
157       {
158         anots[i] = new Annotation("" + cn, null, ' ', Float.NaN);
159       }
160     }
161     AlignmentAnnotation aa = new AlignmentAnnotation(seq.getName()
162             .substring(2), seq.getDescription(), anots);
163     return aa;
164   }
165
166   /**
167    * called by AppletFormatAdapter to generate an annotated alignment, rather
168    * than bare sequences.
169    * 
170    * @param al
171    */
172   public void addAnnotations(Alignment al)
173   {
174     addProperties(al);
175     for (int i = 0; i < annotations.size(); i++)
176     {
177       AlignmentAnnotation aa = annotations
178               .elementAt(i);
179       aa.setPadGaps(true, al.getGapCharacter());
180       al.addAnnotation(aa);
181     }
182   }
183
184   /**
185    * DOCUMENT ME!
186    * 
187    * @param s
188    *          DOCUMENT ME!
189    * @param len
190    *          DOCUMENT ME!
191    * @param gaps
192    *          DOCUMENT ME!
193    * @param displayId
194    *          DOCUMENT ME!
195    * 
196    * @return DOCUMENT ME!
197    */
198   public String print(SequenceI[] s)
199   {
200     out = new StringBuffer();
201     int i = 0;
202
203     while ((i < s.length) && (s[i] != null))
204     {
205       out.append(">" + printId(s[i]));
206       if (s[i].getDescription() != null)
207       {
208         out.append(" " + s[i].getDescription());
209       }
210
211       out.append(newline);
212
213       int nochunks = (s[i].getLength() / len)
214               + (s[i].getLength() % len > 0 ? 1 : 0);
215
216       for (int j = 0; j < nochunks; j++)
217       {
218         int start = j * len;
219         int end = start + len;
220
221         if (end < s[i].getLength())
222         {
223           out.append(s[i].getSequenceAsString(start, end) + newline);
224         }
225         else if (start < s[i].getLength())
226         {
227           out.append(s[i].getSequenceAsString(start, s[i].getLength())
228                   + newline);
229         }
230       }
231
232       i++;
233     }
234
235     return out.toString();
236   }
237
238   /**
239    * DOCUMENT ME!
240    * 
241    * @return DOCUMENT ME!
242    */
243   @Override
244   public String print()
245   {
246     return print(getSeqsAsArray());
247   }
248 }