JAL-3365 expand range of allowed DSSP secondary structure symbols in Stockholm files
[jalview.git] / src / jalview / io / BLCFile.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.Sequence;
24 import jalview.datamodel.SequenceI;
25
26 import java.io.IOException;
27 import java.util.Vector;
28
29 /**
30  * DOCUMENT ME!
31  * 
32  * @author $author$
33  * @version $Revision$
34  */
35 public class BLCFile extends AlignFile
36 {
37   Vector titles;
38
39   /**
40    * Creates a new BLCFile object.
41    */
42   public BLCFile()
43   {
44   }
45
46   /**
47    * Creates a new BLCFile object.
48    * 
49    * @param inFile
50    *          DOCUMENT ME!
51    * @param sourceType
52    *          DOCUMENT ME!
53    * 
54    * @throws IOException
55    *           DOCUMENT ME!
56    */
57   public BLCFile(String inFile, DataSourceType sourceType)
58           throws IOException
59   {
60     super(inFile, sourceType);
61   }
62
63   public BLCFile(FileParse source) throws IOException
64   {
65     super(source);
66   }
67
68   /**
69    * DOCUMENT ME!
70    */
71   @Override
72   public void initData()
73   {
74     super.initData();
75     titles = new Vector();
76   }
77
78   /**
79    * Control the number of block iterations to skip before returning. set to 0
80    * to read first block file entry only set to -1 to read last block file entry
81    * only set to greater than zero to skip at most that many entries before
82    * parsing
83    */
84   int iterationSkips = 0;
85
86   /**
87    * The iteration number for the alignment actually parsed from the blc file
88    */
89   int iterationCount = 0;
90
91   /**
92    * DOCUMENT ME!
93    */
94   @Override
95   public void parse() throws IOException
96   {
97     StringBuffer headerLines = new StringBuffer();
98     int numHeaderLines = 0; // number of lines appended.
99     StringBuffer[] seqstrings = null;
100     if (suffix != null)
101     {
102       try
103       {
104         iterationSkips = Integer.parseInt(suffix);
105       } catch (NumberFormatException e)
106       {
107         iterationSkips = 0; // first
108       }
109     }
110
111     String line = null;
112
113     do
114     {
115       boolean idsFound = false;
116       boolean newids = false;
117       // search for ID header.
118       do
119       {
120         line = nextLine();
121         if (line == null)
122         {
123           break;
124         }
125         // seek end of ids
126         if (line.indexOf("*") > -1)
127         {
128           idsFound = true;
129
130           break;
131         }
132
133         int abracket = line.indexOf(">");
134
135         if (abracket > -1)
136         {
137
138           if (iterationCount > 0 && !newids)
139           {
140             // we have a new set of IDs to record.
141             newids = true;
142             seqs.removeAllElements();
143           }
144
145           line = line.substring(abracket + 1);
146
147           Sequence seq = parseId(line);
148           seqs.addElement(seq);
149         }
150         else
151         {
152           // header lines - keep them for the alignment comments.
153           headerLines.append(line);
154           headerLines.append(newline);
155           numHeaderLines++;
156         }
157       } while (!idsFound);
158       if (line == null)
159       {
160         break; // end of file.
161       }
162       int starCol = line.indexOf("*");
163       seqstrings = new StringBuffer[seqs.size()];
164
165       for (int i = 0; i < seqs.size(); i++)
166       {
167         if (seqstrings[i] == null)
168         {
169           seqstrings[i] = new StringBuffer();
170         }
171       }
172
173       try
174       {
175         line = nextLine();
176         while (line != null && line.indexOf("*") == -1)
177         {
178           for (int i = 0; i < seqs.size(); i++)
179           {
180             if (line.length() > (i + starCol))
181             {
182               seqstrings[i].append(line.charAt(i + starCol));
183             }
184           }
185           line = nextLine();
186         }
187       } catch (IOException e)
188       {
189         if (iterationCount == 0)
190         {
191           throw (e); // otherwise we've just run out of iterations.
192         }
193         else
194         {
195           iterationSkips = 0;
196         }
197       }
198       iterationCount++;
199     } while (--iterationSkips != -1);
200
201     for (int i = 0; i < seqs.size(); i++)
202     {
203       Sequence newSeq = (Sequence) seqs.elementAt(i);
204
205       newSeq.setSequence(seqstrings[i].toString());
206     }
207     if (seqs.size() > 0)
208     {
209       if (headerLines.length() > 1 + numHeaderLines)
210       {
211         // just whitespace or not.
212         setAlignmentProperty("Comments", headerLines.toString());
213       }
214       setAlignmentProperty("iteration", "" + iterationCount);
215     }
216   }
217
218   /**
219    * DOCUMENT ME!
220    * 
221    * @param s
222    *          DOCUMENT ME!
223    * 
224    * @return DOCUMENT ME!
225    */
226   @Override
227   public String print(SequenceI[] s, boolean jvsuffix)
228   {
229     StringBuffer out = new StringBuffer();
230     /**
231      * A general parser for ids. Will look for dbrefs in Uniprot format
232      * source|id And also Jalview /start-end
233      * 
234      * @String id Id to be parsed
235      */
236     int i = 0;
237     int max = -1;
238
239     while ((i < s.length) && (s[i] != null))
240     {
241       out.append(">" + printId(s[i], jvsuffix));
242       if (s[i].getDescription() != null)
243       {
244         out.append(" " + s[i].getDescription());
245       }
246
247       out.append(newline);
248
249       max = Math.max(max, s[i].getLength());
250
251       i++;
252     }
253
254     out.append("* iteration 1");
255     out.append(newline);
256
257     for (int j = 0; j < max; j++)
258     {
259       i = 0;
260
261       while ((i < s.length) && (s[i] != null))
262       {
263         if (s[i].getSequence().length > j)
264         {
265           out.append(s[i].getSequenceAsString(j, j + 1));
266         }
267         else
268         {
269           out.append("-");
270         }
271
272         i++;
273       }
274
275       out.append(newline);
276     }
277
278     out.append("*");
279     out.append(newline);
280
281     return out.toString();
282   }
283 }