FileParse object can be re-used to read different files concatenated together
[jalview.git] / src / jalview / io / BLCFile.java
1 /*
2  * Jalview - A Sequence Alignment Editor and Viewer
3  * Copyright (C) 2007 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * as published by the Free Software Foundation; either version 2
8  * of the License, or (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
18  */
19 package jalview.io;
20
21 import java.io.*;
22 import java.util.*;
23
24 import jalview.datamodel.*;
25
26 /**
27  * DOCUMENT ME!
28  *
29  * @author $author$
30  * @version $Revision$
31  */
32 public class BLCFile
33 extends AlignFile
34 {
35   Vector titles;
36
37   /**
38    * Creates a new BLCFile object.
39    */
40   public BLCFile()
41   {
42   }
43
44   /**
45    * Creates a new BLCFile object.
46    *
47    * @param inFile DOCUMENT ME!
48    * @param type DOCUMENT ME!
49    *
50    * @throws IOException DOCUMENT ME!
51    */
52   public BLCFile(String inFile, String type)
53   throws IOException
54   {
55     super(inFile, type);
56   }
57   public BLCFile(FileParse source) throws IOException
58   {
59     super(source);
60   }
61
62   /**
63    * DOCUMENT ME!
64    */
65   public void initData()
66   {
67     super.initData();
68     titles = new Vector();
69   }
70   /**
71    * Control the number of block iterations to skip before returning.
72    * set to 0 to read first block file entry only
73    * set to -1 to read last block file entry only
74    * set to greater than zero to skip at most that many entries before parsing
75    */
76   int iterationSkips=0;
77   /**
78    * The iteration number for the alignment actually parsed from the blc file 
79    */
80   int iterationCount=0;
81
82   /**
83    * DOCUMENT ME!
84    */
85   public void parse()
86   throws IOException
87   {
88     StringBuffer headerLines=new StringBuffer();
89     int numHeaderLines = 0; // number of lines appended.
90     StringBuffer[] seqstrings=null;
91     if (suffix!=null) {
92       try {
93         iterationSkips = Integer.parseInt(suffix); 
94       } catch (NumberFormatException e) {
95         iterationSkips = 0; // first
96       }
97     }
98
99     String line = null;
100
101     do {
102       boolean idsFound = false;
103       boolean newids = false;
104         // search for ID header.
105       do
106       {
107         line = nextLine();
108         if (line==null)
109           break;
110         // seek end of ids
111         if (line.indexOf("*") > -1)
112         {
113           idsFound = true;
114
115           break;
116         }
117         
118         int abracket = line.indexOf(">");
119
120         if (abracket > -1)
121         {
122
123           if (iterationCount>0 && !newids) {
124             // we have a new set of IDs to record.
125             newids = true;
126             seqs.removeAllElements(); 
127           }
128
129           line = line.substring(abracket + 1);
130
131           Sequence seq = parseId(line);
132           seqs.addElement(seq);
133         } else {
134           // header lines - keep them for the alignment comments.
135           headerLines.append(line);
136           headerLines.append("\n");
137           numHeaderLines++;
138         }
139       }
140       while (!idsFound);
141       if (line==null)
142         break; // end of file.
143       int starCol = line.indexOf("*");
144       seqstrings = new StringBuffer[seqs.size()];
145
146       for (int i = 0; i < seqs.size(); i++)
147       {
148         if (seqstrings[i] == null)
149         {
150           seqstrings[i] = new StringBuffer();
151         }
152       }
153
154       try {
155         line = nextLine();
156         while (line!=null && line.indexOf("*") == -1)
157         {
158           for (int i = 0; i < seqs.size(); i++)
159           {
160             if (line.length() > (i + starCol))
161             {
162               seqstrings[i].append(line.charAt(i + starCol));
163             }
164           }
165           line = nextLine();
166         }
167       } catch (IOException e) {
168         if (iterationCount==0) {
169           throw(e); // otherwise we've just run out of iterations.
170         } else {
171           iterationSkips=0;
172         }
173       }
174       iterationCount++;
175     } while (--iterationSkips!=-1);
176     
177     for (int i = 0; i < seqs.size(); i++)
178     {
179       Sequence newSeq = (Sequence) seqs.elementAt(i);
180
181       newSeq.setSequence(seqstrings[i].toString());
182     }
183     if (seqs.size()>0)
184     {
185       if (headerLines.length()>1+numHeaderLines) // could see if buffer is just whitespace or not. 
186         setAlignmentProperty("Comments", headerLines.toString());
187       setAlignmentProperty("iteration", ""+iterationCount);
188     }
189   }
190
191   /**
192    * DOCUMENT ME!
193    *
194    * @return DOCUMENT ME!
195    */
196   public String print()
197   {
198     return print(getSeqsAsArray());
199   }
200
201   /**
202    * DOCUMENT ME!
203    *
204    * @param s DOCUMENT ME!
205    *
206    * @return DOCUMENT ME!
207    */
208   public String print(SequenceI[] s)
209   {
210     StringBuffer out = new StringBuffer();
211     /**
212      * A general parser for ids. Will look for dbrefs in
213      * Uniprot format source|id
214      * And also Jalview /start-end
215      *
216      * @String id Id to be parsed
217      */
218     int i = 0;
219     int max = -1;
220
221     while ( (i < s.length) && (s[i] != null))
222     {
223       out.append(">" + printId(s[i]));
224       if (s[i].getDescription() != null)
225       {
226         out.append(" " + s[i].getDescription());
227       }
228
229       out.append("\n");
230
231       if (s[i].getSequence().length > max)
232       {
233         max = s[i].getSequence().length;
234       }
235
236       i++;
237     }
238
239     out.append("* iteration 1\n");
240
241     for (int j = 0; j < max; j++)
242     {
243       i = 0;
244
245       while ( (i < s.length) && (s[i] != null))
246       {
247         if (s[i].getSequence().length > j)
248         {
249           out.append(s[i].getSequenceAsString(j, j + 1));
250         }
251         else
252         {
253           out.append("-");
254         }
255
256         i++;
257       }
258
259       out.append("\n");
260     }
261
262     out.append("*\n");
263
264     return out.toString();
265   }
266 }