Looks for missing ids using BlastClient
[jalview.git] / src / jalview / analysis / SequenceFeatureFetcher.java
1 package jalview.analysis;\r
2 \r
3 import java.io.*;\r
4 import java.util.*;\r
5 import jalview.io.*;\r
6 import jalview.gui.*;\r
7 import jalview.datamodel.*;\r
8 \r
9 public class SequenceFeatureFetcher implements Runnable\r
10 {\r
11   AlignmentI align;\r
12   AlignmentPanel ap;\r
13   ArrayList unknownSequences;\r
14 \r
15   public SequenceFeatureFetcher(AlignmentI align, AlignmentPanel ap)\r
16   {\r
17     unknownSequences = new ArrayList();\r
18     this.align = align;\r
19     this.ap = ap;\r
20     Thread thread = new Thread(this);\r
21     thread.start();\r
22   }\r
23 \r
24   public void run()\r
25 {\r
26 \r
27   String cache = jalview.bin.Cache.getProperty("UNIPROT_CACHE");\r
28 \r
29   RandomAccessFile out = null;\r
30 \r
31   try{\r
32     if (cache == null)\r
33     {\r
34       jalview.bin.Cache.setProperty("UNIPROT_CACHE", System.getProperty("user.home")+"/uniprot.xml");\r
35       cache = jalview.bin.Cache.getProperty("UNIPROT_CACHE");\r
36     }\r
37 \r
38 \r
39 \r
40     File test = new File(cache);\r
41     if( !test.exists() )\r
42     {\r
43       out = new RandomAccessFile(cache, "rw");\r
44       out.writeBytes("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");\r
45       out.writeBytes("<UNIPROT_CACHE>\n");\r
46     }\r
47     else\r
48     {\r
49       out = new RandomAccessFile(cache, "rw");\r
50       // open exisiting cache and remove </UNIPROT_CACHE> from the end\r
51       long lastLine = 0;\r
52       String data;\r
53       while ( (data = out.readLine()) != null)\r
54       {\r
55         if (data.indexOf("</entry>") > -1)\r
56           lastLine = out.getFilePointer();\r
57 \r
58       }\r
59       out.seek(lastLine);\r
60     }\r
61 \r
62     int seqIndex = 0;\r
63     Vector sequences = align.getSequences();\r
64 \r
65     while (seqIndex < sequences.size())\r
66     {\r
67       ArrayList ids = new ArrayList();\r
68       for (int i = 0; seqIndex < sequences.size() && i < 50; seqIndex++, i++)\r
69       {\r
70         SequenceI sequence = (SequenceI) sequences.get(seqIndex);\r
71         ids.add(sequence.getName());\r
72       }\r
73 \r
74       tryLocalCacheFirst(ids, align);\r
75 \r
76       if (ids.size() > 0)\r
77       {\r
78         StringBuffer remainingIds = new StringBuffer("uniprot:");\r
79         for (int i = 0; i < ids.size(); i++)\r
80           remainingIds.append(ids.get(i) + ";");\r
81 \r
82          EBIFetchClient ebi = new EBIFetchClient();\r
83          System.out.println(remainingIds.toString());\r
84          String[] result = ebi.fetchData(remainingIds.toString(), "xml", null);\r
85 \r
86         if(result!=null)\r
87           ReadUniprotFile(result, out, align);\r
88       }\r
89 \r
90     }\r
91 \r
92     if (out != null)\r
93     {\r
94       out.writeBytes("</UNIPROT_CACHE>\n");\r
95       out.close();\r
96     }\r
97   }catch(Exception ex){ex.printStackTrace();}\r
98 \r
99   ap.RefreshPanels();\r
100   findMissingIds(align);\r
101 \r
102   if(unknownSequences.size()>0)\r
103   {\r
104     WSWUBlastClient blastClient = new WSWUBlastClient(align, unknownSequences);\r
105   }\r
106 \r
107 }\r
108 \r
109 void ReadUniprotFile(String [] result, RandomAccessFile out, AlignmentI align)\r
110 {\r
111   SequenceI sequence = null;\r
112   Vector features = null;\r
113   String type, description, status, start, end, pdb = null;\r
114 \r
115 \r
116   for (int r = 0; r < result.length; r++)\r
117   {\r
118     if(sequence==null && result[r].indexOf("<name>")>-1)\r
119     {\r
120       long filePointer = 0;\r
121 \r
122       if(out!=null)\r
123       try{\r
124         filePointer=out.getFilePointer();\r
125         out.writeBytes("<entry>\n");\r
126       }catch(Exception ex){}\r
127 \r
128       String seqName = parseElement( result[r], "<name>" , out);\r
129       sequence = align.findName( seqName ) ;\r
130       if(sequence==null)\r
131       {\r
132         sequence = align.findName( seqName.substring(0, seqName.indexOf('_')));\r
133         if(sequence!=null)\r
134         {\r
135           System.out.println("changing "+sequence.getName()+" to "+seqName);\r
136           sequence.setName(seqName);\r
137         }\r
138       }\r
139       if(sequence==null)\r
140       {\r
141         System.out.println("UNIPROT updated suggestion is "+result[r]);\r
142         sequence = align.findName( result[r] ) ;\r
143 \r
144         // this entry has been suggested by ebi.\r
145         // doesn't match id in alignment file\r
146         try   { out.setLength(filePointer);  }  catch (Exception ex) {}\r
147         // now skip to next entry\r
148         while( result[r].indexOf("</entry>")==-1)\r
149           r++;\r
150       }\r
151 \r
152       features = new Vector();\r
153       type=""; start="0"; end="0"; description=""; status=""; pdb="";\r
154 \r
155     }\r
156 \r
157     if(sequence==null)\r
158       continue;\r
159 \r
160      if( result[r].indexOf("<property type=\"pdb accession\"")>-1)\r
161      {\r
162        pdb = parseValue( result[r], "value=" , out);\r
163        sequence.setPDBId(pdb);\r
164      }\r
165 \r
166      if(result[r].indexOf("feature type")>-1)\r
167      {\r
168        type = parseValue( result[r], "type=" , out);\r
169        description = parseValue( result[r], "description=" , null );\r
170        status = parseValue ( result[r], "status=", null);\r
171 \r
172        while( result[r].indexOf("position")==-1)\r
173        {\r
174            r++;  //<location>\r
175        }\r
176       // r++;\r
177        if(result[r].indexOf("begin")>-1)\r
178        {\r
179          start = parseValue( result[r], "position=" , out);\r
180          end = parseValue( result[++r], "position=" , out);\r
181        }\r
182        else\r
183        {\r
184          start = parseValue( result[r], "position=" , out);\r
185          end = parseValue(   result[r], "position=" , null);\r
186        }\r
187        int sstart = Integer.parseInt(start);\r
188        int eend = Integer.parseInt(end);\r
189        if(out!=null)\r
190          try{ out.writeBytes("</feature>\n"); }catch(Exception ex){}\r
191 \r
192 \r
193        if(sstart>=sequence.getStart() && eend<=sequence.getEnd())\r
194        {\r
195          SequenceFeature sf = new SequenceFeature(type,\r
196              sstart,\r
197              eend,\r
198              description,\r
199              status);\r
200          features.add(sf);\r
201        }\r
202      }\r
203 \r
204      if(result[r].indexOf("<sequence")>-1)\r
205      {\r
206        StringBuffer seqString = new StringBuffer();\r
207 \r
208        if(out!=null)\r
209          try  {  out.writeBytes(result[r]+"\n"); }   catch (Exception ex){}\r
210 \r
211        while(result[++r].indexOf("</sequence>")==-1)\r
212        {\r
213          seqString.append(result[r]);\r
214          if(out!=null)\r
215          try  {  out.writeBytes(result[r]+"\n"); }   catch (Exception ex){}\r
216        }\r
217 \r
218        if(out!=null)\r
219          try  {  out.writeBytes(result[r]+"\n"); }   catch (Exception ex){}\r
220 \r
221        StringBuffer nonGapped = new StringBuffer();\r
222        for (int i = 0; i < sequence.getSequence().length(); i++)\r
223        {\r
224          if (!jalview.util.Comparison.isGap(sequence.getCharAt(i)))\r
225            nonGapped.append(sequence.getCharAt(i));\r
226        }\r
227 \r
228        int absStart = seqString.toString().indexOf(nonGapped.toString());\r
229        if(absStart==-1)\r
230        {\r
231          unknownSequences.add(sequence.getName());\r
232          features = null;\r
233          System.out.println(sequence.getName()+ "does not match ");\r
234          continue;\r
235        }\r
236 \r
237        int absEnd =   absStart + nonGapped.toString().length();\r
238        absStart+=1;\r
239 \r
240        if(absStart!=sequence.getStart() || absEnd!=sequence.getEnd())\r
241          System.out.println("Updated: "+sequence.getName()+" "+\r
242                            sequence.getStart()+"/"+sequence.getEnd()+"  to  "+ absStart+"/"+absEnd);\r
243 \r
244 \r
245        sequence.setStart(absStart);\r
246        sequence.setEnd(absEnd);\r
247 \r
248      }\r
249 \r
250      if(result[r].indexOf("</entry>")>-1)\r
251      {\r
252        if(features!=null)\r
253          sequence.setSequenceFeatures( features );\r
254        features = null;\r
255        sequence = null;\r
256        if(out!=null)\r
257          try{  out.writeBytes("</entry>\n"); }catch(Exception ex){}\r
258 \r
259      }\r
260   }\r
261 }\r
262 \r
263 void findMissingIds(AlignmentI align)\r
264 {\r
265   String data;\r
266   ArrayList cachedIds = new ArrayList();\r
267 \r
268   try\r
269   {\r
270     BufferedReader in = new BufferedReader(\r
271         new FileReader(jalview.bin.Cache.getProperty("UNIPROT_CACHE")));\r
272 \r
273     while ( (data = in.readLine()) != null)\r
274     {\r
275       if (data.indexOf("name") > -1)\r
276       {\r
277         String name = parseElement(data, "<name>", null);\r
278         cachedIds.add(name);\r
279       }\r
280     }\r
281   }\r
282   catch (Exception ex)\r
283   {   ex.printStackTrace();  }\r
284 \r
285   for(int i=0; i<align.getHeight(); i++)\r
286     if( !cachedIds.contains( align.getSequenceAt(i).getName() ) )\r
287       unknownSequences.add( align.getSequenceAt(i).getName() );\r
288 \r
289 \r
290 }\r
291 \r
292 void tryLocalCacheFirst(ArrayList ids, AlignmentI align)\r
293 {\r
294   ArrayList cacheData = new ArrayList();\r
295   try{\r
296     BufferedReader in = new BufferedReader(\r
297           new FileReader(jalview.bin.Cache.getProperty("UNIPROT_CACHE")));\r
298 \r
299     // read through cache file, if the cache has sequences we're looking for\r
300     // add the lines to a new String array, Readthis new array and\r
301     // make sure we remove the ids from the list to retrieve from EBI\r
302     String data;\r
303     while( ( data=in.readLine())!=null)\r
304     {\r
305       if(data.indexOf("name")>-1)\r
306       {\r
307         String name = parseElement( data, "<name>" , null) ;\r
308         if(ids.contains( name ) )\r
309         {\r
310           cacheData.add("<entry>");\r
311           cacheData.add(data);\r
312           while( data.indexOf("</entry>")==-1)\r
313           {\r
314             data = in.readLine();\r
315             cacheData.add(data);\r
316           }\r
317           cacheData.add(data);\r
318 \r
319           ids.remove( name );\r
320         }\r
321       }\r
322     }\r
323   }\r
324   catch(Exception ex){ex.printStackTrace();}\r
325 \r
326   String [] localData = new String[cacheData.size()];\r
327   cacheData.toArray( localData );\r
328   if(localData!=null && localData.length>0)\r
329     ReadUniprotFile(localData, null, align);\r
330 }\r
331 \r
332 \r
333 String parseValue(String line, String tag, RandomAccessFile out)\r
334 {\r
335   if(out!=null)\r
336     try{  out.writeBytes(line+"\n"); }catch(Exception ex){}\r
337 \r
338 \r
339   int index = line.indexOf(tag)+tag.length()+1;\r
340   if(index==tag.length())\r
341     return "";\r
342 \r
343   return line.substring( index, line.indexOf("\"", index+1) );\r
344 }\r
345 \r
346 \r
347 String parseElement(String line, String tag, RandomAccessFile out)\r
348 {\r
349   if (out != null)\r
350     try\r
351     {\r
352       out.writeBytes(line + "\n");\r
353     }\r
354     catch (Exception ex)\r
355     {}\r
356 \r
357   int index = line.indexOf(tag) + tag.length();\r
358   return line.substring(index, line.indexOf("</"));\r
359 }\r
360 \r
361 \r
362 }\r