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())