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