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