Formatted source
[jalview.git] / src / jalview / io / ClustalFile.java
1 /*\r
2 * Jalview - A Sequence Alignment Editor and Viewer\r
3 * Copyright (C) 2005 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 jalview.datamodel.*;\r
22 \r
23 import jalview.util.*;\r
24 \r
25 import java.io.*;\r
26 \r
27 import java.util.*;\r
28 \r
29 \r
30 public class ClustalFile extends AlignFile {\r
31     Vector ids;\r
32 \r
33     public ClustalFile() {\r
34     }\r
35 \r
36     public ClustalFile(String inStr) {\r
37         super(inStr);\r
38     }\r
39 \r
40     public ClustalFile(String inFile, String type) throws IOException {\r
41         super(inFile, type);\r
42     }\r
43 \r
44     public void initData() {\r
45         super.initData();\r
46         ids = new Vector();\r
47     }\r
48 \r
49     public void parse() {\r
50         int i = 0;\r
51         boolean flag = false;\r
52 \r
53         Vector headers = new Vector();\r
54         Hashtable seqhash = new Hashtable();\r
55 \r
56         String line;\r
57 \r
58         try {\r
59             while ((line = nextLine()) != null) {\r
60                 if (line.indexOf(" ") != 0) {\r
61                     StringTokenizer str = new StringTokenizer(line, " ");\r
62                     String id = "";\r
63 \r
64                     if (str.hasMoreTokens()) {\r
65                         id = str.nextToken();\r
66 \r
67                         if (id.equals("CLUSTAL")) {\r
68                             flag = true;\r
69                         } else {\r
70                             if (flag) {\r
71                                 StringBuffer tempseq;\r
72 \r
73                                 if (seqhash.containsKey(id)) {\r
74                                     tempseq = (StringBuffer) seqhash.get(id);\r
75                                 } else {\r
76                                     tempseq = new StringBuffer();\r
77                                     seqhash.put(id, tempseq);\r
78                                 }\r
79 \r
80                                 if (!(headers.contains(id))) {\r
81                                     headers.addElement(id);\r
82                                 }\r
83 \r
84                                 if (str.hasMoreTokens()) {\r
85                                     tempseq.append(str.nextToken());\r
86                                 }\r
87                             }\r
88                         }\r
89                     }\r
90                 }\r
91             }\r
92         } catch (IOException e) {\r
93             System.err.println("Exception parsing clustal file " + e);\r
94             e.printStackTrace();\r
95         }\r
96 \r
97         if (flag) {\r
98             this.noSeqs = headers.size();\r
99 \r
100             //Add sequences to the hash\r
101             for (i = 0; i < headers.size(); i++) {\r
102                 int start = -1;\r
103                 int end = -1;\r
104 \r
105                 if (seqhash.get(headers.elementAt(i)) != null) {\r
106                     if (maxLength < seqhash.get(headers.elementAt(i)).toString()\r
107                                                .length()) {\r
108                         maxLength = seqhash.get(headers.elementAt(i)).toString()\r
109                                            .length();\r
110                     }\r
111 \r
112                     String head = headers.elementAt(i).toString();\r
113                     start = 1;\r
114                     end = seqhash.get(headers.elementAt(i)).toString().length();\r
115 \r
116                     if (head.indexOf("/") > 0) {\r
117                         StringTokenizer st = new StringTokenizer(head, "/");\r
118 \r
119                         if (st.countTokens() == 2) {\r
120                             ids.addElement(st.nextToken());\r
121 \r
122                             String tmp = st.nextToken();\r
123                             st = new StringTokenizer(tmp, "-");\r
124 \r
125                             if (st.countTokens() == 2) {\r
126                                 start = Integer.valueOf(st.nextToken())\r
127                                                .intValue();\r
128                                 end = Integer.valueOf(st.nextToken()).intValue();\r
129                             }\r
130                         } else {\r
131                             ids.addElement(headers.elementAt(i));\r
132                         }\r
133                     } else {\r
134                         ids.addElement(headers.elementAt(i));\r
135                     }\r
136 \r
137                     Sequence newSeq = new Sequence(ids.elementAt(i).toString(),\r
138                             seqhash.get(headers.elementAt(i).toString())\r
139                                    .toString(), start, end);\r
140 \r
141                     seqs.addElement(newSeq);\r
142                 } else {\r
143                     System.err.println(\r
144                         "Clustal File Reader: Can't find sequence for " +\r
145                         headers.elementAt(i));\r
146                 }\r
147             }\r
148         }\r
149     }\r
150 \r
151     public String print() {\r
152         return print(getSeqsAsArray());\r
153     }\r
154 \r
155     public static String print(SequenceI[] s) {\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             String tmp = s[i].getName() + "/" + s[i].getStart() + "-" +\r
165                 s[i].getEnd();\r
166 \r
167             if (s[i].getSequence().length() > max) {\r
168                 max = s[i].getSequence().length();\r
169             }\r
170 \r
171             if (tmp.length() > maxid) {\r
172                 maxid = tmp.length();\r
173             }\r
174 \r
175             i++;\r
176         }\r
177 \r
178         if (maxid < 15) {\r
179             maxid = 15;\r
180         }\r
181 \r
182         maxid++;\r
183 \r
184         int len = 60;\r
185         int nochunks = (max / len) + 1;\r
186 \r
187         for (i = 0; i < nochunks; i++) {\r
188             int j = 0;\r
189 \r
190             while ((j < s.length) && (s[j] != null)) {\r
191                 out.append(new Format("%-" + maxid + "s").form(s[j].getName() +\r
192                         "/" + s[j].getStart() + "-" + s[j].getEnd()) + " ");\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                     out.append(s[j].getSequence().substring(start, end));\r
200                 } else {\r
201                     if (start < s[j].getSequence().length()) {\r
202                         out.append(s[j].getSequence().substring(start));\r
203                     }\r
204                 }\r
205 \r
206                 out.append("\n");\r
207                 j++;\r
208             }\r
209 \r
210             out.append("\n");\r
211         }\r
212 \r
213         return out.toString();\r
214     }\r
215 }\r