Response to bug mantis?id=8187 - some quick hacks to read and write david's MSF file...
[jalview.git] / src / jalview / io / MSFfile.java
1 package jalview.io;\r
2 \r
3 import jalview.datamodel.*;\r
4 import jalview.util.*;\r
5 \r
6 import java.io.*;\r
7 import java.util.*;\r
8 \r
9 public class MSFfile extends AlignFile {\r
10 \r
11   public MSFfile()\r
12   {}\r
13 \r
14   public MSFfile(String inStr) {\r
15     super(inStr);\r
16   }\r
17 \r
18   public MSFfile(String inFile, String type) throws IOException {\r
19     super(inFile,type);\r
20   }\r
21 \r
22   private static com.stevesoft.pat.Regex gapre = new com.stevesoft.pat.Regex("\\~","-");\r
23   private static com.stevesoft.pat.Regex re2gap = new com.stevesoft.pat.Regex("["+jalview.util.Comparison.GapChars+"]","\\~");\r
24 \r
25   public void parse() {\r
26     int       i       = 0;\r
27     boolean   seqFlag = false;\r
28     String    key     = new String();\r
29     Vector    headers = new Vector();\r
30     Hashtable seqhash = new Hashtable();\r
31     String    line;\r
32 \r
33     try {\r
34     while ((line = nextLine()) != null) {\r
35 \r
36       StringTokenizer str = new StringTokenizer(line);\r
37 \r
38       while (str.hasMoreTokens()) {\r
39 \r
40         String inStr = str.nextToken();\r
41 \r
42         //If line has header information add to the headers vector\r
43         if (inStr.indexOf("Name:") != -1) {\r
44           key = str.nextToken();\r
45           headers.addElement(key);\r
46         }\r
47 \r
48         //if line has // set SeqFlag to 1 so we know sequences are coming\r
49         if (inStr.indexOf("//") != -1) {\r
50           seqFlag = true;\r
51         }\r
52 \r
53         //Process lines as sequence lines if seqFlag is set\r
54         if (( inStr.indexOf("//") == -1) && (seqFlag == true)) {\r
55           //seqeunce id is the first field\r
56           key = inStr;\r
57           StringBuffer tempseq;\r
58 \r
59           //Get sequence from hash if it exists\r
60           if (seqhash.containsKey(key)) {\r
61             tempseq = (StringBuffer)seqhash.get(key);\r
62           } else {\r
63             tempseq = new StringBuffer();\r
64             seqhash.put(key,tempseq);\r
65           }\r
66 \r
67           //loop through the rest of the words\r
68           while (str.hasMoreTokens()) {\r
69             //append the word to the sequence\r
70             tempseq.append(str.nextToken());\r
71           }\r
72         }\r
73       }\r
74     }\r
75     } catch (IOException e) {\r
76       System.err.println("Exception parsing MSFFile " + e);\r
77       e.printStackTrace();\r
78     }\r
79 \r
80     this.noSeqs = headers.size();\r
81 \r
82     //Add sequences to the hash\r
83     for (i = 0; i < headers.size(); i++ ) {\r
84 \r
85       if ( seqhash.get(headers.elementAt(i)) != null) {\r
86         String head =  headers.elementAt(i).toString();\r
87         String seq  =  seqhash.get(head).toString();\r
88 \r
89         int start = 1;\r
90         int end = seq.length();\r
91 \r
92         if (maxLength <  head.length() ) {\r
93           maxLength =  head.length();\r
94         }\r
95 \r
96         if (head.indexOf("/") > 0 ) {\r
97 \r
98           StringTokenizer st = new StringTokenizer(head,"/");\r
99 \r
100           if (st.countTokens() == 2) {\r
101 \r
102             head = st.nextToken();\r
103             String tmp = st.nextToken();\r
104             st = new StringTokenizer(tmp,"-");\r
105             if (st.countTokens() == 2) {\r
106               start = Integer.valueOf(st.nextToken()).intValue();\r
107               end = Integer.valueOf(st.nextToken()).intValue();\r
108             }\r
109           }\r
110         }\r
111         // Replace ~ with a sensible gap character\r
112         seq = gapre.replaceAll(seq);\r
113         Sequence newSeq = new Sequence(head,seq,start,end);\r
114 \r
115         seqs.addElement(newSeq);\r
116 \r
117       } else {\r
118         System.err.println("MSFFile Parser: Can't find sequence for " + headers.elementAt(i));\r
119       }\r
120     }\r
121 \r
122   }\r
123 \r
124   public static int checkSum(String seq) {\r
125     //String chars =  "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz.*~&@";\r
126     int check = 0;\r
127 \r
128     String index =  "--------------------------------------&---*---.-----------------@ABCDEFGHIJKLMNOPQRSTUVWXYZ------ABCDEFGHIJKLMNOPQRSTUVWXYZ----@";\r
129     index += "--------------------------------------------------------------------------------------------------------------------------------";\r
130 \r
131     for(int i = 0; i < seq.length(); i++) {\r
132       try {\r
133         if (i <seq.length()) {\r
134           int pos = index.indexOf(seq.substring(i,i+1));\r
135           if (!index.substring(pos,pos+1).equals("_")) {\r
136             check += ((i % 57) + 1) * pos;\r
137           }\r
138         }\r
139       } catch (Exception e) {\r
140         System.err.println("Exception during MSF Checksum calculation");\r
141         e.printStackTrace();\r
142       }\r
143     }\r
144     return check % 10000;\r
145   }\r
146 \r
147   public static String print(SequenceI[] s) {\r
148     StringBuffer out = new StringBuffer("PileUp\n\n");\r
149 \r
150     int max = 0;\r
151     int maxid = 0;\r
152 \r
153     int i = 0;\r
154     String big = "";\r
155     while (i < s.length && s[i] != null) {\r
156       big += s[i].getSequence();\r
157       i++;\r
158     }\r
159     i = 0;\r
160     int bigcheck = checkSum(big);\r
161 \r
162     out.append("   MSF: " + s[0].getSequence().length() + "   Type: P    Check:  " + bigcheck + "   ..\n\n\n");\r
163 \r
164     while (i < s.length && s[i] != null) {\r
165       String seq = s[i].getSequence();\r
166       String name =  s[i].getName()+ "/" + s[i].getStart() + "-" + s[i].getEnd();\r
167       int check = checkSum(s[i].getSequence());\r
168       out.append(" Name: " + name + " oo  Len:  " + s[i].getSequence().length() + "  Check:  " + check + "  Weight:  1.00\n");\r
169       if (seq.length() > max) {\r
170         max = seq.length();\r
171       }\r
172       if (name.length() > maxid) {\r
173         maxid = name.length();\r
174       }\r
175       i++;\r
176     }\r
177 \r
178     if (maxid < 10) {\r
179       maxid = 10;\r
180     }\r
181     maxid++;\r
182     out.append( "\n\n//\n\n");\r
183 \r
184     int len = 50;\r
185 \r
186     int nochunks =  max / len + 1;\r
187     if (max%len == 0) {\r
188       nochunks--;\r
189     }\r
190     for (i = 0; i < nochunks; i++) {\r
191       int j = 0;\r
192       while (j < s.length && s[j] != null) {\r
193         String name =  s[j].getName();\r
194         out.append( new Format("%-" + maxid + "s").form(name + "/" + s[j].getStart() + "-" + s[j].getEnd()) + " ");\r
195         for (int k = 0; k < 5; k++) {\r
196 \r
197           int start = i*50 + k*10;\r
198           int end = start + 10;\r
199 \r
200           if (end < s[j].getSequence().length() && start < s[j].getSequence().length() ) {\r
201             out.append(re2gap.replaceAll(s[j].getSequence().substring(start,end)));\r
202             if (k < 4) {\r
203               // out.append(" ");\r
204             } else {\r
205               out.append("\n");\r
206             }\r
207           } else {\r
208             if (start < s[j].getSequence().length()) {\r
209               out.append(re2gap.replaceAll(s[j].getSequence().substring(start)));\r
210               out.append("\n");\r
211             } else {\r
212               if (k == 0) {\r
213                 out.append("\n");\r
214               }\r
215             }\r
216           }\r
217         }\r
218         j++;\r
219       }\r
220       out.append("\n");\r
221 \r
222     }\r
223     return out.toString();\r
224   }\r
225   public String print() {\r
226     return print(getSeqsAsArray());\r
227   }\r
228 }\r
229 \r
230 \r
231 \r
232 \r
233 \r
234 \r
235 \r