--- /dev/null
+package jalview.ws2.client.ebi;
+
+import java.io.IOException;
+import java.io.StringReader;
+import java.util.List;
+
+import jalview.datamodel.SequenceI;
+import jalview.io.FileFormat;
+import jalview.ws.params.ArgumentI;
+import jalview.ws.params.simple.BooleanOption;
+import jalview.ws.params.simple.DoubleParameter;
+import jalview.ws.params.simple.IntegerParameter;
+import jalview.ws2.api.Credentials;
+import jalview.ws2.api.JobStatus;
+import jalview.ws2.api.WebServiceJobHandle;
+import jalview.ws2.client.api.WebServiceClientI;
+import uk.ac.dundee.compbio.hmmerclient.PhmmerClient;
+import uk.ac.dundee.compbio.hmmerclient.PhmmerRequest;
+import uk.ac.dundee.compbio.hmmerclient.PhmmerRequest.SequenceDatabase;
+import uk.ac.dundee.compbio.hmmerclient.PhmmerRequest.SubstitutionMatrix;
+
+public class PhmmerWSClient implements WebServiceClientI
+{
+
+ final PhmmerClient client;
+
+ PhmmerWSClient(PhmmerClient client)
+ {
+ this.client = client;
+ }
+
+ @Override
+ public String getUrl()
+ {
+ return client.getURL().toString();
+ }
+
+ @Override
+ public String getClientName()
+ {
+ return "ebi-job-dispatcher";
+ }
+
+ @Override
+ public WebServiceJobHandle submit(List<SequenceI> sequences,
+ List<ArgumentI> args, Credentials credentials) throws IOException
+ {
+ var request = PhmmerRequest.newBuilder();
+ String sequence = FileFormat.Fasta.getWriter(null)
+ .print(new SequenceI[]{ sequences.get(0) }, false);
+ request.sequence(new StringReader(sequence));
+ populateRequestArguments(request, args);
+ var email = credentials.getEmail() != null ? credentials.getEmail() :
+ "nouser@jalview.org";
+ var jobId = client.submit(request.build(), email);
+ return new WebServiceJobHandle(
+ getClientName(), "phmmer", getUrl(), jobId);
+ }
+
+ private static void populateRequestArguments(PhmmerRequest.Builder request, List<ArgumentI> args)
+ {
+ boolean useBitScore = false;
+ boolean useEValue = false;
+ for (var arg : args)
+ {
+ if (arg.getName().equals("cut-offs"))
+ if (arg.getValue().equals("E"))
+ useEValue = true;
+ else if (arg.getValue().equals("T"))
+ useBitScore = true;
+ else
+ throw new IllegalArgumentException(
+ "cut-offs argument contains value other than \"E\" or \"T\": "
+ + arg.getValue());
+ }
+ assert (useBitScore || useEValue) && !(useBitScore && useEValue);
+ for (var arg : args)
+ {
+ switch (arg.getName())
+ {
+ case "incE":
+ request.incE(useEValue ? DoubleParameter.parseFloat(arg) : null);
+ break;
+ case "incdomE":
+ request.incdomE(useEValue ? DoubleParameter.parseFloat(arg) : null);
+ break;
+ case "E":
+ request.E(useEValue ? DoubleParameter.parseFloat(arg) : null);
+ break;
+ case "domE":
+ request.domE(useEValue ? DoubleParameter.parseFloat(arg) : null);
+ break;
+ case "incT":
+ request.incT(useBitScore ? DoubleParameter.parseFloat(arg) : null);
+ break;
+ case "incdomT":
+ request.incdomT(useBitScore ? DoubleParameter.parseFloat(arg) : null);
+ break;
+ case "T":
+ request.T(useBitScore ? DoubleParameter.parseFloat(arg) : null);
+ break;
+ case "domT":
+ request.domT(useBitScore ? DoubleParameter.parseFloat(arg) : null);
+ break;
+ case "popen":
+ request.popen(DoubleParameter.parseFloat(arg));
+ break;
+ case "pextend":
+ request.pextend(DoubleParameter.parseFloat(arg));
+ break;
+ case "mx":
+ request.mx(parseSubstitutionMatrix(arg));
+ break;
+ case "nobias":
+ request.noBias(BooleanOption.parseBoolean(arg));
+ break;
+ case "compressedout":
+ request.compressedOut(BooleanOption.parseBoolean(arg));
+ break;
+ case "alignView":
+ request.compressedOut(BooleanOption.parseBoolean(arg));
+ break;
+ case "database":
+ request.database(parseSequenceDatabase(arg));
+ break;
+ case "evalue":
+ request.evalue(DoubleParameter.parseFloat(arg));
+ break;
+ case "nhits":
+ request.nhits(IntegerParameter.parseInt(arg));
+ break;
+ }
+ }
+ }
+
+ private static SubstitutionMatrix parseSubstitutionMatrix(ArgumentI arg)
+ {
+ if (arg.getValue() == null)
+ return null;
+ switch (arg.getValue())
+ {
+ case "BLOSUM45":
+ return SubstitutionMatrix.BLOSUM45;
+ case "BLOSUM62":
+ return SubstitutionMatrix.BLOSUM62;
+ case "BLOSUM90":
+ return SubstitutionMatrix.BLOSUM90;
+ case "PAM30":
+ return SubstitutionMatrix.PAM30;
+ case "PAM70":
+ return SubstitutionMatrix.PAM70;
+ default:
+ throw new IllegalArgumentException(
+ "invalid matrix " + arg.getValue());
+ }
+ }
+
+ private static SequenceDatabase parseSequenceDatabase(ArgumentI arg)
+ {
+ if (arg.getValue() == null)
+ return null;
+ switch (arg.getValue())
+ {
+ case "swissprot":
+ return SequenceDatabase.SWISS_PROT;
+ case "uniprotrefprot":
+ return SequenceDatabase.REFERENCE_PROTEOMES;
+ case "uniprotkb":
+ return SequenceDatabase.UNIPROTKB;
+ case "pdb":
+ return SequenceDatabase.PDB;
+ case "rp75":
+ return SequenceDatabase.RP75;
+ case "rp55":
+ return SequenceDatabase.RP55;
+ case "rp35":
+ return SequenceDatabase.RP35;
+ case "rp15":
+ return SequenceDatabase.RP15;
+ case "ensembl":
+ return SequenceDatabase.ENSEMBL;
+ case "merops":
+ return SequenceDatabase.MEROPS;
+ case "qfo":
+ return SequenceDatabase.QUEST_FOR_ORTHOLOGS;
+ case "chembl":
+ return SequenceDatabase.CHEMBL;
+ default:
+ throw new IllegalArgumentException(
+ "invalid database " + arg.getValue());
+ }
+ }
+
+ @Override
+ public JobStatus getStatus(WebServiceJobHandle job) throws IOException
+ {
+ var status = client.getStatus(job.getJobId());
+ switch (status)
+ {
+ case PENDING: return JobStatus.SUBMITTED;
+ case QUEUED: return JobStatus.QUEUED;
+ case RUNNING: return JobStatus.RUNNING;
+ case FINISHED: return JobStatus.COMPLETED;
+ case FAILURE: return JobStatus.FAILED;
+ case ERROR: return JobStatus.SERVER_ERROR;
+ case NOT_FOUND: return JobStatus.SERVER_ERROR;
+ case UNDEFINED: return JobStatus.UNKNOWN;
+ }
+ return JobStatus.UNKNOWN;
+ }
+
+ @Override
+ public String getLog(WebServiceJobHandle job) throws IOException
+ {
+ return "";
+ }
+
+ @Override
+ public String getErrorLog(WebServiceJobHandle job) throws IOException
+ {
+ return "";
+ }
+
+ @Override
+ public void cancel(WebServiceJobHandle job)
+ throws IOException, UnsupportedOperationException
+ {
+ throw new UnsupportedOperationException(
+ "ebi job dispather does not support job cancellation");
+ }
+
+}