1 package jalview.ws.jws2;
3 import jalview.analysis.AlignSeq;
4 import jalview.analysis.SeqsetUtils;
5 import jalview.api.AlignViewportI;
6 import jalview.api.AlignmentViewPanel;
7 import jalview.bin.Cache;
8 import jalview.datamodel.AlignmentAnnotation;
9 import jalview.datamodel.AlignmentI;
10 import jalview.datamodel.Annotation;
11 import jalview.datamodel.SequenceFeature;
12 import jalview.datamodel.SequenceI;
13 import jalview.gui.AlignFrame;
14 import jalview.gui.IProgressIndicator;
15 import jalview.workers.AlignCalcWorker;
16 import jalview.ws.jws2.dm.JabaWsParamSet;
17 import jalview.ws.jws2.jabaws2.Jws2Instance;
18 import jalview.ws.params.WsParamSetI;
20 import java.awt.Color;
21 import java.util.ArrayList;
22 import java.util.HashMap;
23 import java.util.Iterator;
24 import java.util.List;
27 import com.sun.xml.internal.ws.client.ClientTransportException;
29 import compbio.data.msa.SequenceAnnotation;
30 import compbio.data.sequence.FastaSequence;
31 import compbio.data.sequence.Score;
32 import compbio.data.sequence.ScoreManager;
33 import compbio.metadata.Argument;
34 import compbio.metadata.ChunkHolder;
35 import compbio.metadata.JobStatus;
36 import compbio.metadata.JobSubmissionException;
37 import compbio.metadata.Option;
38 import compbio.metadata.ResultNotAvailableException;
39 import compbio.metadata.WrongParameterException;
41 public abstract class JabawsAlignCalcWorker extends AlignCalcWorker
44 @SuppressWarnings("unchecked")
45 protected SequenceAnnotation aaservice;
47 protected ScoreManager scoremanager;
49 protected WsParamSetI preset;
51 protected List<Argument> arguments;
53 public JabawsAlignCalcWorker(AlignViewportI alignViewport,
54 AlignmentViewPanel alignPanel)
56 super(alignViewport, alignPanel);
59 IProgressIndicator guiProgress;
61 public JabawsAlignCalcWorker(Jws2Instance service, AlignFrame alignFrame,
62 WsParamSetI preset, List<Argument> paramset)
64 this(alignFrame.getCurrentView(), alignFrame.alignPanel);
65 this.guiProgress = alignFrame;
67 this.arguments = paramset;
68 this.service = service;
69 aaservice = (SequenceAnnotation) service.service;
73 public WsParamSetI getPreset()
78 public List<Argument> getArguments()
84 * reconfigure and restart the AAConsClient. This method will spawn a new
85 * thread that will wait until any current jobs are finished, modify the
86 * parameters and restart the conservation calculation with the new values.
91 public void updateParameters(final WsParamSetI newpreset,
92 final List<Argument> newarguments)
95 arguments = newarguments;
96 calcMan.startWorker(this);
99 public List<Option> getJabaArguments()
101 List<Option> newargs = new ArrayList<Option>();
102 if (preset != null && preset instanceof JabaWsParamSet)
104 newargs.addAll(((JabaWsParamSet) preset).getjabaArguments());
106 if (arguments != null && arguments.size() > 0)
108 for (Argument rg : arguments)
110 if (Option.class.isAssignableFrom(rg.getClass()))
112 newargs.add((Option) rg);
122 if (aaservice == null)
126 long progressId = -1;
128 int serverErrorsLeft = 3;
130 String rslt = "JOB NOT DEFINED";
131 StringBuffer msg=new StringBuffer();
138 List<compbio.data.sequence.FastaSequence> seqs = getInputSequences(alignViewport
143 calcMan.workerComplete(this);
147 AlignmentAnnotation[] aa = alignViewport.getAlignment()
148 .getAlignmentAnnotation();
149 if (guiProgress != null)
151 guiProgress.setProgressBar("JABA " + getServiceActionText(),
152 progressId = System.currentTimeMillis());
154 if (preset == null && arguments==null)
156 rslt = aaservice.analize(seqs);
162 rslt = aaservice.customAnalize(seqs, getJabaArguments());
163 } catch (WrongParameterException x)
165 throw new JobSubmissionException(
166 "Invalid paremeter set. Check Jalview implementation.", x);
170 boolean finished = false;
174 JobStatus status = aaservice.getJobStatus(rslt);
175 if (status.equals(JobStatus.FINISHED))
179 if (calcMan.isPending(this) && this instanceof AAConsClient)
182 // cancel this job and yield to the new job
185 if (aaservice.cancelJob(rslt))
187 System.err.println("Cancelled AACon job: " + rslt);
191 System.err.println("FAILED TO CANCELL AACon job: " + rslt);
194 } catch (Exception x)
202 ChunkHolder stats = null;
206 boolean retry = false;
211 stats = aaservice.pullExecStatistics(rslt, rpos);
212 } catch (Exception x)
215 if (x.getMessage().contains(
216 "Position in a file could not be negative!"))
218 // squash index out of bounds exception- seems to happen for
219 // disorder predictors which don't (apparently) produce any
220 // progress information and JABA server throws an exception
221 // because progress length is -1.
226 if (--serverErrorsLeft > 0)
231 } catch (InterruptedException q) {};
240 System.out.print(stats.getChunk());
242 rpos = stats.getNextPosition();
244 } while (stats != null && rpos > cpos);
246 if (!finished && status.equals(JobStatus.FAILED))
251 } catch (InterruptedException x)
257 if (serverErrorsLeft>0)
262 } catch (InterruptedException x)
266 scoremanager = aaservice.getAnnotation(rslt);
267 if (scoremanager != null)
269 jalview.bin.Cache.log
270 .debug("Updating result annotation from Job " + rslt
271 + " at " + service.getUri());
272 updateResultAnnotation(true);
277 catch (JobSubmissionException x)
280 System.err.println("submission error with " + getServiceActionText()
283 calcMan.workerCannotRun(this);
284 } catch (ResultNotAvailableException x)
286 System.err.println("collection error:\nJob ID: " + rslt);
288 calcMan.workerCannotRun(this);
290 } catch (OutOfMemoryError error)
292 calcMan.workerCannotRun(this);
295 // hconsensus = null;
296 ap.raiseOOMWarning(getServiceActionText(), error);
297 } catch (Exception x)
299 calcMan.workerCannotRun(this);
302 // hconsensus = null;
304 .println("Blacklisting worker due to unexpected exception:");
309 calcMan.workerComplete(this);
312 calcMan.workerComplete(this);
313 if (guiProgress != null && progressId!=-1)
315 guiProgress.setProgressBar("", progressId);
317 ap.paintAlignment(true);
321 // TODO: stash message somewhere in annotation or alignment view.
322 // code below shows result in a text box popup
323 /* jalview.gui.CutAndPasteTransfer cap = new jalview.gui.CutAndPasteTransfer();
324 cap.setText(msg.toString());
325 jalview.gui.Desktop.addInternalFrame(cap, "Job Status for "+getServiceActionText(), 600, 400); */
332 public void updateAnnotation()
334 updateResultAnnotation(false);
337 public abstract void updateResultAnnotation(boolean immediate);
339 public abstract String getServiceActionText();
341 boolean submitGaps = true;
343 boolean alignedSeqs = true;
345 boolean nucleotidesAllowed = false;
347 boolean proteinAllowed = false;
350 * record sequences for mapping result back to afterwards
352 protected boolean bySequence = false;
354 Map<String, SequenceI> seqNames;
357 public List<FastaSequence> getInputSequences(AlignmentI alignment)
359 if (alignment == null || alignment.getWidth() <= 0
360 || alignment.getSequences() == null
361 // || (alignedSeqs && !alignment.isAligned() && !submitGaps)
362 || alignment.isNucleotide() ? !nucleotidesAllowed
367 List<compbio.data.sequence.FastaSequence> seqs = new ArrayList<compbio.data.sequence.FastaSequence>();
373 seqNames = new HashMap<String, SequenceI>();
375 gapMap=new boolean[0];
376 for (SequenceI sq : ((List<SequenceI>) alignment.getSequences()))
378 if (sq.getEnd() - sq.getStart() > minlen - 1)
380 String newname = SeqsetUtils.unique_name(seqs.size() + 1);
381 // make new input sequence with or without gaps
382 if (seqNames != null)
384 seqNames.put(newname, sq);
389 seqs.add(seq = new compbio.data.sequence.FastaSequence(newname,sq.getSequenceAsString()));
390 if (gapMap==null || gapMap.length<seq.getSequence().length())
393 gapMap=new boolean[seq.getLength()];
394 System.arraycopy(tg, 0, gapMap, 0, tg.length);
395 for (int p=tg.length;p<gapMap.length;p++)
397 gapMap[p]=false; // init as a gap
400 for (int apos:sq.gapMap()) {
401 gapMap[apos]=true; // aligned.
404 seqs.add(seq = new compbio.data.sequence.FastaSequence(newname,
406 .extractGaps(jalview.util.Comparison.GapChars,
407 sq.getSequenceAsString())));
409 if (seq.getSequence().length() > ln)
411 ln = seq.getSequence().length();
415 if (alignedSeqs && submitGaps)
418 for (int i=0;i<gapMap.length;i++)
425 // try real hard to return something submittable
426 // TODO: some of AAcons measures need a minimum of two or three amino
427 // acids at each position, and aacons doesn't gracefully degrade.
428 for (int p = 0; p < seqs.size(); p++)
430 FastaSequence sq = seqs.get(p);
431 int l = sq.getSequence().length();
432 // strip gapped columns
433 char[] padded = new char[realw],orig=sq.getSequence().toCharArray();
434 for (int i=0,pp=0;i<realw; pp++)
440 padded[i++]=orig[pp];
446 seqs.set(p, new compbio.data.sequence.FastaSequence(sq.getId(),
447 new String(padded)));
454 * notify manager that we have started, and wait for a free calculation slot
456 * @return true if slot is obtained and work still valid, false if another
457 * thread has done our work for us.
461 calcMan.notifyStart(this);
462 ap.paintAlignment(false);
463 while (!calcMan.notifyWorking(this))
465 if (calcMan.isWorking(this))
473 ap.paintAlignment(false);
477 } catch (Exception ex)
479 ex.printStackTrace();
482 if (alignViewport.isClosed())
490 protected void createAnnotationRowsForScores(
491 List<AlignmentAnnotation> ourAnnot, String calcId, int alWidth,
494 // simple annotation row
495 AlignmentAnnotation annotation = alignViewport.getAlignment()
496 .findOrCreateAnnotation(scr.getMethod(), calcId, true, null,
498 if (alWidth == gapMap.length) // scr.getScores().size())
500 constructAnnotationFromScore(annotation, 0, alWidth, scr);
501 ourAnnot.add(annotation);
505 protected AlignmentAnnotation createAnnotationRowsForScores(
506 List<AlignmentAnnotation> ourAnnot, String typeName,
507 String calcId, SequenceI dseq, int base, Score scr)
509 System.out.println("Creating annotation on dseq:" + dseq.getStart()
510 + " base is " + base + " and length=" + dseq.getLength()
511 + " == " + scr.getScores().size());
512 // AlignmentAnnotation annotation = new AlignmentAnnotation(
513 // scr.getMethod(), typeName, new Annotation[]
514 // {}, 0, -1, AlignmentAnnotation.LINE_GRAPH);
515 // annotation.setCalcId(calcId);
516 AlignmentAnnotation annotation = alignViewport.getAlignment()
517 .findOrCreateAnnotation(typeName, calcId, false, dseq, null);
518 constructAnnotationFromScore(annotation, base, dseq.getLength(), scr);
519 annotation.createSequenceMapping(dseq, dseq.findPosition(base), false);
520 annotation.adjustForAlignment();
521 dseq.addAlignmentAnnotation(annotation);
522 ourAnnot.add(annotation);
526 private void constructAnnotationFromScore(AlignmentAnnotation annotation,
527 int base, int alWidth, Score scr)
529 Annotation[] elm = new Annotation[alWidth];
530 Iterator<Float> vals = scr.getScores().iterator();
531 float m = 0f, x = 0f;
532 for (int i = base; vals.hasNext(); i++)
534 float val = vals.next().floatValue();
552 // if we're at a gapped column then skip to next ungapped position
553 if (gapMap != null && gapMap.length > 0)
557 elm[i++] = new Annotation("", "", ' ', Float.NaN);
560 elm[i] = new Annotation("", "" + val, ' ', val);
563 annotation.annotations = elm;
564 annotation.belowAlignment = true;
570 annotation.graphMax = x;
571 annotation.graphMin = m;
572 annotation.validateRangeAndDisplay();
575 protected void updateOurAnnots(List<AlignmentAnnotation> ourAnnot)
577 List<AlignmentAnnotation> our = ourAnnots;
578 ourAnnots = ourAnnot;
579 AlignmentI alignment = alignViewport.getAlignment();
584 for (AlignmentAnnotation an : our)
586 if (!ourAnnots.contains(an))
588 // remove the old annotation
589 alignment.deleteAnnotation(an);
595 ap.adjustAnnotationHeight();