ensure lastSeq is refreshed if new feature added
[jalview.git] / src / jalview / io / ClustalFile.java
1 /*\r
2  * Jalview - A Sequence Alignment Editor and Viewer\r
3  * Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
4  *\r
5  * This program is free software; you can redistribute it and/or\r
6  * modify it under the terms of the GNU General Public License\r
7  * as published by the Free Software Foundation; either version 2\r
8  * of the License, or (at your option) any later version.\r
9  *\r
10  * This program is distributed in the hope that it will be useful,\r
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
13  * GNU General Public License for more details.\r
14  *\r
15  * You should have received a copy of the GNU General Public License\r
16  * along with this program; if not, write to the Free Software\r
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
18  */\r
19 package jalview.io;\r
20 \r
21 import java.io.*;\r
22 import java.util.*;\r
23 \r
24 import jalview.datamodel.*;\r
25 import jalview.util.*;\r
26 \r
27 public class ClustalFile\r
28     extends AlignFile\r
29 {\r
30 \r
31   public ClustalFile()\r
32   {\r
33   }\r
34 \r
35   public ClustalFile(String inFile, String type)\r
36       throws IOException\r
37   {\r
38     super(inFile, type);\r
39   }\r
40 \r
41   public void initData()\r
42   {\r
43     super.initData();\r
44   }\r
45 \r
46   public void parse() throws IOException\r
47   {\r
48     int i = 0;\r
49     boolean flag = false;\r
50 \r
51     Vector headers = new Vector();\r
52     Hashtable seqhash = new Hashtable();\r
53     StringBuffer tempseq;\r
54     String line, id;\r
55     StringTokenizer str;\r
56 \r
57     try\r
58     {\r
59       while ( (line = nextLine()) != null)\r
60       {\r
61         if (line.indexOf(" ") != 0)\r
62         {\r
63           str = new StringTokenizer(line, " ");\r
64 \r
65           if (str.hasMoreTokens())\r
66           {\r
67             id = str.nextToken();\r
68 \r
69             if (id.equalsIgnoreCase("CLUSTAL"))\r
70             {\r
71               flag = true;\r
72             }\r
73             else\r
74             {\r
75               if (flag)\r
76               {\r
77                 if (seqhash.containsKey(id))\r
78                 {\r
79                   tempseq = (StringBuffer) seqhash.get(id);\r
80                 }\r
81                 else\r
82                 {\r
83                   tempseq = new StringBuffer();\r
84                   seqhash.put(id, tempseq);\r
85                 }\r
86 \r
87                 if (! (headers.contains(id)))\r
88                 {\r
89                   headers.addElement(id);\r
90                 }\r
91 \r
92                 if (str.hasMoreTokens())\r
93                 {\r
94                   tempseq.append(str.nextToken());\r
95                 }\r
96               }\r
97             }\r
98           }\r
99           else\r
100             flag = true;\r
101         }\r
102       }\r
103     }\r
104     catch (IOException e)\r
105     {\r
106       System.err.println("Exception parsing clustal file " + e);\r
107       e.printStackTrace();\r
108     }\r
109 \r
110     if (flag)\r
111     {\r
112       this.noSeqs = headers.size();\r
113 \r
114       //Add sequences to the hash\r
115       for (i = 0; i < headers.size(); i++)\r
116       {\r
117         if (seqhash.get(headers.elementAt(i)) != null)\r
118         {\r
119           if (maxLength < seqhash.get(headers.elementAt(i)).toString()\r
120               .length())\r
121           {\r
122             maxLength = seqhash.get(headers.elementAt(i)).toString()\r
123                 .length();\r
124           }\r
125 \r
126           Sequence newSeq = parseId(headers.elementAt(i).toString());\r
127           newSeq.setSequence( seqhash.get(headers.elementAt(i).toString()).toString() );\r
128 \r
129           if (!isValidProteinSequence(newSeq.getSequence()))\r
130           {\r
131               throw new IOException(AppletFormatAdapter.INVALID_CHARACTERS\r
132                                     + " : " + newSeq.getName()\r
133                                     + " : " + invalidCharacter);\r
134           }\r
135 \r
136 \r
137           seqs.addElement(newSeq);\r
138         }\r
139         else\r
140         {\r
141           System.err.println(\r
142               "Clustal File Reader: Can't find sequence for " +\r
143               headers.elementAt(i));\r
144         }\r
145       }\r
146     }\r
147   }\r
148 \r
149   public String print()\r
150   {\r
151     return print(getSeqsAsArray());\r
152   }\r
153 \r
154   public String print(SequenceI[] s)\r
155   {\r
156     StringBuffer out = new StringBuffer("CLUSTAL\n\n");\r
157 \r
158     int max = 0;\r
159     int maxid = 0;\r
160 \r
161     int i = 0;\r
162 \r
163     while ( (i < s.length) && (s[i] != null))\r
164     {\r
165       String tmp = printId(s[i]);\r
166 \r
167       if (s[i].getSequence().length > max)\r
168       {\r
169         max = s[i].getSequence().length;\r
170       }\r
171 \r
172       if (tmp.length() > maxid)\r
173       {\r
174         maxid = tmp.length();\r
175       }\r
176 \r
177       i++;\r
178     }\r
179 \r
180     if (maxid < 15)\r
181     {\r
182       maxid = 15;\r
183     }\r
184 \r
185     maxid++;\r
186 \r
187     int len = 60;\r
188     int nochunks = (max / len) + 1;\r
189 \r
190     for (i = 0; i < nochunks; i++)\r
191     {\r
192       int j = 0;\r
193 \r
194       while ( (j < s.length) && (s[j] != null))\r
195       {\r
196         out.append(new Format("%-" + maxid + "s").form( printId(s[j]) + " "));\r
197 \r
198         int start = i * len;\r
199         int end = start + len;\r
200 \r
201         if ( (end < s[j].getSequence().length) &&\r
202             (start < s[j].getSequence().length))\r
203         {\r
204           out.append(s[j].getSequenceAsString(start, end));\r
205         }\r
206         else\r
207         {\r
208           if (start < s[j].getSequence().length)\r
209           {\r
210             out.append(s[j].getSequenceAsString().substring(start));\r
211           }\r
212         }\r
213 \r
214         out.append("\n");\r
215         j++;\r
216       }\r
217 \r
218       out.append("\n");\r
219     }\r
220 \r
221     return out.toString();\r
222   }\r
223 }\r