GPL license added
[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 \r
20 package jalview.io;\r
21 \r
22 import jalview.datamodel.*;\r
23 import jalview.util.*;\r
24 \r
25 import java.io.*;\r
26 import java.util.*;\r
27 \r
28 public class ClustalFile extends AlignFile {\r
29 \r
30   Vector ids;\r
31 \r
32   public ClustalFile()\r
33   {}\r
34 \r
35   public ClustalFile(String inStr) {\r
36     super(inStr);\r
37   }\r
38 \r
39 \r
40   public void initData() {\r
41     super.initData();\r
42     ids = new Vector();\r
43   }\r
44 \r
45   public ClustalFile(String inFile, String type) throws IOException {\r
46     super(inFile,type);\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             if (id.equals("CLUSTAL")) {\r
67               flag = true;\r
68             } else {\r
69               if (flag) {\r
70                 StringBuffer tempseq;\r
71                 if (seqhash.containsKey(id)) {\r
72                   tempseq = (StringBuffer)seqhash.get(id);\r
73                 } else {\r
74                   tempseq = new StringBuffer();\r
75                   seqhash.put(id,tempseq);\r
76                 }\r
77 \r
78                 if (!(headers.contains(id))) {\r
79                   headers.addElement(id);\r
80                 }\r
81 \r
82                 if(str.hasMoreTokens())\r
83                   tempseq.append(str.nextToken());\r
84               }\r
85             }\r
86           }\r
87         }\r
88       }\r
89     } catch (IOException e) {\r
90       System.err.println("Exception parsing clustal file " + e);\r
91       e.printStackTrace();\r
92     }\r
93 \r
94     if (flag) {\r
95       this.noSeqs = headers.size();\r
96 \r
97       //Add sequences to the hash\r
98       for (i = 0; i < headers.size(); i++ ) {\r
99         int start = -1;\r
100         int end   = -1;\r
101 \r
102         if ( seqhash.get(headers.elementAt(i)) != null) {\r
103           if (maxLength <  seqhash.get(headers.elementAt(i)).toString().length() ) {\r
104             maxLength =  seqhash.get(headers.elementAt(i)).toString().length();\r
105           }\r
106           String head =  headers.elementAt(i).toString();\r
107           start = 1;\r
108           end   =  seqhash.get(headers.elementAt(i)).toString().length();\r
109 \r
110           if (head.indexOf("/") > 0 ) {\r
111             StringTokenizer st = new StringTokenizer(head,"/");\r
112             if (st.countTokens() == 2) {\r
113 \r
114               ids.addElement(st.nextToken());\r
115 \r
116               String tmp = st.nextToken();\r
117               st = new StringTokenizer(tmp,"-");\r
118               if (st.countTokens() == 2) {\r
119                 start = Integer.valueOf(st.nextToken()).intValue();\r
120                 end = Integer.valueOf(st.nextToken()).intValue();\r
121               }\r
122             } else {\r
123               ids.addElement(headers.elementAt(i));\r
124             }\r
125           }  else {\r
126             ids.addElement(headers.elementAt(i));\r
127 \r
128           }\r
129           Sequence newSeq = new Sequence(ids.elementAt(i).toString(),\r
130                                          seqhash.get(headers.elementAt(i).toString()).toString(),start,end);\r
131 \r
132           seqs.addElement(newSeq);\r
133 \r
134         } else {\r
135           System.err.println("Clustal File Reader: Can't find sequence for " + headers.elementAt(i));\r
136         }\r
137       }\r
138     }\r
139 \r
140   }\r
141 \r
142   public String print() {\r
143     return print(getSeqsAsArray());\r
144   }\r
145   public static String print(SequenceI[] s) {\r
146 \r
147     StringBuffer out = new StringBuffer("CLUSTAL\n\n");\r
148 \r
149     int max = 0;\r
150     int maxid = 0;\r
151 \r
152     int i = 0;\r
153 \r
154     while (i < s.length && s[i] != null) {\r
155       String tmp = s[i].getName() + "/" + s[i].getStart() + "-" + s[i].getEnd();\r
156 \r
157       if (s[i].getSequence().length() > max) {\r
158         max = s[i].getSequence().length();\r
159       }\r
160       if (tmp.length() > maxid) {\r
161         maxid = tmp.length();\r
162       }\r
163       i++;\r
164     }\r
165 \r
166     if (maxid < 15) {\r
167       maxid = 15;\r
168     }\r
169     maxid++;\r
170     int len = 60;\r
171     int nochunks =  max / len + 1;\r
172 \r
173     for (i = 0; i < nochunks; i++) {\r
174       int j = 0;\r
175       while ( j < s.length && s[j] != null) {\r
176         out.append( new Format("%-" + maxid + "s").form(s[j].getName() + "/" + s[j].getStart() + "-" + s[j].getEnd()) + " ");\r
177         int start = i*len;\r
178         int end = start + len;\r
179 \r
180         if (end < s[j].getSequence().length() && start < s[j].getSequence().length() )\r
181           out.append(s[j].getSequence().substring(start,end));\r
182         else\r
183         {\r
184           if (start < s[j].getSequence().length())\r
185             out.append(s[j].getSequence().substring(start));\r
186         }\r
187         out.append("\n");\r
188         j++;\r
189       }\r
190       out.append("\n");\r
191 \r
192     }\r
193 \r
194     return out.toString();\r
195   }\r
196 \r
197 \r
198 }\r