Any character non aa or nucleotide is a space
[jalview.git] / src / jalview / io / JPredFile.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
20 /**
21  * PredFile.java
22  * JalviewX / Vamsas Project
23  * JPred.seq.concise reader
24  */
25 package jalview.io;
26
27 import java.io.*;
28 import java.util.*;
29
30 import jalview.datamodel.*;
31
32
33 /**
34  * DOCUMENT ME!
35  *
36  * @author $author$
37  * @version $Revision$
38  */
39 public class JPredFile extends AlignFile
40 {
41     Vector ids;
42     Vector conf;
43     Hashtable Scores; // Hash of names and score vectors
44     Hashtable Symscores; // indexes of symbol annotation properties in sequenceI vector
45     private int QuerySeqPosition;
46
47
48     /**
49      * Creates a new JPredFile object.
50      *
51      * @param inFile DOCUMENT ME!
52      * @param type DOCUMENT ME!
53      *
54      * @throws IOException DOCUMENT ME!
55      */
56     public JPredFile(String inFile, String type) throws IOException
57     {
58         super(inFile, type);
59     }
60
61     /**
62      * DOCUMENT ME!
63      *
64      * @param QuerySeqPosition DOCUMENT ME!
65      */
66     public void setQuerySeqPosition(int QuerySeqPosition)
67     {
68         this.QuerySeqPosition = QuerySeqPosition;
69     }
70
71     /**
72      * DOCUMENT ME!
73      *
74      * @return DOCUMENT ME!
75      */
76     public int getQuerySeqPosition()
77     {
78         return QuerySeqPosition;
79     }
80
81     /**
82      * DOCUMENT ME!
83      *
84      * @return DOCUMENT ME!
85      */
86     public Hashtable getScores()
87     {
88         return Scores;
89     }
90
91     /**
92      * DOCUMENT ME!
93      *
94      * @return DOCUMENT ME!
95      */
96     public Hashtable getSymscores()
97     {
98         return Symscores;
99     }
100
101     /**
102      * DOCUMENT ME!
103      */
104     public void initData()
105     {
106         super.initData();
107         Scores = new Hashtable();
108         ids = null;
109         conf = null;
110     }
111
112     /**
113  * parse a JPred concise file into a sequence-alignment like object.
114  */
115     public void parse() throws IOException
116     {
117         // JBPNote log.System.out.println("all read in ");
118         String line;
119         QuerySeqPosition = -1;
120         noSeqs = 0;
121
122         Vector seq_entries = new Vector();
123         Vector ids = new Vector();
124         Hashtable Symscores = new Hashtable();
125
126         while ((line = nextLine()) != null)
127         {
128             // Concise format allows no comments or non comma-formatted data
129             StringTokenizer str = new StringTokenizer(line, ":");
130             String id = "";
131
132             if (!str.hasMoreTokens())
133             {
134                 continue;
135             }
136
137             id = str.nextToken();
138
139             String seqsym = str.nextToken();
140             StringTokenizer symbols = new StringTokenizer(seqsym, ",");
141
142             // decide if we have more than just alphanumeric symbols
143             int numSymbols = symbols.countTokens();
144
145             if (numSymbols == 0)
146             {
147                 continue;
148             }
149
150             if (seqsym.length() != (2 * numSymbols))
151             {
152                 // Set of scalars for some property
153                 if (Scores.containsKey(id))
154                 {
155                     int i = 1;
156
157                     while (Scores.containsKey(id + "_" + i))
158                     {
159                         i++;
160                     }
161
162                     id = id + "_" + i;
163                 }
164
165                 Vector scores = new Vector();
166
167                 // Typecheck from first entry
168                 int i = 0;
169                 String ascore = "dead";
170
171                 try
172                 {
173                     // store elements as floats...
174                     while (symbols.hasMoreTokens())
175                     {
176                         ascore = symbols.nextToken();
177
178                         Float score = new Float(ascore);
179                         scores.addElement((Object) score);
180                     }
181
182                     Scores.put(id, scores);
183                 }
184                 catch (Exception e)
185                 {
186                     // or just keep them as strings
187                     i = scores.size();
188
189                     for (int j = 0; j < i; j++)
190                     {
191                         scores.setElementAt(
192                             (Object) ((Float) scores.elementAt(j)).toString(), j);
193                     }
194
195                     scores.addElement((Object) ascore);
196
197                     while (symbols.hasMoreTokens())
198                     {
199                         ascore = symbols.nextToken();
200                         scores.addElement((Object) ascore);
201                     }
202
203                     Scores.put(id, scores);
204                 }
205             }
206             else if (id.equals("jnetconf"))
207             {
208                 // log.debug System.out.println("here");
209                 id = "Prediction Confidence";
210                 this.conf = new Vector(numSymbols);
211
212                 for (int i = 0; i < numSymbols; i++)
213                 {
214                     conf.setElementAt( symbols.nextToken(), i);
215                 }
216             }
217             else
218             {
219                 // Sequence or a prediction string (rendered as sequence)
220                 StringBuffer newseq = new StringBuffer();
221
222                 for (int i = 0; i < numSymbols; i++)
223                 {
224                     newseq.append(symbols.nextToken());
225                 }
226
227                 if (id.indexOf(";") > -1)
228                 {
229                     seq_entries.addElement(newseq);
230
231                     int i = 1;
232                     String name = id.substring(id.indexOf(";") + 1);
233
234                     while (ids.lastIndexOf(name) > -1)
235                     {
236                         name = id.substring(id.indexOf(";") + 1) + "_" + ++i;
237                     }
238
239                     ids.addElement(name);
240
241                     noSeqs++;
242                 }
243                 else
244                 {
245                     if (id.equals("JNETPRED"))
246                     {
247                         id = "Predicted Secondary Structure";
248                     }
249
250                     seq_entries.addElement(newseq.toString());
251                     ids.addElement(id);
252                     Symscores.put((Object) id,
253                         (Object) new Integer(ids.size() - 1));
254                 }
255             }
256         }
257         /* leave it to the parser user to actually check this.
258         if (noSeqs < 1)
259         {
260             throw new IOException(
261                 "JpredFile Parser: No sequence in the prediction!");
262         }*/
263
264         maxLength = seq_entries.elementAt(0).toString().length();
265
266         for (int i = 0; i < ids.size(); i++)
267         {
268             // Add all sequence like objects
269             Sequence newSeq = new Sequence(ids.elementAt(i).toString(),
270                     seq_entries.elementAt(i).toString(), 1,
271                     seq_entries.elementAt(i).toString().length());
272
273
274             if (maxLength != seq_entries.elementAt(i).toString().length())
275             {
276                 throw new IOException("JPredConcise: Entry (" +
277                     ids.elementAt(i).toString() +
278                     ") has an unexpected number of columns");
279             }
280
281             if (newSeq.getName().startsWith("QUERY") &&
282                     (QuerySeqPosition == -1))
283             {
284                 QuerySeqPosition = seqs.size();
285             }
286
287             seqs.addElement(newSeq);
288         }
289     }
290
291     /**
292  * print
293  *
294  * @return String
295    */
296     public String print()
297     {
298         return "Not Supported";
299     }
300
301     /**
302      * DOCUMENT ME!
303      *
304      * @param args DOCUMENT ME!
305      */
306     public static void main(String[] args)
307     {
308         try
309         {
310             JPredFile blc = new JPredFile(args[0], "File");
311
312             for (int i = 0; i < blc.seqs.size(); i++)
313             {
314                 System.out.println(((Sequence) blc.seqs.elementAt(i)).getName() +
315                     "\n" + ((Sequence) blc.seqs.elementAt(i)).getSequenceAsString() +
316                     "\n");
317             }
318         }
319         catch (java.io.IOException e)
320         {
321             System.err.println("Exception " + e);
322             e.printStackTrace();
323         }
324     }
325     Vector annotSeqs=null;
326   /**
327    * removeNonSequences
328    */
329   public void removeNonSequences()
330   {
331     if (annotSeqs!=null)
332       return;
333     annotSeqs = new Vector();
334     Vector newseqs = new Vector();
335     int i=0;
336     int j=seqs.size();
337     for (; i<QuerySeqPosition; i++)
338         annotSeqs.addElement(seqs.elementAt(i));
339       // check that no stray annotations have been added at the end.
340       {
341         SequenceI sq = (SequenceI) seqs.elementAt(j-1);
342         if (sq.getName().toUpperCase().startsWith("JPRED")) {
343           annotSeqs.addElement(sq);
344           seqs.removeElementAt(--j);
345         }
346       }
347     for (; i<j; i++)
348         newseqs.addElement(seqs.elementAt(i));
349
350     seqs.removeAllElements();
351     seqs = newseqs;
352   }
353 }
354
355
356 /*
357  StringBuffer out = new StringBuffer();
358
359  out.append("START PRED\n");
360  for (int i = 0; i < s[0].sequence.length(); i++)
361  {
362   out.append(s[0].sequence.substring(i, i + 1) + " ");
363   out.append(s[1].sequence.substring(i, i + 1) + " ");
364   out.append(s[1].score[0].elementAt(i) + " ");
365   out.append(s[1].score[1].elementAt(i) + " ");
366   out.append(s[1].score[2].elementAt(i) + " ");
367   out.append(s[1].score[3].elementAt(i) + " ");
368
369   out.append("\n");
370  }
371  out.append("END PRED\n");
372  return out.toString();
373  }
374
375     public static void main(String[] args)
376  {
377   try
378   {
379     BLCFile blc = new BLCFile(args[0], "File");
380     DrawableSequence[] s = new DrawableSequence[blc.seqs.size()];
381     for (int i = 0; i < blc.seqs.size(); i++)
382     {
383       s[i] = new DrawableSequence( (Sequence) blc.seqs.elementAt(i));
384     }
385     String out = BLCFile.print(s);
386
387     AlignFrame af = new AlignFrame(null, s);
388     af.resize(700, 500);
389     af.show();
390     System.out.println(out);
391   }
392   catch (java.io.IOException e)
393   {
394     System.out.println("Exception " + e);
395   }
396  }
397
398  }
399  */