JAL-2629 fix hmsearch and jackhmmer not being able to search alignment
[jalview.git] / src / jalview / hmmer / HMMERParamStore.java
1 package jalview.hmmer;
2
3 import jalview.bin.Cache;
4 import jalview.datamodel.SequenceI;
5 import jalview.gui.Preferences;
6 import jalview.util.MessageManager;
7 import jalview.viewmodel.AlignmentViewport;
8 import jalview.ws.params.ArgumentI;
9 import jalview.ws.params.ParamDatastoreI;
10 import jalview.ws.params.WsParamSetI;
11 import jalview.ws.params.simple.BooleanOption;
12 import jalview.ws.params.simple.DoubleParameter;
13 import jalview.ws.params.simple.FileParameter;
14 import jalview.ws.params.simple.IntegerParameter;
15 import jalview.ws.params.simple.LogarithmicParameter;
16 import jalview.ws.params.simple.Option;
17 import jalview.ws.params.simple.RadioChoiceParameter;
18 import jalview.ws.params.simple.StringParameter;
19
20 import java.io.File;
21 import java.io.IOException;
22 import java.util.ArrayList;
23 import java.util.Arrays;
24 import java.util.List;
25 import java.util.Scanner;
26
27 public final class HMMERParamStore implements ParamDatastoreI
28 {
29   private static final String HMMBUILD = "hmmbuild";
30
31   private static final String HMMALIGN = "hmmalign";
32
33   private static final String HMMSEARCH = "hmmsearch";
34
35   private static final String JACKHMMER = "jackhmmer";
36
37   private String name;
38
39   private List<WsParamSetI> presets = new ArrayList<>();
40
41   private AlignmentViewport viewport;
42
43   private HMMERParamStore(String nam, AlignmentViewport av)
44   {
45     this.viewport = av;
46     this.name = nam;
47   }
48
49   public static HMMERParamStore forBuild(AlignmentViewport viewport)
50   {
51     return new HMMERParamStore(HMMBUILD, viewport);
52   }
53
54   public static HMMERParamStore forAlign(AlignmentViewport viewport)
55   {
56     return new HMMERParamStore(HMMALIGN, viewport);
57   }
58
59   public static HMMERParamStore forSearch(AlignmentViewport viewport)
60   {
61     return new HMMERParamStore(HMMSEARCH, viewport);
62   }
63
64   public static HMMERParamStore forJackhmmer(AlignmentViewport viewport)
65   {
66     return new HMMERParamStore(JACKHMMER, viewport);
67   }
68
69   @Override
70   public List<WsParamSetI> getPresets()
71   {
72     return presets;
73   }
74
75   @Override
76   public WsParamSetI getPreset(String nam)
77   {
78     return null;
79   }
80
81   @Override
82   public List<ArgumentI> getServiceParameters()
83   {
84     List<ArgumentI> args = new ArrayList<>();
85     switch (name)
86     {
87     case HMMSEARCH:
88       getHMMSearchParams(args);
89       break;
90     case HMMALIGN:
91       getHMMAlignParams(args);
92       break;
93     case HMMBUILD:
94       getHMMBuildParams(args);
95       break;
96     case JACKHMMER:
97       getJackhmmerParams(args);
98     default:
99     }
100
101     return args;
102   }
103
104   /**
105    * Answers default parameters for hmmsearch, taking into account any
106    * configured as user preferences
107    * 
108    * @param args
109    */
110   private void getHMMSearchParams(List<ArgumentI> args)
111   {
112     /*
113      * 'Options'
114      */
115     args.add(new BooleanOption(
116             MessageManager.getString(HMMSearch.AUTO_ALIGN_SEQS_KEY),
117             MessageManager.getString("label.auto_align_seqs_desc"), false,
118             false, false, null));
119     args.add(new BooleanOption(
120             MessageManager.getString(HMMSearch.USE_ACCESSIONS_KEY),
121             MessageManager.getString("label.use_accessions_desc"), false,
122             false, true, null));
123     args.add(new BooleanOption(
124             MessageManager.getString(HMMSearch.TRIM_TERMINI_KEY),
125             MessageManager.getString("label.trim_termini_desc"), false,
126             false, true, null));
127     args.add(new BooleanOption(
128             MessageManager.getString(HMMSearch.RETURN_N_NEW_SEQ),
129             MessageManager.getString("label.check_for_new_sequences_desc"),
130             false, false, false, null));
131
132     /*
133      * 'Parameters'
134      */
135     addChoiceOfHmm(args);
136
137     // addChoiceOfDatabase(args);
138
139     String thisAlignment = MessageManager
140             .getString(HMMSearch.THIS_ALIGNMENT_KEY);
141     String database = MessageManager.getString("label.database");
142     args.add(new FileParameter(database, "", false, "", ""));
143     args.add(new IntegerParameter(
144             MessageManager.getString(HMMSearch.NUMBER_OF_RESULTS_KEY),
145             MessageManager.getString("label.number_of_results_desc"), true,
146             100, 0, 100000));
147     args.add(new RadioChoiceParameter(
148             MessageManager.getString(HMMSearch.REPORTING_CUTOFF_KEY), null,
149             Arrays.asList(MessageManager.getString(HMMSearch.CUTOFF_NONE),
150                     MessageManager.getString(HMMSearch.CUTOFF_EVALUE),
151                     MessageManager.getString(HMMSearch.CUTOFF_SCORE)),
152             MessageManager.getString(HMMSearch.CUTOFF_EVALUE)));
153     args.add(new LogarithmicParameter(
154             MessageManager.getString(HMMSearch.SEQ_EVALUE_KEY),
155             MessageManager.getString("label.seq_e_value_desc"), false, 1D,
156             1E-100, 10D));
157     args.add(new LogarithmicParameter(
158             MessageManager.getString(HMMSearch.DOM_EVALUE_KEY),
159             MessageManager.getString("label.dom_e_value_desc"), false, 1D,
160             1E-100, 10D));
161     args.add(
162             new DoubleParameter(
163                     MessageManager.getString(HMMSearch.SEQ_SCORE_KEY),
164                     MessageManager.getString("label.seq_score_desc"), false,
165                     0d, 0d, 1000d));
166     args.add(
167             new DoubleParameter(
168                     MessageManager.getString(HMMSearch.DOM_SCORE_KEY),
169                     MessageManager.getString("label.dom_score_desc"), false,
170                     0d, 0d, 1000d));
171   }
172
173   /**
174    * Answers default parameters for jackhmmer, taking into account any configured
175    * as user preferences
176    * 
177    * @param args
178    */
179   private void getJackhmmerParams(List<ArgumentI> args)
180   {
181
182     /*
183      * 'Parameters'
184      */
185     addChoiceOfSequence(args);
186
187     // addChoiceOfDatabase(args);
188
189     String database = MessageManager.getString("label.database");
190     args.add(new FileParameter(database, "", false, "", ""));
191     args.add(new RadioChoiceParameter(
192             MessageManager.getString(JackHMMER.REPORTING_CUTOFF_KEY), null,
193             Arrays.asList(MessageManager.getString(JackHMMER.CUTOFF_NONE),
194                     MessageManager.getString(JackHMMER.CUTOFF_EVALUE),
195                     MessageManager.getString(JackHMMER.CUTOFF_SCORE)),
196             MessageManager.getString(JackHMMER.CUTOFF_EVALUE)));
197     args.add(new LogarithmicParameter(
198             MessageManager.getString(JackHMMER.SEQ_EVALUE_KEY),
199             MessageManager.getString("label.seq_e_value_desc"), false, 1D,
200             1E-38, 10D));
201     args.add(new LogarithmicParameter(
202             MessageManager.getString(JackHMMER.DOM_EVALUE_KEY),
203             MessageManager.getString("label.dom_e_value_desc"), false, 1D,
204             1E-38, 10D));
205     args.add(new DoubleParameter(
206             MessageManager.getString(JackHMMER.SEQ_SCORE_KEY),
207             MessageManager.getString("label.seq_score_desc"), false, 0d, 0d,
208             1000d));
209     args.add(new DoubleParameter(
210             MessageManager.getString(JackHMMER.DOM_SCORE_KEY),
211             MessageManager.getString("label.dom_score_desc"), false, 0d, 0d,
212             1000d));
213   }
214
215   /**
216    * Constructs a choice parameter for database to search; always includes 'this
217    * alignment', and also includes any databases held under user preferences key
218    * "HMMSEARCH_DBS" as a comma-delimited list
219    * 
220    * @param args
221    */
222   protected void addChoiceOfDatabase(List<ArgumentI> args)
223   {
224     String names = Cache.getProperty(Preferences.HMMSEARCH_DBS);
225     if (names == null || names.isEmpty())
226     {
227       return;
228     }
229
230     List<String> filePaths = new ArrayList<>();
231     List<String> fileNames = new ArrayList<>();
232
233     String thisAlignment = MessageManager.getString(HMMSearch.THIS_ALIGNMENT_KEY);
234     filePaths.add(thisAlignment);
235     fileNames.add(thisAlignment);
236
237     Scanner nameScanner = new Scanner(names);
238     nameScanner.useDelimiter(Preferences.COMMA);
239
240     while (nameScanner.hasNext())
241     {
242       String next = nameScanner.next();
243       if ("null".equals(next))
244       {
245         Cache.setProperty(Preferences.HMMSEARCH_DBS, "");
246       }
247       else
248       {
249         filePaths.add(next);
250         int pos = next.lastIndexOf(File.separator);
251         String fileName = next.substring(pos + 1);
252         fileNames.add(fileName);
253       }
254     }
255     nameScanner.close();
256     ArgumentI databasesOption = new StringParameter(
257             MessageManager.getString(HMMSearch.DATABASE_KEY),
258             MessageManager.getString("label.database_for_hmmsearch"), true,
259             thisAlignment,
260             thisAlignment,
261             filePaths, fileNames);
262     args.add(databasesOption);
263   }
264
265   /**
266    * Answers default parameters for hmmalign, taking into account any configured
267    * as user preferences
268    * 
269    * @param args
270    */
271   private void getHMMAlignParams(List<ArgumentI> args)
272   {
273     addChoiceOfHmm(args);
274
275     boolean def = Cache.getDefault(Preferences.HMMALIGN_TRIM_TERMINI,
276             false);
277     args.add(new BooleanOption(
278             MessageManager.getString("label.trim_termini"),
279             MessageManager.getString("label.trim_termini_desc"),
280             false, false, def, null));
281   }
282
283   /**
284    * Adds an argument representing the choice of HMM sequences (profiles)
285    * against which to perform align or search, provided at least one is found
286    * 
287    * @param args
288    */
289   protected void addChoiceOfHmm(List<ArgumentI> args)
290   {
291     List<SequenceI> hmms = viewport.getAlignment().getHmmSequences();
292     if (!hmms.isEmpty())
293     {
294       List<String> options = new ArrayList<>();
295       for (SequenceI hmmSeq : hmms)
296       {
297         options.add(hmmSeq.getName());
298       }
299       String defseq = options.get(0);
300       ArgumentI arg = new StringParameter(
301               MessageManager.getString("label.use_hmm"), null, true, defseq,
302               defseq, options, null);
303       args.add(arg);
304     }
305   }
306
307   /**
308    * Adds an argument representing the choice of sequence against which to perform
309    * jackhmmer
310    * 
311    * @param args
312    */
313   protected void addChoiceOfSequence(List<ArgumentI> args)
314   {
315     List<SequenceI> sequences = viewport.getAlignment().getSequences();
316
317     List<String> options = new ArrayList<>();
318
319     for (SequenceI seq : sequences)
320     {
321       options.add(seq.getName());
322     }
323
324     String defseq = options.get(0);
325     ArgumentI arg = new StringParameter(
326             MessageManager.getString("label.use_sequence"), null, true,
327             defseq,
328             defseq, options, null);
329     args.add(arg);
330   }
331
332   /**
333    * Answers default parameters for hmmbuild, taking into account any configured
334    * as user preferences
335    * 
336    * @param args
337    */
338   private void getHMMBuildParams(List<ArgumentI> args)
339   {
340     /*
341      * name to give the computed alignment HMM consensus sequence
342      * (Jalview constructs group HMM consensus sequence names)
343      */
344     String defValue = "Alignment_HMM";
345     StringParameter nameParam = new StringParameter(MessageManager.getString("label.hmm_name"),
346             MessageManager.getString("label.hmm_name_desc"), true, defValue,
347             defValue);
348     args.add(nameParam);
349
350     /*
351      * only enable Use Reference Annotation if RF is present
352      */
353     if (viewport.hasReferenceAnnotation())
354     {
355       args.add(new BooleanOption(
356               MessageManager.getString("label.use_reference"),
357               MessageManager.getString("label.use_reference_desc"), true,
358               true, true, null));
359     }
360
361     /*
362      * choice of whether to compute HMM for alignment and/or group(s)
363      * - only if there are any groups
364      */
365     if (!viewport.getAlignment().getGroups().isEmpty())
366     {
367       List<String> options = new ArrayList<>();
368       options.add(MessageManager.getString("label.alignment"));
369       options.add(MessageManager.getString("label.groups_and_alignment"));
370       options.add(MessageManager.getString("label.groups"));
371       options.add(MessageManager.getString("label.selected_group"));
372       args.add(new Option(MessageManager.getString("label.hmmbuild_for"),
373               MessageManager.getString("label.hmmbuild_for_desc"), true,
374               MessageManager.getString("label.alignment"),
375               MessageManager.getString("label.alignment"), options, null));
376     }
377   }
378
379   @Override
380   public boolean presetExists(String forName)
381   {
382     return false;
383   }
384
385   @Override
386   public void deletePreset(String forName)
387   {
388   }
389
390   @Override
391   public void storePreset(String presetName, String text,
392           List<ArgumentI> jobParams)
393   {
394   }
395
396   @Override
397   public void updatePreset(String oldName, String presetName, String text,
398           List<ArgumentI> jobParams)
399   {
400   }
401
402   @Override
403   public WsParamSetI parseServiceParameterFile(String forName,
404           String description, String[] serviceURL, String parameters)
405           throws IOException
406   {
407     return null;
408   }
409
410   @Override
411   public String generateServiceParameterFile(WsParamSetI pset)
412           throws IOException
413   {
414     return null;
415   }
416
417 }