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