blc header lines inserted as 'comment' alignment property
[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
58   /**
59    * DOCUMENT ME!
60    */
61   public void initData()
62   {
63     super.initData();
64     titles = new Vector();
65   }
66   /**
67    * Control the number of block iterations to skip before returning.
68    * set to 0 to read first block file entry only
69    * set to -1 to read last block file entry only
70    * set to greater than zero to skip at most that many entries before parsing
71    */
72   int iterationSkips=0;
73   /**
74    * The iteration number for the alignment actually parsed from the blc file 
75    */
76   int iterationCount=0;
77
78   /**
79    * DOCUMENT ME!
80    */
81   public void parse()
82   throws IOException
83   {
84     StringBuffer headerLines=new StringBuffer();
85     int numHeaderLines = 0; // number of lines appended.
86     StringBuffer[] seqstrings=null;
87     if (suffix!=null) {
88       try {
89         iterationSkips = Integer.parseInt(suffix); 
90       } catch (NumberFormatException e) {
91         iterationSkips = 0; // first
92       }
93     }
94
95     String line = null;
96
97     do {
98       boolean idsFound = false;
99       boolean newids = false;
100         // search for ID header.
101       do
102       {
103         line = nextLine();
104         if (line==null)
105           break;
106         // seek end of ids
107         if (line.indexOf("*") > -1)
108         {
109           idsFound = true;
110
111           break;
112         }
113         
114         int abracket = line.indexOf(">");
115
116         if (abracket > -1)
117         {
118
119           if (iterationCount>0 && !newids) {
120             // we have a new set of IDs to record.
121             newids = true;
122             seqs.removeAllElements(); 
123           }
124
125           line = line.substring(abracket + 1);
126
127           Sequence seq = parseId(line);
128           seqs.addElement(seq);
129         } else {
130           // header lines - keep them for the alignment comments.
131           headerLines.append(line);
132           headerLines.append("\n");
133           numHeaderLines++;
134         }
135       }
136       while (!idsFound);
137       if (line==null)
138         break; // end of file.
139       int starCol = line.indexOf("*");
140       seqstrings = new StringBuffer[seqs.size()];
141
142       for (int i = 0; i < seqs.size(); i++)
143       {
144         if (seqstrings[i] == null)
145         {
146           seqstrings[i] = new StringBuffer();
147         }
148       }
149
150       try {
151         line = nextLine();
152         while (line!=null && line.indexOf("*") == -1)
153         {
154           for (int i = 0; i < seqs.size(); i++)
155           {
156             if (line.length() > (i + starCol))
157             {
158               seqstrings[i].append(line.charAt(i + starCol));
159             }
160           }
161           line = nextLine();
162         }
163       } catch (IOException e) {
164         if (iterationCount==0) {
165           throw(e); // otherwise we've just run out of iterations.
166         } else {
167           iterationSkips=0;
168         }
169       }
170       iterationCount++;
171     } while (--iterationSkips!=-1);
172     
173     for (int i = 0; i < seqs.size(); i++)
174     {
175       Sequence newSeq = (Sequence) seqs.elementAt(i);
176
177       newSeq.setSequence(seqstrings[i].toString());
178     }
179     if (seqs.size()>0)
180     {
181       if (headerLines.length()>1+numHeaderLines) // could see if buffer is just whitespace or not. 
182         setAlignmentProperty("Comments", headerLines.toString());
183       setAlignmentProperty("iteration", ""+iterationCount);
184     }
185   }
186
187   /**
188    * DOCUMENT ME!
189    *
190    * @return DOCUMENT ME!
191    */
192   public String print()
193   {
194     return print(getSeqsAsArray());
195   }
196
197   /**
198    * DOCUMENT ME!
199    *
200    * @param s DOCUMENT ME!
201    *
202    * @return DOCUMENT ME!
203    */
204   public String print(SequenceI[] s)
205   {
206     StringBuffer out = new StringBuffer();
207     /**
208      * A general parser for ids. Will look for dbrefs in
209      * Uniprot format source|id
210      * And also Jalview /start-end
211      *
212      * @String id Id to be parsed
213      */
214     int i = 0;
215     int max = -1;
216
217     while ( (i < s.length) && (s[i] != null))
218     {
219       out.append(">" + printId(s[i]));
220       if (s[i].getDescription() != null)
221       {
222         out.append(" " + s[i].getDescription());
223       }
224
225       out.append("\n");
226
227       if (s[i].getSequence().length > max)
228       {
229         max = s[i].getSequence().length;
230       }
231
232       i++;
233     }
234
235     out.append("* iteration 1\n");
236
237     for (int j = 0; j < max; j++)
238     {
239       i = 0;
240
241       while ( (i < s.length) && (s[i] != null))
242       {
243         if (s[i].getSequence().length > j)
244         {
245           out.append(s[i].getSequenceAsString(j, j + 1));
246         }
247         else
248         {
249           out.append("-");
250         }
251
252         i++;
253       }
254
255       out.append("\n");
256     }
257
258     out.append("*\n");
259
260     return out.toString();
261   }
262 }