Append start and end
[jalview.git] / src / jalview / io / DasSequenceFeatureFetcher.java
1 /*\r
2 * Jalview - A Sequence Alignment Editor and Viewer\r
3 * Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
4 *\r
5 * This program is free software; you can redistribute it and/or\r
6 * modify it under the terms of the GNU General Public License\r
7 * as published by the Free Software Foundation; either version 2\r
8 * of the License, or (at your option) any later version.\r
9 *\r
10 * This program is distributed in the hope that it will be useful,\r
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
13 * GNU General Public License for more details.\r
14 *\r
15 * You should have received a copy of the GNU General Public License\r
16 * along with this program; if not, write to the Free Software\r
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
18 */\r
19 package jalview.io;\r
20 \r
21 import jalview.datamodel.*;\r
22 \r
23 import jalview.gui.*;\r
24 \r
25 import java.util.*;\r
26 \r
27 import java.net.URL;\r
28 \r
29 import org.biojava.dasobert.das.FeatureThread;\r
30 import org.biojava.dasobert.dasregistry.Das1Source;\r
31 import org.biojava.dasobert.eventmodel.FeatureEvent;\r
32 import org.biojava.dasobert.eventmodel.FeatureListener;\r
33 import org.biojava.dasobert.dasregistry.DasSource;\r
34 \r
35 import org.biojava.dasobert.das2.io.DasSourceReaderImpl;\r
36 import org.biojava.dasobert.dasregistry.Das1Source;\r
37 import org.biojava.dasobert.dasregistry.DasSource;\r
38 import org.biojava.dasobert.das2.Das2Source;\r
39 import org.biojava.dasobert.das2.DasSourceConverter;\r
40 \r
41 \r
42 import jalview.bin.Cache;\r
43 \r
44 \r
45 /**\r
46  * DOCUMENT ME!\r
47  *\r
48  * @author $author$\r
49  * @version $Revision$\r
50  */\r
51 public class DasSequenceFeatureFetcher implements Runnable\r
52 {\r
53   final AlignmentI dataset;\r
54   final AlignFrame af;\r
55   StringBuffer sbuffer = new StringBuffer();\r
56 \r
57 \r
58 \r
59   /**\r
60    * Creates a new SequenceFeatureFetcher object.\r
61    *\r
62    * @param align DOCUMENT ME!\r
63    * @param ap DOCUMENT ME!\r
64    */\r
65   public DasSequenceFeatureFetcher(AlignmentI align,\r
66                                    AlignFrame af)\r
67   {\r
68     this.dataset = align.getDataset();\r
69     this.af = af;\r
70 \r
71     Thread thread = new Thread(this);\r
72     thread.start();\r
73   }\r
74   /**\r
75    * creates a jalview sequence feature from a das feature document\r
76    * @param dasfeature\r
77    * @return sequence feature object created using dasfeature information\r
78    */\r
79   SequenceFeature newSequenceFeature(Map dasfeature, String nickname)\r
80   {\r
81           try {\r
82                 /**\r
83            * Different qNames for a DAS Feature - are string keys to the HashMaps in features\r
84            * "METHOD") ||\r
85            qName.equals("TYPE") ||\r
86            qName.equals("START") ||\r
87            qName.equals("END") ||\r
88            qName.equals("NOTE") ||\r
89            qName.equals("LINK") ||\r
90            qName.equals("SCORE")\r
91            */\r
92                   String desc = new String();\r
93                   if (dasfeature.containsKey("NOTE"))\r
94                                 desc+=(String) dasfeature.get("NOTE");\r
95 \r
96 \r
97                   int start = 0, end = 0;\r
98                   float score = 0f;\r
99 \r
100                   try{ start = Integer.parseInt( dasfeature.get("START").toString()); }\r
101                   catch( Exception ex){}\r
102                   try{ end = Integer.parseInt( dasfeature.get("END").toString()); }\r
103                   catch (Exception ex){}\r
104                   try{ score = Integer.parseInt( dasfeature.get("SCORE").toString()); }\r
105                   catch (Exception ex){}\r
106 \r
107 \r
108                   SequenceFeature f = new SequenceFeature(\r
109                                   (String) dasfeature.get("TYPE"),\r
110                                   desc,\r
111                                   start,\r
112                                   end,\r
113                                   score,\r
114                                   nickname);\r
115 \r
116                   if (dasfeature.containsKey("LINK"))\r
117                  {\r
118                       f.addLink(f.getType()+" "+f.begin+"_"+f.end\r
119                                 +"|"+ dasfeature.get("LINK"));\r
120                   }\r
121                   // (String) dasfeature.get("ID"),\r
122                   ////  (String) dasfeature.get("METHOD"),\r
123                                 //  (String) dasfeature.get("SCORE"),\r
124                                 //  null\r
125                         // );\r
126 \r
127                      // System.out.println(nickname+" "+f.getType()+" "+f.begin+" "+f.end);\r
128           return f;\r
129           }\r
130           catch (Exception e) {\r
131             e.printStackTrace();\r
132                   Cache.log.debug("Failed to parse "+dasfeature.toString(), e);\r
133                   return null;\r
134           }\r
135   }\r
136   /**\r
137    * fetch and add das features to a sequence using the given source URL and Id to create a feature request\r
138    * @param seq\r
139    * @param SourceUrl\r
140    * @param id\r
141    */\r
142   protected void createFeatureFetcher(final Sequence seq,\r
143                                       final String sourceUrl,\r
144                                       String id,\r
145                                       String nickname)  {\r
146           //////////////\r
147           /// fetch DAS features\r
148           final Das1Source source = new Das1Source();\r
149           source.setUrl(sourceUrl);\r
150           source.setNickname(nickname);\r
151 \r
152 \r
153           Cache.log.debug("new Das Feature Fetcher for " + id + " querying " +\r
154                           sourceUrl);\r
155           if (id != null && id.length() > 0)\r
156           {\r
157             FeatureThread fetcher = new FeatureThread(id\r
158                +  ":" + seq.getStart() + "," +seq.getEnd()\r
159                  , source);\r
160 \r
161             fetcher.addFeatureListener(new FeatureListener()\r
162             {\r
163               public void comeBackLater(FeatureEvent e)\r
164               {\r
165                 Cache.log.debug("das source " + e.getDasSource().getNickname() +\r
166                                 " asked us to come back in " + e.getComeBackLater() +\r
167                                 " secs.");\r
168               }\r
169 \r
170               public void newFeatures(FeatureEvent e)\r
171               {\r
172                 Das1Source ds = e.getDasSource();\r
173 \r
174                 Map[] features = e.getFeatures();\r
175                 // add features to sequence\r
176                 Cache.log.debug("das source " + ds.getUrl() + " returned " +\r
177                                 features.length + " features");\r
178 \r
179                 if (features.length > 0)\r
180                 {\r
181                   for (int i = 0; i < features.length; i++)\r
182                   {\r
183                       SequenceFeature f = newSequenceFeature(features[i],\r
184                         source.getNickname());\r
185 \r
186                       seq.addSequenceFeature(f);\r
187                   }\r
188                 }\r
189                 else\r
190                 {\r
191                   System.out.println("No features found for sequence " +seq.getName()\r
192                                      +" from: "+ e.getDasSource().getNickname());\r
193                 }\r
194 \r
195               }\r
196             }\r
197 \r
198             );\r
199 \r
200             //NOTE alignPanel listener will be called after the previous\r
201             //anonymous listener!!!\r
202             fetcher.addFeatureListener(af);\r
203 \r
204             fetcher.start();\r
205           }\r
206   }\r
207   /**\r
208    * Spawns a number of dasobert Fetcher threads to add features to sequences in the dataset\r
209    */\r
210   public void run()\r
211   {\r
212     long startTime = System.currentTimeMillis();\r
213     af.setProgressBar("Fetching DAS Sequence Features", startTime);\r
214 \r
215     DasSource [] sources = new jalview.gui.DasSourceBrowser().getDASSource();\r
216 \r
217     String active = jalview.bin.Cache.getDefault("DAS_ACTIVE_SOURCE", "uniprot");\r
218     StringTokenizer st = new StringTokenizer(active, "\t");\r
219     Vector selectedSources = new Vector();\r
220     String token;\r
221     while (st.hasMoreTokens())\r
222     {\r
223       token = st.nextToken();\r
224       for(int i=0; i<sources.length; i++)\r
225       {\r
226         if(sources[i].getNickname().equals(token))\r
227         {\r
228           selectedSources.addElement(sources[i]);\r
229           break;\r
230         }\r
231       }\r
232     }\r
233 \r
234 \r
235     if(selectedSources == null || selectedSources.size()==0)\r
236     {\r
237       System.out.println("No DAS Sources active");\r
238       af.setProgressBar("No DAS Sources Active", startTime);\r
239       return;\r
240     }\r
241 \r
242     try\r
243     {\r
244       int seqIndex = 0;\r
245       Vector sequences = dataset.getSequences();\r
246       while (seqIndex < sequences.size())\r
247       {\r
248           Sequence sequence = (Sequence) sequences.get(seqIndex);\r
249           Vector uprefs = jalview.util.DBRefUtils.selectRefs(sequence.getDBRef(),\r
250               new String[]  {\r
251               jalview.datamodel.DBRefSource.PDB,\r
252               jalview.datamodel.DBRefSource.UNIPROT});\r
253 \r
254           for(int sourceIndex=0; sourceIndex<selectedSources.size(); sourceIndex++)\r
255           {\r
256             DasSource dasSource = (DasSource)selectedSources.elementAt(sourceIndex);\r
257 \r
258             if (uprefs != null)\r
259             {\r
260               // we know the id for this entry, so don't note its ID in the unknownSequences list\r
261               for (int j = 0;  j < uprefs.size(); j++)\r
262               {\r
263 \r
264                 // Will have to pass any mapping information to the fetcher - the start/end for the DBRefEntry may not be the same as the sequence's start/end\r
265                 org.biojava.dasobert.dasregistry.DasCoordinateSystem cs[] = dasSource.getCoordinateSystem();\r
266                 for (int l=0; l<cs.length; l++)\r
267                 {\r
268                   if (jalview.util.DBRefUtils.isDasCoordinateSystem(cs[l].getName(), (DBRefEntry)\r
269                       uprefs.get(j)))\r
270                   {\r
271                     Cache.log.debug("Launched fetcher for coordinate system " +\r
272                                     cs[l].getName());\r
273 \r
274 \r
275                     createFeatureFetcher(sequence,\r
276                                          dasSource.getUrl(),\r
277                                          ( (DBRefEntry) uprefs.get(j)).\r
278                                          getAccessionId(),\r
279                                          dasSource.getNickname());\r
280                   }\r
281                 }\r
282               }\r
283             }\r
284             else\r
285             {\r
286               String id = null;\r
287               // try and use the name as the sequence id\r
288               if (sequence.getName().indexOf("|") > -1)\r
289               {\r
290                 id = sequence.getName().substring(\r
291                     sequence.getName().lastIndexOf("|") + 1);\r
292               }\r
293               else\r
294               {\r
295                 id = sequence.getName();\r
296               }\r
297               if (id != null)\r
298               {\r
299                 // Should try to call a general feature fetcher that queries many sources with name to discover applicable ID references\r
300                 createFeatureFetcher(sequence,\r
301                                      dasSource.getUrl(),\r
302                                      id,\r
303                                      dasSource.getNickname());\r
304               }\r
305             }\r
306           }\r
307 \r
308           seqIndex++;\r
309     }\r
310     }\r
311     catch (Exception ex)\r
312     {\r
313       ex.printStackTrace();\r
314     }\r
315 \r
316     af.setProgressBar("DAS Feature Fetching Complete", startTime);\r
317   }\r
318 \r
319 \r
320   public static DasSource[] getDASSources()\r
321   {\r
322     DasSourceReaderImpl reader = new DasSourceReaderImpl();\r
323 \r
324     String registryURL =jalview.bin.Cache.getDefault("DAS_REGISTRY_URL",\r
325         "http://www.spice-3d.org/dasregistry/das1/sources"\r
326       );\r
327 \r
328     try\r
329     {\r
330       URL url = new URL(registryURL);\r
331 \r
332       DasSource[] sources = reader.readDasSource(url);\r
333 \r
334       List das1sources = new ArrayList();\r
335       for (int i = 0; i < sources.length; i++)\r
336       {\r
337         DasSource ds = sources[i];\r
338         if (ds instanceof Das2Source)\r
339         {\r
340           Das2Source d2s = (Das2Source) ds;\r
341           if (d2s.hasDas1Capabilities())\r
342           {\r
343             Das1Source d1s = DasSourceConverter.toDas1Source(d2s);\r
344             das1sources.add(d1s);\r
345           }\r
346 \r
347         }\r
348         else if (ds instanceof Das1Source)\r
349         {\r
350           das1sources.add( (Das1Source) ds);\r
351         }\r
352       }\r
353 \r
354       return (Das1Source[]) das1sources.toArray(new Das1Source[das1sources.size()]);\r
355     }\r
356     catch (Exception ex)\r
357     {\r
358       ex.printStackTrace();\r
359       return null;\r
360     }\r
361 \r
362   }\r
363 }\r
364 \r
365 \r