9f879c0d459de738fb5498dd865cff5033cea766
[jalview.git] / src / jalview / io / PileUpfile.java
1 /*
2 * Jalview - A Sequence Alignment Editor and Viewer
3 * Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version 2
8 * of the License, or (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
18 */\r
19 package jalview.io;\r
20 \r
21 \r
22 /**
23  * <p>Title: </p>
24  *  PileUpfile
25  * <p>Description: </p>
26  *
27  *  Read and write PileUp style MSF Files.
28  *  This used to be the MSFFile class, and was written according to the EBI's idea
29  *  of a subset of the MSF alignment format. But, that was updated to reflect current
30  *  GCG style IO fashion, as found in Emboss (thanks David Martin!)
31  *
32  **/\r
33 import jalview.datamodel.*;\r
34 \r
35 import jalview.util.*;\r
36 \r
37 import java.io.*;\r
38 \r
39 import java.util.*;\r
40 \r
41 \r
42 public class PileUpfile extends AlignFile {\r
43     public PileUpfile() {\r
44     }\r
45 \r
46     public PileUpfile(String inStr) {\r
47         super(inStr);\r
48     }\r
49 \r
50     public PileUpfile(String inFile, String type) throws IOException {\r
51         super(inFile, type);\r
52     }\r
53 \r
54     public void parse() {\r
55         int i = 0;\r
56         boolean seqFlag = false;\r
57         String key = new String();\r
58         Vector headers = new Vector();\r
59         Hashtable seqhash = new Hashtable();\r
60         String line;\r
61 \r
62         try {\r
63             while ((line = nextLine()) != null) {\r
64                 StringTokenizer str = new StringTokenizer(line);\r
65 \r
66                 while (str.hasMoreTokens()) {\r
67                     String inStr = str.nextToken();\r
68 \r
69                     //If line has header information add to the headers vector\r
70                     if (inStr.indexOf("Name:") != -1) {\r
71                         key = str.nextToken();\r
72                         headers.addElement(key);\r
73                     }\r
74 \r
75                     //if line has // set SeqFlag to 1 so we know sequences are coming\r
76                     if (inStr.indexOf("//") != -1) {\r
77                         seqFlag = true;\r
78                     }\r
79 \r
80                     //Process lines as sequence lines if seqFlag is set\r
81                     if ((inStr.indexOf("//") == -1) && (seqFlag == true)) {\r
82                         //seqeunce id is the first field\r
83                         key = inStr;\r
84 \r
85                         StringBuffer tempseq;\r
86 \r
87                         //Get sequence from hash if it exists\r
88                         if (seqhash.containsKey(key)) {\r
89                             tempseq = (StringBuffer) seqhash.get(key);\r
90                         } else {\r
91                             tempseq = new StringBuffer();\r
92                             seqhash.put(key, tempseq);\r
93                         }\r
94 \r
95                         //loop through the rest of the words\r
96                         while (str.hasMoreTokens()) {\r
97                             //append the word to the sequence\r
98                             tempseq.append(str.nextToken());\r
99                         }\r
100                     }\r
101                 }\r
102             }\r
103         } catch (IOException e) {\r
104             System.err.println("Exception parsing PileUpfile " + e);\r
105             e.printStackTrace();\r
106         }\r
107 \r
108         this.noSeqs = headers.size();\r
109 \r
110         //Add sequences to the hash\r
111         for (i = 0; i < headers.size(); i++) {\r
112             if (seqhash.get(headers.elementAt(i)) != null) {\r
113                 String head = headers.elementAt(i).toString();\r
114                 String seq = seqhash.get(head).toString();\r
115 \r
116                 int start = 1;\r
117                 int end = seq.length();\r
118 \r
119                 if (maxLength < head.length()) {\r
120                     maxLength = head.length();\r
121                 }\r
122 \r
123                 if (head.indexOf("/") > 0) {\r
124                     StringTokenizer st = new StringTokenizer(head, "/");\r
125 \r
126                     if (st.countTokens() == 2) {\r
127                         head = st.nextToken();\r
128 \r
129                         String tmp = st.nextToken();\r
130                         st = new StringTokenizer(tmp, "-");\r
131 \r
132                         if (st.countTokens() == 2) {\r
133                             start = Integer.valueOf(st.nextToken()).intValue();\r
134                             end = Integer.valueOf(st.nextToken()).intValue();\r
135                         }\r
136                     }\r
137                 }\r
138 \r
139                 Sequence newSeq = new Sequence(head, seq, start, end);\r
140 \r
141                 seqs.addElement(newSeq);\r
142             } else {\r
143                 System.err.println(\r
144                     "PileUpfile Parser: Can't find sequence for " +\r
145                     headers.elementAt(i));\r
146             }\r
147         }\r
148     }\r
149 \r
150     public static int checkSum(String seq) {\r
151         //String chars =  "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz.*~&@";\r
152         int check = 0;\r
153 \r
154         String index = "--------------------------------------&---*---.-----------------@ABCDEFGHIJKLMNOPQRSTUVWXYZ------ABCDEFGHIJKLMNOPQRSTUVWXYZ----@";\r
155         index += "--------------------------------------------------------------------------------------------------------------------------------";\r
156 \r
157         for (int i = 0; i < seq.length(); i++) {\r
158             try {\r
159                 if (i < seq.length()) {\r
160                     int pos = index.indexOf(seq.substring(i, i + 1));\r
161 \r
162                     if (!index.substring(pos, pos + 1).equals("_")) {\r
163                         check += (((i % 57) + 1) * pos);\r
164                     }\r
165                 }\r
166             } catch (Exception e) {\r
167                 System.err.println("Exception during MSF Checksum calculation");\r
168                 e.printStackTrace();\r
169             }\r
170         }\r
171 \r
172         return check % 10000;\r
173     }\r
174 \r
175     public static String print(SequenceI[] s) {\r
176         StringBuffer out = new StringBuffer("PileUp\n\n");\r
177 \r
178         int max = 0;\r
179         int maxid = 0;\r
180 \r
181         int i = 0;\r
182         String big = "";\r
183 \r
184         while ((i < s.length) && (s[i] != null)) {\r
185             big += s[i].getSequence();\r
186             i++;\r
187         }\r
188 \r
189         i = 0;\r
190 \r
191         int bigcheck = checkSum(big);\r
192 \r
193         out.append("   MSF: " + s[0].getSequence().length() +\r
194             "   Type: P    Check:  " + bigcheck + "   ..\n\n\n");\r
195 \r
196         while ((i < s.length) && (s[i] != null)) {\r
197             String seq = s[i].getSequence();\r
198             String name = s[i].getName() + "/" + s[i].getStart() + "-" +\r
199                 s[i].getEnd();\r
200             int check = checkSum(s[i].getSequence());\r
201             out.append(" Name: " + name + " oo  Len:  " +\r
202                 s[i].getSequence().length() + "  Check:  " + check +\r
203                 "  Weight:  1.00\n");\r
204 \r
205             if (seq.length() > max) {\r
206                 max = seq.length();\r
207             }\r
208 \r
209             if (name.length() > maxid) {\r
210                 maxid = name.length();\r
211             }\r
212 \r
213             i++;\r
214         }\r
215 \r
216         if (maxid < 10) {\r
217             maxid = 10;\r
218         }\r
219 \r
220         maxid++;\r
221         out.append("\n\n//\n\n");\r
222 \r
223         int len = 50;\r
224 \r
225         int nochunks = (max / len) + 1;\r
226 \r
227         if ((max % len) == 0) {\r
228             nochunks--;\r
229         }\r
230 \r
231         for (i = 0; i < nochunks; i++) {\r
232             int j = 0;\r
233 \r
234             while ((j < s.length) && (s[j] != null)) {\r
235                 String name = s[j].getName();\r
236                 out.append(new Format("%-" + maxid + "s").form(name + "/" +\r
237                         s[j].getStart() + "-" + s[j].getEnd()) + " ");\r
238 \r
239                 for (int k = 0; k < 5; k++) {\r
240                     int start = (i * 50) + (k * 10);\r
241                     int end = start + 10;\r
242 \r
243                     if ((end < s[j].getSequence().length()) &&\r
244                             (start < s[j].getSequence().length())) {\r
245                         out.append(s[j].getSequence().substring(start, end));\r
246 \r
247                         if (k < 4) {\r
248                             out.append(" ");\r
249                         } else {\r
250                             out.append("\n");\r
251                         }\r
252                     } else {\r
253                         if (start < s[j].getSequence().length()) {\r
254                             out.append(s[j].getSequence().substring(start));\r
255                             out.append("\n");\r
256                         } else {\r
257                             if (k == 0) {\r
258                                 out.append("\n");\r
259                             }\r
260                         }\r
261                     }\r
262                 }\r
263 \r
264                 j++;\r
265             }\r
266 \r
267             out.append("\n");\r
268         }\r
269 \r
270         return out.toString();\r
271     }\r
272 \r
273     public String print() {\r
274         return print(getSeqsAsArray());\r
275     }\r
276 }\r