5d7be8c52a9ba25275a8559fec5799b099cb6b4b
[jalview.git] / src / jalview / io / ClustalFile.java
1 /*\r
2  * Jalview - A Sequence Alignment Editor and Viewer\r
3  * Copyright (C) 2007 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()\r
47       throws IOException\r
48   {\r
49     int i = 0;\r
50     boolean flag = false;\r
51 \r
52     Vector headers = new Vector();\r
53     Hashtable seqhash = new Hashtable();\r
54     StringBuffer tempseq;\r
55     String line, id;\r
56     StringTokenizer str;\r
57 \r
58     try\r
59     {\r
60       while ( (line = nextLine()) != null)\r
61       {\r
62         if (line.indexOf(" ") != 0)\r
63         {\r
64           str = new StringTokenizer(line, " ");\r
65 \r
66           if (str.hasMoreTokens())\r
67           {\r
68             id = str.nextToken();\r
69 \r
70             if (id.equalsIgnoreCase("CLUSTAL"))\r
71             {\r
72               flag = true;\r
73             }\r
74             else\r
75             {\r
76               if (flag)\r
77               {\r
78                 if (seqhash.containsKey(id))\r
79                 {\r
80                   tempseq = (StringBuffer) seqhash.get(id);\r
81                 }\r
82                 else\r
83                 {\r
84                   tempseq = new StringBuffer();\r
85                   seqhash.put(id, tempseq);\r
86                 }\r
87 \r
88                 if (! (headers.contains(id)))\r
89                 {\r
90                   headers.addElement(id);\r
91                 }\r
92 \r
93                 if (str.hasMoreTokens())\r
94                 {\r
95                   tempseq.append(str.nextToken());\r
96                 }\r
97               }\r
98             }\r
99           }\r
100           else\r
101           {\r
102             flag = true;\r
103           }\r
104         }\r
105       }\r
106     }\r
107     catch (IOException e)\r
108     {\r
109       System.err.println("Exception parsing clustal file " + e);\r
110       e.printStackTrace();\r
111     }\r
112 \r
113     if (flag)\r
114     {\r
115       this.noSeqs = headers.size();\r
116 \r
117       //Add sequences to the hash\r
118       for (i = 0; i < headers.size(); i++)\r
119       {\r
120         if (seqhash.get(headers.elementAt(i)) != null)\r
121         {\r
122           if (maxLength < seqhash.get(headers.elementAt(i)).toString()\r
123               .length())\r
124           {\r
125             maxLength = seqhash.get(headers.elementAt(i)).toString()\r
126                 .length();\r
127           }\r
128 \r
129           Sequence newSeq = parseId(headers.elementAt(i).toString());\r
130           newSeq.setSequence(seqhash.get(headers.elementAt(i).toString()).\r
131                              toString());\r
132 \r
133           seqs.addElement(newSeq);\r
134         }\r
135         else\r
136         {\r
137           System.err.println(\r
138               "Clustal File Reader: Can't find sequence for " +\r
139               headers.elementAt(i));\r
140         }\r
141       }\r
142     }\r
143   }\r
144 \r
145   public String print()\r
146   {\r
147     return print(getSeqsAsArray());\r
148   }\r
149 \r
150   public String print(SequenceI[] s)\r
151   {\r
152     StringBuffer out = new StringBuffer("CLUSTAL\n\n");\r
153 \r
154     int max = 0;\r
155     int maxid = 0;\r
156 \r
157     int i = 0;\r
158 \r
159     while ( (i < s.length) && (s[i] != null))\r
160     {\r
161       String tmp = printId(s[i]);\r
162 \r
163       if (s[i].getSequence().length > max)\r
164       {\r
165         max = s[i].getSequence().length;\r
166       }\r
167 \r
168       if (tmp.length() > maxid)\r
169       {\r
170         maxid = tmp.length();\r
171       }\r
172 \r
173       i++;\r
174     }\r
175 \r
176     if (maxid < 15)\r
177     {\r
178       maxid = 15;\r
179     }\r
180 \r
181     maxid++;\r
182 \r
183     int len = 60;\r
184     int nochunks = (max / len) + 1;\r
185 \r
186     for (i = 0; i < nochunks; i++)\r
187     {\r
188       int j = 0;\r
189 \r
190       while ( (j < s.length) && (s[j] != null))\r
191       {\r
192         out.append(new Format("%-" + maxid + "s").form(printId(s[j]) + " "));\r
193 \r
194         int start = i * len;\r
195         int end = start + len;\r
196 \r
197         if ( (end < s[j].getSequence().length) &&\r
198             (start < s[j].getSequence().length))\r
199         {\r
200           out.append(s[j].getSequenceAsString(start, end));\r
201         }\r
202         else\r
203         {\r
204           if (start < s[j].getSequence().length)\r
205           {\r
206             out.append(s[j].getSequenceAsString().substring(start));\r
207           }\r
208         }\r
209 \r
210         out.append("\n");\r
211         j++;\r
212       }\r
213 \r
214       out.append("\n");\r
215     }\r
216 \r
217     return out.toString();\r
218   }\r
219 }\r