more subtle rearrangements
[jalview.git] / src / jalview / ws / JPredClient.java
1 package jalview.ws;\r
2 \r
3 import org.apache.axis.client.*;\r
4 import javax.xml.namespace.QName;\r
5 import java.util.*;\r
6 import jalview.datamodel.*;\r
7 import jalview.gui.*;\r
8 import javax.swing.*;\r
9 import java.util.*;\r
10 import java.awt.*;\r
11 import jalview.analysis.AlignSeq;\r
12 import ext.vamsas.*;\r
13 \r
14 public class JPredClient\r
15     extends WSClient\r
16 {\r
17   ext.vamsas.JPredWS server;\r
18   String altitle = "";\r
19   java.util.Hashtable SequenceInfo = null;\r
20   private WebserviceInfo setWebService()\r
21   {\r
22     WebServiceName = "JNetWS";\r
23     WebServiceJobTitle = "JNet secondary structure prediction";\r
24     WebServiceReference =\r
25         "\"Cuff J. A and Barton G.J (1999) Application of enhanced "\r
26         + "multiple sequence alignment profiles to improve protein secondary structure prediction, "\r
27         + "Proteins 40:502-511\".";\r
28     WsURL = "http://www.compbio.dundee.ac.uk/JalviewWS/services/jpred";\r
29     WebserviceInfo wsInfo = new WebserviceInfo(WebServiceJobTitle,\r
30                                                WebServiceReference);\r
31 \r
32     return wsInfo;\r
33   }\r
34 \r
35     private boolean locateWebService()\r
36     {\r
37 \r
38       JPredWSServiceLocator loc = new JPredWSServiceLocator(); // Default\r
39       try\r
40       {\r
41         this.server = loc.getjpred(new java.net.URL(WsURL)); // JBPNote will be set from properties\r
42         ( (JpredSoapBindingStub)this.server).setTimeout(60000); // one minute stub\r
43       }\r
44       catch (Exception ex)\r
45       {\r
46         JOptionPane.showMessageDialog(Desktop.desktop,\r
47             "The Secondary Structure Prediction Service named "\r
48                                       + WebServiceName + " at " + WsURL +\r
49                                       " couldn't be located.",\r
50                                       "Internal Jalview Error",\r
51                                       JOptionPane.WARNING_MESSAGE);\r
52         wsInfo.setProgressText("Serious! " + WebServiceName +\r
53                                " Service location failed\nfor URL :"\r
54                                + WsURL + "\n" + ex.getMessage());\r
55         wsInfo.setStatus(wsInfo.STATE_STOPPED_SERVERERROR);\r
56         return false;\r
57       }\r
58       return true;\r
59     }\r
60 \r
61     public JPredClient(String title, SequenceI[] msf)\r
62     {\r
63       wsInfo = setWebService();\r
64       SequenceI seq = msf[0];\r
65       altitle = "JNet prediction on " + seq.getName() +\r
66           " using alignment from " + title;\r
67 \r
68       wsInfo.setProgressText("Job details for MSA based prediction (" + title +\r
69                              ") on sequence :\n>"\r
70                              + seq.getName() + "\n"\r
71                              + AlignSeq.extractGaps("-. ", seq.getSequence()) +\r
72                              "\n");\r
73 \r
74       SequenceInfo = jalview.analysis.SeqsetUtils.SeqCharacterHash(seq);\r
75       if (!locateWebService())\r
76         return;\r
77 \r
78       JPredThread jthread = new JPredThread(msf);\r
79       jthread.start();\r
80     }\r
81 \r
82     public JPredClient(String title, SequenceI seq)\r
83     {\r
84       wsInfo = setWebService();\r
85       wsInfo.setProgressText("Job details for prediction on sequence :\n>"\r
86                              + seq.getName() + "\n" +\r
87                              AlignSeq.extractGaps("-. ", seq.getSequence()) +\r
88                              "\n");\r
89       altitle = "JNet prediction for sequence " + seq.getName() + " from " +\r
90           title;\r
91 \r
92       SequenceInfo = jalview.analysis.SeqsetUtils.SeqCharacterHash(seq);\r
93 \r
94       if (!locateWebService())\r
95               return;\r
96 \r
97       JPredThread jthread = new JPredThread(seq);\r
98       jthread.start();\r
99     }\r
100 \r
101     class JPredThread\r
102         extends Thread\r
103     {\r
104       String OutputHeader;\r
105       ext.vamsas.JpredResult result;\r
106       ext.vamsas.Sequence sequence;\r
107       ext.vamsas.Msfalignment msa;\r
108       String jobId;\r
109       boolean jobComplete = false;\r
110       int allowedServerExceptions = 3; // thread dies if too many exceptions.\r
111       JPredThread(SequenceI seq)\r
112       {\r
113         OutputHeader = wsInfo.getProgressText();\r
114         this.sequence = new ext.vamsas.Sequence();\r
115         this.sequence.setId(seq.getName());\r
116         this.sequence.setSeq(AlignSeq.extractGaps("-. ", seq.getSequence()));\r
117       }\r
118 \r
119       JPredThread(SequenceI[] msf)\r
120       {\r
121         OutputHeader = wsInfo.getProgressText();\r
122         this.sequence = new ext.vamsas.Sequence();\r
123         this.sequence.setId(msf[0].getName());\r
124         this.sequence.setSeq(AlignSeq.extractGaps("-. ", msf[0].getSequence()));\r
125         jalview.io.PileUpfile mwrite = new jalview.io.PileUpfile();\r
126         this.msa = new ext.vamsas.Msfalignment();\r
127         msa.setMsf(mwrite.print(msf));\r
128       }\r
129 \r
130       public void run()\r
131       {\r
132 \r
133         StartJob();\r
134 \r
135         while (!jobComplete && (allowedServerExceptions > 0))\r
136         {\r
137           try\r
138           {\r
139             if ( (result = server.getresult(jobId)) == null)\r
140             {\r
141               throw (new Exception(\r
142                   "Timed out when communicating with server\nTry again later.\n"));\r
143             }\r
144 \r
145             if (result.isRunning())\r
146             {\r
147               wsInfo.setStatus(WebserviceInfo.STATE_RUNNING);\r
148             }\r
149             else if (result.isQueued())\r
150             {\r
151               wsInfo.setStatus(WebserviceInfo.STATE_QUEUING);\r
152             }\r
153 \r
154             if (result.isFinished())\r
155             {\r
156               parseResult();\r
157               jobComplete = true;\r
158               jobsRunning--;\r
159             }\r
160             else\r
161             {\r
162               wsInfo.setProgressText(OutputHeader + "\n" + result.getStatus());\r
163               if (! (result.isJobFailed() || result.isServerError()))\r
164               {\r
165                 try\r
166                 {\r
167                   Thread.sleep(5000);\r
168                 }\r
169                 catch (InterruptedException ex1)\r
170                 {\r
171                 }\r
172                 //  System.out.println("I'm alive "+seqid+" "+jobid);\r
173               }\r
174               else\r
175               {\r
176                 wsInfo.setStatus(WebserviceInfo.STATE_STOPPED_ERROR);\r
177               }\r
178             }\r
179           }\r
180           catch (Exception ex)\r
181           {\r
182             allowedServerExceptions--;\r
183             wsInfo.appendProgressText("\nJPredWS Server exception!\n" +\r
184                                       ex.getMessage());\r
185             try\r
186             {\r
187               if (allowedServerExceptions > 0)\r
188               {\r
189                 Thread.sleep(5000);\r
190               }\r
191             }\r
192             catch (InterruptedException ex1)\r
193             {\r
194             }\r
195           }\r
196         }\r
197 \r
198         if (! (result.isJobFailed() || result.isServerError()))\r
199         {\r
200           wsInfo.setStatus(WebserviceInfo.STATE_STOPPED_OK);\r
201         }\r
202         else\r
203         {\r
204           wsInfo.setStatus(WebserviceInfo.STATE_STOPPED_ERROR);\r
205         }\r
206       }\r
207 \r
208       void StartJob()\r
209       {\r
210         try\r
211         {\r
212           if (msa != null)\r
213           {\r
214             jobId = server.predictOnMsa(msa);\r
215           }\r
216           else\r
217           {\r
218             jobId = server.predict(sequence);\r
219           }\r
220           if (jobId != null)\r
221           {\r
222             if (jobId.startsWith("Broken"))\r
223             {\r
224               throw new Exception("Submission " + jobId);\r
225             }\r
226             else\r
227             {\r
228               System.out.println(WsURL + " Job Id '" + jobId + "'");\r
229             }\r
230           }\r
231           else\r
232           {\r
233             throw new Exception("Server timed out - try again later\n");\r
234 \r
235           }\r
236         }\r
237         catch (Exception e)\r
238         {\r
239           wsInfo.setStatus(WebserviceInfo.STATE_STOPPED_SERVERERROR);\r
240           allowedServerExceptions = 0;\r
241           jobComplete = false;\r
242           wsInfo.appendProgressText("Failed to submit the prediction: " +\r
243                                     e.toString() + "\nJust close the window\n");\r
244           System.err.println(\r
245               "JPredWS Client: Failed to submit the prediction\n" +\r
246               e.toString() + "\n");\r
247           // e.printStackTrace(); TODO: JBPNote DEBUG\r
248         }\r
249       }\r
250 \r
251       private void addFloatAnnotations(Alignment al, int[] gapmap,\r
252                                        Vector values, String Symname,\r
253                                        String Visname, float min, float max,\r
254                                        int winLength)\r
255       {\r
256 \r
257         Annotation[] annotations = new Annotation[al.getWidth()];\r
258         for (int j = 0; j < values.size(); j++)\r
259         {\r
260           float value = Float.parseFloat(values.get(j).toString());\r
261           annotations[gapmap[j]] = new Annotation("", value + "", ' ', value);\r
262         }\r
263         al.addAnnotation(new AlignmentAnnotation(Symname, Visname, annotations,\r
264                                                  min, max, winLength));\r
265       }\r
266 \r
267       void parseResult()\r
268       {\r
269         // OutputHeader = output.getText();\r
270         if (result.isFailed())\r
271         {\r
272           OutputHeader += "Job failed.\n";\r
273         }\r
274         if (result.getStatus() != null)\r
275         {\r
276           OutputHeader += "\n" + result.getStatus();\r
277         }\r
278         if (result.getPredfile() != null)\r
279         {\r
280           OutputHeader += "\n" + result.getPredfile();\r
281           // JBPNote The returned files from a webservice could be hidden behind icons in the monitor window that, when clicked, pop up their corresponding data\r
282         }\r
283         if (result.getAligfile() != null)\r
284         {\r
285           OutputHeader += "\n" + result.getAligfile();\r
286         }\r
287         wsInfo.setProgressText(OutputHeader);\r
288         try\r
289         {\r
290           // JPredFile prediction = new JPredFile("C:/JalviewX/files/jpred.txt", "File");\r
291           jalview.io.JPredFile prediction = new jalview.io.JPredFile(result.\r
292               getPredfile(), "Paste");\r
293           SequenceI[] preds = prediction.getSeqsAsArray();\r
294           Alignment al;\r
295           int FirstSeq; // the position of the query sequence in Alignment al\r
296           boolean noMsa = true; // set if no MSA has been returned by JPred\r
297 \r
298           if (this.msa != null && result.getAligfile() != null)\r
299           {\r
300             // we ignore the returned alignment if we only predicted on a single sequence\r
301             String format = jalview.io.IdentifyFile.Identify(result.getAligfile(),\r
302                 "Paste");\r
303             if (jalview.io.FormatAdapter.formats.contains(format))\r
304             {\r
305               al = new Alignment(jalview.io.FormatAdapter.readFile(result.\r
306                   getAligfile(), "Paste", format));\r
307               noMsa = false;\r
308               FirstSeq = 0;\r
309             }\r
310             else\r
311             {\r
312               throw (new Exception("Unknown format 'format' for file : \n" +\r
313                                    result.getAligfile()));\r
314             }\r
315 \r
316           }\r
317           else\r
318           {\r
319             al = new Alignment(preds);\r
320             FirstSeq = prediction.getQuerySeqPosition();\r
321           }\r
322 \r
323           if (!jalview.analysis.SeqsetUtils.SeqCharacterUnhash(al.getSequenceAt(\r
324               FirstSeq), SequenceInfo))\r
325           {\r
326             throw (new Exception(\r
327                 "Couldn't recover sequence properties for JNet Query sequence!"));\r
328           }\r
329 \r
330           AlignmentAnnotation annot;\r
331           Annotation[] annotations = null;\r
332           int i = 0;\r
333           int width = preds[0].getSequence().length();\r
334 \r
335           int[] gapmap = al.getSequenceAt(FirstSeq).gapMap();\r
336 \r
337           if (gapmap.length != width)\r
338           {\r
339             throw (new Exception(\r
340                 "Jnet Client Error\nNumber of residues in supposed query sequence :\n"\r
341                 + al.getSequenceAt(FirstSeq).getName() + "\n"\r
342                 + al.getSequenceAt(FirstSeq).getSequence()\r
343                 + "\nDiffer from number of prediction sites in \n" +\r
344                 result.getPredfile() + "\n"));\r
345           }\r
346           // JBPNote Should also rename the query sequence sometime...\r
347           i = 0;\r
348           while (i < preds.length)\r
349           {\r
350             String id = preds[i].getName().toUpperCase();\r
351             if (id.startsWith("LUPAS") || id.startsWith("JNET") ||\r
352                 id.startsWith("JPRED"))\r
353             {\r
354               annotations = new Annotation[al.getWidth()];\r
355 \r
356               if (id.equals("JNETPRED")\r
357                   || id.equals("JNETPSSM")\r
358                   || id.equals("JNETFREQ")\r
359                   || id.equals("JNETHMM")\r
360                   || id.equals("JNETALIGN")\r
361                   || id.equals("JPRED"))\r
362               {\r
363                 for (int j = 0; j < width; j++)\r
364                 {\r
365                   annotations[gapmap[j]] = new Annotation("", "",\r
366                       preds[i].getCharAt(j), 0);\r
367                 }\r
368               }\r
369               else if (id.equals("JNETCONF"))\r
370               {\r
371                 for (int j = 0; j < width; j++)\r
372                 {\r
373                   float value = Float.parseFloat(preds[i].getCharAt(j) + "");\r
374                   annotations[gapmap[j]] = new Annotation(preds[i].getCharAt(j) +\r
375                       "", "", preds[i].getCharAt(j), value);\r
376                 }\r
377               }\r
378               else\r
379               {\r
380                 for (int j = 0; j < width; j++)\r
381                 {\r
382                   annotations[gapmap[j]] = new Annotation(preds[i].getCharAt(j) +\r
383                       "", "", ' ', 0);\r
384                 }\r
385               }\r
386 \r
387               if (id.equals("JNETCONF"))\r
388               {\r
389                 annot = new AlignmentAnnotation(preds[i].getName(),\r
390                                                 "JNet Output",\r
391                                                 annotations, 0f, 10f, 1);\r
392               }\r
393 \r
394               else\r
395               {\r
396                 annot = new AlignmentAnnotation(preds[i].getName(),\r
397                                                 "JNet Output",\r
398                                                 annotations);\r
399               }\r
400               al.addAnnotation(annot);\r
401               if (noMsa)\r
402               {\r
403                 al.deleteSequence(preds[i]);\r
404               }\r
405             }\r
406             i++;\r
407           }\r
408 \r
409           Hashtable scores = prediction.getScores();\r
410           /*  addFloatAnnotations(al, gapmap,  (Vector)scores.get("JNETPROPH"),\r
411                                 "JnetpropH", "Jnet Helix Propensity", 0f,1f,1);\r
412 \r
413             addFloatAnnotations(al, gapmap,  (Vector)scores.get("JNETPROPB"),\r
414            "JnetpropB", "Jnet Beta Sheet Propensity", 0f,1f,1);\r
415 \r
416             addFloatAnnotations(al, gapmap,  (Vector)scores.get("JNETPROPC"),\r
417                                 "JnetpropC", "Jnet Coil Propensity", 0f,1f,1);\r
418            */\r
419           AlignFrame af = new AlignFrame(al);\r
420 \r
421           Desktop.addInternalFrame(af,\r
422                                    altitle,\r
423                                    AlignFrame.NEW_WINDOW_WIDTH,\r
424                                    AlignFrame.NEW_WINDOW_HEIGHT);\r
425         }\r
426         catch (Exception ex)\r
427         {\r
428           ex.printStackTrace();\r
429         }\r
430 \r
431       }\r
432 \r
433     }\r
434   }\r