7aaa2fecdcc9f54fdd01b817ba0c10e6b4bb73dd
[jalview.git] / src / jalview / ws / jws2 / AAConsClient.java
1 package jalview.ws.jws2;
2
3
4 import jalview.analysis.AlignSeq;
5 import jalview.analysis.SeqsetUtils;
6 import jalview.api.AlignViewportI;
7 import jalview.api.AlignmentViewPanel;
8 import jalview.datamodel.AlignmentAnnotation;
9 import jalview.datamodel.AlignmentI;
10 import jalview.datamodel.Annotation;
11 import jalview.datamodel.SequenceGroup;
12 import jalview.datamodel.SequenceI;
13 import jalview.gui.AlignFrame;
14 import jalview.workers.AlignCalcWorker;
15 import jalview.ws.jws2.dm.JabaWsParamSet;
16 import jalview.ws.jws2.jabaws2.Jws2Instance;
17 import jalview.ws.params.WsParamSetI;
18
19 import java.util.ArrayList;
20 import java.util.Iterator;
21 import java.util.List;
22 import java.util.Map;
23 import java.util.TreeSet;
24
25 import compbio.data.msa.SequenceAnnotation;
26 import compbio.data.sequence.Score;
27 import compbio.data.sequence.ScoreManager;
28 import compbio.metadata.Argument;
29 import compbio.metadata.ChunkHolder;
30 import compbio.metadata.JobStatus;
31 import compbio.metadata.JobSubmissionException;
32 import compbio.metadata.Option;
33 import compbio.metadata.ResultNotAvailableException;
34 import compbio.metadata.WrongParameterException;
35
36 public class AAConsClient extends AlignCalcWorker
37 {
38
39   public AAConsClient(AlignViewportI alignViewport,
40           AlignmentViewPanel alignPanel)
41   {
42     super(alignViewport, alignPanel);
43   }
44
45   @SuppressWarnings("unchecked")
46   SequenceAnnotation aaservice;
47
48   private ScoreManager scoremanager;
49
50   private WsParamSetI preset;
51
52   private List<Argument> arguments;
53   
54   public WsParamSetI getPreset()
55   {
56     return preset;
57   }
58   public List<Argument> getArguments()
59   {
60     return arguments;
61   }
62   /**
63    * reconfigure and restart the AAConsClient. This method will spawn a new thread that will wait until any current jobs are finished, modify the parameters and restart the conservation calculation with the new values.
64    * @param newpreset
65    * @param newarguments
66    */
67   public void updateParameters(final WsParamSetI newpreset, final List<Argument> newarguments)
68   {
69     if (calcMan.isWorking(this))
70     {
71       new Thread(new Runnable() {
72         @Override
73         public void run()
74         {
75          
76           try {Thread.sleep(200);
77           } catch (InterruptedException x) {};
78             updateParameters(newpreset, newarguments);
79           }
80         }
81       ).start();
82     } else {
83       preset=newpreset;
84       arguments=newarguments;
85       calcMan.startWorker(this);
86     }
87   }
88  
89
90   public AAConsClient(Jws2Instance service, AlignFrame alignFrame,
91           WsParamSetI preset, List<Argument> paramset)
92   {
93     this(alignFrame.getCurrentView(), alignFrame.alignPanel);
94     this.preset = preset;
95     this.arguments = paramset;
96     aaservice = (SequenceAnnotation) service.service;
97
98   }
99
100   public List<Option> getJabaArguments()
101   {
102     List<Option> newargs = new ArrayList<Option>();
103     if (preset != null && preset instanceof JabaWsParamSet)
104     {
105       newargs.addAll(((JabaWsParamSet) preset).getjabaArguments());
106     }
107     if (arguments != null && arguments.size() > 0)
108     {
109       for (Argument rg : arguments)
110       {
111         if (Option.class.isAssignableFrom(rg.getClass()))
112         {
113           newargs.add((Option) rg);
114         }
115       }
116     }
117     return newargs;
118   }
119
120   @Override
121   public void run()
122   {
123     if (aaservice == null)
124     {
125       return;
126     }
127
128     try
129     {
130       if (checkDone())
131       {
132         return; 
133       }
134       AlignmentI alignment = alignViewport.getAlignment();
135
136       int aWidth = -1;
137
138       if (alignment == null || (aWidth = alignment.getWidth()) < 0)
139       {
140         calcMan.workerComplete(this);
141         return;
142       }
143
144       /*
145        * AlignmentAnnotation
146        * strucConsensus=alignViewport.getAlignmentStrucConsensusAnnotation();
147        * Hashtable[]
148        * hStrucConsensus=alignViewport.getRnaStructureConsensusHash();
149        * strucConsensus.annotations = null; strucConsensus.annotations = new
150        * Annotation[aWidth];
151        * 
152        * hStrucConsensus = new Hashtable[aWidth];
153        */
154       AlignmentAnnotation[] aa = alignViewport.getAlignment()
155               .getAlignmentAnnotation();
156       /*
157        * AlignmentAnnotation rnaStruc = null; // select rna struct to use for
158        * calculation for (int i = 0; i < aa.length; i++) { if
159        * (aa[i].getRNAStruc() != null && aa[i].isValidStruc()) { rnaStruc =
160        * aa[i]; break; } } // check to see if its valid
161        * 
162        * if (rnaStruc==null || !rnaStruc.isValidStruc()) {
163        * calcMan.workerComplete(this); return; }
164        */
165       List<compbio.data.sequence.FastaSequence> seqs = new ArrayList<compbio.data.sequence.FastaSequence>();
166
167       boolean submitGaps = true;
168       int minlen = 10;
169       for (SequenceI sq : ((List<SequenceI>) alignment.getSequences()))
170       {
171
172         if (sq.getEnd() - sq.getStart() > minlen - 1)
173         {
174           String newname = SeqsetUtils.unique_name(seqs.size() + 1);
175           // make new input sequence with or without gaps
176           seqs.add(new compbio.data.sequence.FastaSequence(newname,
177                   (submitGaps) ? sq.getSequenceAsString() : AlignSeq
178                           .extractGaps(jalview.util.Comparison.GapChars,
179                                   sq.getSequenceAsString())));
180         }
181       }
182
183       String rslt;
184       if (preset == null)
185       {
186         rslt=aaservice.analize(seqs);
187       }
188       else
189       {
190         try {
191         rslt=aaservice.customAnalize(seqs,  getJabaArguments());
192         } catch (WrongParameterException x)
193         {
194           throw new JobSubmissionException("Invalid paremeter set. Check Jalview implementation.",x);
195           
196         }
197       }
198       boolean finished = false;
199       long rpos = 0;
200       do
201       {
202         JobStatus status = aaservice.getJobStatus(rslt);
203         if (status.equals(JobStatus.FINISHED))
204         {
205           finished = true;
206         }
207         long cpos;
208         do
209         {
210           cpos = rpos;
211           ChunkHolder stats = aaservice.pullExecStatistics(rslt, rpos);
212           if (stats != null)
213           {
214             System.out.print(stats.getChunk());
215             rpos = stats.getNextPosition();
216           }
217         } while (rpos > cpos);
218
219         if (!finished && status.equals(JobStatus.FAILED))
220         {
221           try
222           {
223             Thread.sleep(200);
224           } catch (InterruptedException x)
225           {
226           }
227           ;
228         }
229
230       } while (!finished);
231       try
232       {
233         Thread.sleep(200);
234       } catch (InterruptedException x)
235       {
236       }
237       ;
238       scoremanager = aaservice.getAnnotation(rslt);
239       if (scoremanager != null)
240       {
241         updateResultAnnotation(true);
242       }
243     } catch (JobSubmissionException x)
244     {
245
246       System.err.println("submission error:");
247       x.printStackTrace();
248       calcMan.workerCannotRun(this);
249     } catch (ResultNotAvailableException x)
250     {
251       System.err.println("collection error:");
252       x.printStackTrace();
253       calcMan.workerCannotRun(this);
254
255     } catch (OutOfMemoryError error)
256     {
257       calcMan.workerCannotRun(this);
258
259       // consensus = null;
260       // hconsensus = null;
261       ap.raiseOOMWarning("calculating Amino acid consensus using AACons service", error);
262     }
263     catch (Exception x)
264     {
265       calcMan.workerCannotRun(this);
266
267       // consensus = null;
268       // hconsensus = null;
269       System.err.println("Blacklisting worker due to unexpected exception:");
270       x.printStackTrace();
271     }
272     finally {
273
274     calcMan.workerComplete(this);
275     if (ap != null)
276     {
277       ap.paintAlignment(true);
278     }
279     }
280
281   }
282
283   /**
284    * notify manager that we have started, and wait for a free calculation slot
285    * @return true if slot is obtained and work still valid, false if another thread has done our work for us.
286    */
287   private boolean checkDone()
288   {
289     calcMan.notifyStart(this);
290     // ap.paintAlignment(false);
291     while (!calcMan.notifyWorking(this))
292     {
293       if (calcMan.isWorking(this))
294       {
295         return true;
296       }
297       try
298       {
299         if (ap != null)
300         {
301           ap.paintAlignment(false);
302         }
303
304         Thread.sleep(200);
305       } catch (Exception ex)
306       {
307         ex.printStackTrace();
308       }
309     }
310     if (alignViewport.isClosed())
311     {
312       abortAndDestroy();
313       return true;
314     }
315     return false;
316   }
317
318   /**
319    * update the consensus annotation from the sequence profile data using
320    * current visualization settings.
321    */
322   public void updateAnnotation()
323   {
324     updateResultAnnotation(false);
325   }
326
327   private AlignmentAnnotation findOrCreate(String name, boolean autoCalc,
328           SequenceI seqRef, SequenceGroup groupRef)
329   {
330     for (AlignmentAnnotation annot : alignViewport.getAlignment()
331             .getAlignmentAnnotation())
332     {
333       if (annot.autoCalculated == autoCalc
334               && annot.getCalcId().equals(name)
335               && annot.sequenceRef == seqRef && annot.groupRef == groupRef)
336       {
337         return annot;
338       }
339     }
340     AlignmentAnnotation annot = new AlignmentAnnotation(name, name,
341             new Annotation[1], 0f, 0f, AlignmentAnnotation.BAR_GRAPH);
342     annot.hasText=false;
343     annot.setCalcId(new String(name));
344     annot.autoCalculated = autoCalc;
345     if (seqRef != null)
346     {
347       annot.setSequenceRef(seqRef);
348     }
349     annot.groupRef = groupRef;
350     alignViewport.getAlignment().addAnnotation(annot);
351
352     return annot;
353   }
354   public void updateResultAnnotation(boolean immediate)
355   {
356
357     if (immediate || !calcMan.isWorking(this) && scoremanager != null)
358     {
359       AlignmentAnnotation annotation;
360       ;
361       Map<String, TreeSet<Score>> scoremap = scoremanager.asMap();
362       int alWidth = alignViewport.getAlignment().getWidth();
363       AlignmentI alignment;
364       int ann = (alignment=alignViewport.getAlignment()).getAlignmentAnnotation().length;
365       ArrayList<AlignmentAnnotation> ourAnnot=new ArrayList<AlignmentAnnotation>();
366       for (String score : scoremap.keySet())
367       {
368         TreeSet<Score> scores = scoremap.get(score);
369         for (Score scr : scores)
370         {
371           if (scr.getRanges() != null && scr.getRanges().size() > 0)
372           {
373             /**
374              * annotation in range annotation = findOrCreate(scr.getMethod(),
375              * true, null, null); Annotation[] elm = new Annotation[alWidth];
376              * Iterator<Float> vals = scr.getScores().iterator(); for (Range rng
377              * : scr.getRanges()) { float val = vals.next().floatValue(); for
378              * (int i = rng.from; i <= rng.to; i++) { elm[i] = new
379              * Annotation("", "", ' ', val); } } annotation.annotations = elm;
380              * annotation.validateRangeAndDisplay();
381              */
382           }
383           else
384           {
385             // simple annotation row
386             annotation = findOrCreate(scr.getMethod(), true, null, null);
387             Annotation[] elm = new Annotation[alWidth];
388             if (alWidth==scr.getScores().size())
389             {
390             Iterator<Float> vals = scr.getScores().iterator();
391             float m=0f,x=0f;
392             for (int i = 0; vals.hasNext(); i++)
393             {
394               float val = vals.next().floatValue();
395               if (i==0) { m=val;x=val;} else { if (m>val) { m=val; }; if (x<val) { x=val;}}
396               elm[i] = new Annotation("",""+val,' ',val);
397             }
398             
399             annotation.annotations = elm;
400             annotation.belowAlignment = true;
401             if (x<0)
402             {
403               x=0;
404             }
405             x+=(x-m)*0.1;
406             annotation.graphMax=x;
407             annotation.graphMin=m;
408             annotation.validateRangeAndDisplay();
409             ourAnnot.add(annotation);
410             }
411           }
412         }
413       }
414       if (ourAnnot.size()>0)
415       {
416         List<AlignmentAnnotation> our=ourAnnots;
417         ourAnnots = ourAnnot;
418         if (our!=null) {
419           if (our.size()>0)
420           {
421             for (AlignmentAnnotation an:our)
422             {
423               if (!ourAnnots.contains(an))
424               {
425                 // remove the old annotation
426                 alignment.deleteAnnotation(an);
427               }
428             }
429           }
430           our.clear();
431         }
432       }
433       //if (ann != alignViewport.getAlignment().getAlignmentAnnotation().length)
434       {
435         ap.adjustAnnotationHeight();
436       }
437      /* else
438       {
439         ap.paintAlignment(true);
440       }*/
441     }
442   }
443
444 }