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