JAL-3954 Fix typo in error message
[jalview.git] / src / jalview / ws2 / client / ebi / PhmmerWSClient.java
1 package jalview.ws2.client.ebi;
2
3 import java.io.IOException;
4 import java.io.StringReader;
5 import java.util.List;
6
7 import jalview.datamodel.SequenceI;
8 import jalview.io.FileFormat;
9 import jalview.ws.params.ArgumentI;
10 import jalview.ws.params.simple.BooleanOption;
11 import jalview.ws.params.simple.DoubleParameter;
12 import jalview.ws.params.simple.IntegerParameter;
13 import jalview.ws2.api.Credentials;
14 import jalview.ws2.api.JobStatus;
15 import jalview.ws2.api.WebServiceJobHandle;
16 import jalview.ws2.client.api.WebServiceClientI;
17 import uk.ac.dundee.compbio.hmmerclient.PhmmerClient;
18 import uk.ac.dundee.compbio.hmmerclient.PhmmerRequest;
19 import uk.ac.dundee.compbio.hmmerclient.PhmmerRequest.SequenceDatabase;
20 import uk.ac.dundee.compbio.hmmerclient.PhmmerRequest.SubstitutionMatrix;
21
22 public class PhmmerWSClient implements WebServiceClientI
23 {
24
25   final PhmmerClient client;
26
27   PhmmerWSClient(PhmmerClient client)
28   {
29     this.client = client;
30   }
31
32   @Override
33   public String getUrl()
34   {
35     return client.getURL().toString();
36   }
37
38   @Override
39   public String getClientName()
40   {
41     return "ebi-job-dispatcher";
42   }
43
44   @Override
45   public WebServiceJobHandle submit(List<SequenceI> sequences,
46           List<ArgumentI> args, Credentials credentials) throws IOException
47   {
48     var request = PhmmerRequest.newBuilder();
49     String sequence = FileFormat.Fasta.getWriter(null)
50             .print(new SequenceI[]{ sequences.get(0) }, false);
51     request.sequence(new StringReader(sequence));
52     populateRequestArguments(request, args);
53     var email = credentials.getEmail() != null ? credentials.getEmail() :
54       "nouser@jalview.org";
55     var jobId = client.submit(request.build(), email);
56     return new WebServiceJobHandle(
57             getClientName(), "phmmer", getUrl(), jobId);
58   }
59   
60   private static void populateRequestArguments(PhmmerRequest.Builder request, List<ArgumentI> args)
61   {
62     boolean useBitScore = false;
63     boolean useEValue = false;
64     for (var arg : args)
65     {
66       if (arg.getName().equals("cut-offs"))
67         if (arg.getValue().equals("E"))
68           useEValue = true;
69         else if (arg.getValue().equals("T"))
70           useBitScore = true;
71         else
72           throw new IllegalArgumentException(
73                   "cut-offs argument contains value other than \"E\" or \"T\": "
74                           + arg.getValue());
75     }
76     assert (useBitScore || useEValue) && !(useBitScore && useEValue);
77     for (var arg : args)
78     {
79       switch (arg.getName())
80       {
81       case "incE":
82         request.incE(useEValue ? DoubleParameter.parseFloat(arg) : null);
83         break;
84       case "incdomE":
85         request.incdomE(useEValue ? DoubleParameter.parseFloat(arg) : null);
86         break;
87       case "E":
88         request.E(useEValue ? DoubleParameter.parseFloat(arg) : null);
89         break;
90       case "domE":
91         request.domE(useEValue ? DoubleParameter.parseFloat(arg) : null);
92         break;
93       case "incT":
94         request.incT(useBitScore ? DoubleParameter.parseFloat(arg) : null);
95         break;
96       case "incdomT":
97         request.incdomT(useBitScore ? DoubleParameter.parseFloat(arg) : null);
98         break;
99       case "T":
100         request.T(useBitScore ? DoubleParameter.parseFloat(arg) : null);
101         break;
102       case "domT":
103         request.domT(useBitScore ? DoubleParameter.parseFloat(arg) : null);
104         break;
105       case "popen":
106         request.popen(DoubleParameter.parseFloat(arg));
107         break;
108       case "pextend":
109         request.pextend(DoubleParameter.parseFloat(arg));
110         break;
111       case "mx":
112         request.mx(parseSubstitutionMatrix(arg));
113         break;
114       case "nobias":
115         request.noBias(BooleanOption.parseBoolean(arg));
116         break;
117       case "compressedout":
118         request.compressedOut(BooleanOption.parseBoolean(arg));
119         break;
120       case "alignView":
121         request.compressedOut(BooleanOption.parseBoolean(arg));
122         break;
123       case "database":
124         request.database(parseSequenceDatabase(arg));
125         break;
126       case "evalue":
127         request.evalue(DoubleParameter.parseFloat(arg));
128         break;
129       case "nhits":
130         request.nhits(IntegerParameter.parseInt(arg));
131         break;
132       }
133     }
134   }
135
136   private static SubstitutionMatrix parseSubstitutionMatrix(ArgumentI arg)
137   {
138     if (arg.getValue() == null)
139       return null;
140     switch (arg.getValue())
141     {
142     case "BLOSUM45":
143       return SubstitutionMatrix.BLOSUM45;
144     case "BLOSUM62":
145       return SubstitutionMatrix.BLOSUM62;
146     case "BLOSUM90":
147       return SubstitutionMatrix.BLOSUM90;
148     case "PAM30":
149       return SubstitutionMatrix.PAM30;
150     case "PAM70":
151       return SubstitutionMatrix.PAM70;
152     default:
153       throw new IllegalArgumentException(
154               "invalid matrix " + arg.getValue());
155     }
156   }
157
158   private static SequenceDatabase parseSequenceDatabase(ArgumentI arg)
159   {
160     if (arg.getValue() == null)
161       return null;
162     switch (arg.getValue())
163     {
164     case "swissprot":
165       return SequenceDatabase.SWISS_PROT;
166     case "uniprotrefprot":
167       return SequenceDatabase.REFERENCE_PROTEOMES;
168     case "uniprotkb":
169       return SequenceDatabase.UNIPROTKB;
170     case "pdb":
171       return SequenceDatabase.PDB;
172     case "rp75":
173       return SequenceDatabase.RP75;
174     case "rp55":
175       return SequenceDatabase.RP55;
176     case "rp35":
177       return SequenceDatabase.RP35;
178     case "rp15":
179       return SequenceDatabase.RP15;
180     case "ensembl":
181       return SequenceDatabase.ENSEMBL;
182     case "merops":
183       return SequenceDatabase.MEROPS;
184     case "qfo":
185       return SequenceDatabase.QUEST_FOR_ORTHOLOGS;
186     case "chembl":
187       return SequenceDatabase.CHEMBL;
188     default:
189       throw new IllegalArgumentException(
190               "invalid database " + arg.getValue());
191     }
192   }
193
194   @Override
195   public JobStatus getStatus(WebServiceJobHandle job) throws IOException
196   {
197     var status = client.getStatus(job.getJobId());
198     switch (status)
199     {
200     case PENDING: return JobStatus.SUBMITTED;
201     case QUEUED: return JobStatus.QUEUED;
202     case RUNNING: return JobStatus.RUNNING;
203     case FINISHED: return JobStatus.COMPLETED;
204     case FAILURE: return JobStatus.FAILED;
205     case ERROR: return JobStatus.SERVER_ERROR;
206     case NOT_FOUND: return JobStatus.SERVER_ERROR;
207     case UNDEFINED: return JobStatus.UNKNOWN;
208     }
209     return JobStatus.UNKNOWN;
210   }
211
212   @Override
213   public String getLog(WebServiceJobHandle job) throws IOException
214   {
215     return "";
216   }
217
218   @Override
219   public String getErrorLog(WebServiceJobHandle job) throws IOException
220   {
221     return "";
222   }
223
224   @Override
225   public void cancel(WebServiceJobHandle job)
226           throws IOException, UnsupportedOperationException
227   {
228     throw new UnsupportedOperationException(
229             "ebi job dispatcher does not support job cancellation");
230   }
231
232 }