(JAL-965) new api methods to allow features to be loaded without automatically enabli...
[jalview.git] / src / jalview / io / ClustalFile.java
1 /*
2  * Jalview - A Sequence Alignment Editor and Viewer (Version 2.7)
3  * Copyright (C) 2011 J Procter, AM Waterhouse, G Barton, M Clamp, S Searle
4  * 
5  * This file is part of Jalview.
6  * 
7  * Jalview is free software: you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License 
9  * as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
10  * 
11  * Jalview is distributed in the hope that it will be useful, but 
12  * WITHOUT ANY WARRANTY; without even the implied warranty 
13  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
14  * PURPOSE.  See the GNU General Public License for more details.
15  * 
16  * You should have received a copy of the GNU General Public License along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
17  */
18 package jalview.io;
19
20 import java.io.*;
21 import java.util.*;
22
23 import jalview.datamodel.*;
24 import jalview.util.*;
25
26 public class ClustalFile extends AlignFile
27 {
28
29   public ClustalFile()
30   {
31   }
32
33   public ClustalFile(String inFile, String type) throws IOException
34   {
35     super(inFile, type);
36   }
37
38   public ClustalFile(FileParse source) throws IOException
39   {
40     super(source);
41   }
42
43   public void initData()
44   {
45     super.initData();
46   }
47
48   public void parse() throws IOException
49   {
50     int i = 0;
51     boolean flag = false;
52
53     Vector headers = new Vector();
54     Hashtable seqhash = new Hashtable();
55     StringBuffer tempseq;
56     String line, id;
57     StringTokenizer str;
58
59     try
60     {
61       while ((line = nextLine()) != null)
62       {
63         if (line.indexOf(" ") != 0)
64         {
65           str = new StringTokenizer(line, " ");
66
67           if (str.hasMoreTokens())
68           {
69             id = str.nextToken();
70
71             if (id.equalsIgnoreCase("CLUSTAL"))
72             {
73               flag = true;
74             }
75             else
76             {
77               if (flag)
78               {
79                 if (seqhash.containsKey(id))
80                 {
81                   tempseq = (StringBuffer) seqhash.get(id);
82                 }
83                 else
84                 {
85                   tempseq = new StringBuffer();
86                   seqhash.put(id, tempseq);
87                 }
88
89                 if (!(headers.contains(id)))
90                 {
91                   headers.addElement(id);
92                 }
93
94                 if (str.hasMoreTokens())
95                 {
96                   tempseq.append(str.nextToken());
97                 }
98               }
99             }
100           }
101           else
102           {
103             flag = true;
104           }
105         }
106       }
107     } catch (IOException e)
108     {
109       System.err.println("Exception parsing clustal file " + e);
110       e.printStackTrace();
111     }
112
113     if (flag)
114     {
115       this.noSeqs = headers.size();
116
117       // Add sequences to the hash
118       for (i = 0; i < headers.size(); i++)
119       {
120         if (seqhash.get(headers.elementAt(i)) != null)
121         {
122           if (maxLength < seqhash.get(headers.elementAt(i)).toString()
123                   .length())
124           {
125             maxLength = seqhash.get(headers.elementAt(i)).toString()
126                     .length();
127           }
128
129           Sequence newSeq = parseId(headers.elementAt(i).toString());
130           newSeq.setSequence(seqhash.get(headers.elementAt(i).toString())
131                   .toString());
132
133           seqs.addElement(newSeq);
134         }
135         else
136         {
137           System.err
138                   .println("Clustal File Reader: Can't find sequence for "
139                           + headers.elementAt(i));
140         }
141       }
142     }
143   }
144
145   public String print()
146   {
147     return print(getSeqsAsArray());
148   }
149
150   public String print(SequenceI[] s)
151   {
152     StringBuffer out = new StringBuffer("CLUSTAL"+newline+newline);
153
154     int max = 0;
155     int maxid = 0;
156
157     int i = 0;
158
159     while ((i < s.length) && (s[i] != null))
160     {
161       String tmp = printId(s[i]);
162
163       if (s[i].getSequence().length > max)
164       {
165         max = s[i].getSequence().length;
166       }
167
168       if (tmp.length() > maxid)
169       {
170         maxid = tmp.length();
171       }
172
173       i++;
174     }
175
176     if (maxid < 15)
177     {
178       maxid = 15;
179     }
180
181     maxid++;
182
183     int len = 60;
184     int nochunks = (max / len) + 1;
185
186     for (i = 0; i < nochunks; i++)
187     {
188       int j = 0;
189
190       while ((j < s.length) && (s[j] != null))
191       {
192         out.append(new Format("%-" + maxid + "s").form(printId(s[j]) + " "));
193
194         int start = i * len;
195         int end = start + len;
196
197         if ((end < s[j].getSequence().length)
198                 && (start < s[j].getSequence().length))
199         {
200           out.append(s[j].getSequenceAsString(start, end));
201         }
202         else
203         {
204           if (start < s[j].getSequence().length)
205           {
206             out.append(s[j].getSequenceAsString().substring(start));
207           }
208         }
209
210         out.append(newline);
211         j++;
212       }
213
214       out.append(newline);
215     }
216
217     return out.toString();
218   }
219 }