JAL-2629 hmm search UI and structural improvements, inclusion thresholds
[jalview.git] / src / jalview / hmmer / Search.java
1 package jalview.hmmer;
2
3 import jalview.datamodel.Alignment;
4 import jalview.datamodel.AlignmentAnnotation;
5 import jalview.datamodel.AlignmentI;
6 import jalview.datamodel.SequenceI;
7 import jalview.gui.AlignFrame;
8 import jalview.util.FileUtils;
9 import jalview.util.MessageManager;
10 import jalview.ws.params.ArgumentI;
11
12 import java.io.BufferedReader;
13 import java.io.File;
14 import java.io.FileReader;
15 import java.io.IOException;
16 import java.util.Hashtable;
17 import java.util.List;
18 import java.util.Scanner;
19
20 public abstract class Search extends HmmerCommand
21 {
22
23   static final String JACKHMMER = "jackhmmer";
24
25   static final String HMMSEARCH = "hmmsearch";
26
27   boolean realign = false;
28
29   boolean trim = false;
30
31   SequenceI[] seqs;
32
33   String databaseName;
34
35   boolean searchAlignment = true;
36
37   Hashtable sequencesHash;
38
39   public Search(AlignFrame alignFrame, List<ArgumentI> args)
40   {
41     super(alignFrame, args);
42   }
43
44   @Override
45   public void run()
46   {
47   }
48
49   /**
50    * Reads in the scores table output by jackhmmer and adds annotation to
51    * sequences for E-value and bit score
52    * 
53    * @param inputTableTemp
54    * @throws IOException
55    */
56   void readTable(File inputTableTemp) throws IOException
57   {
58     BufferedReader br = new BufferedReader(new FileReader(inputTableTemp));
59     String line = "";
60     while (!line.startsWith("Query:"))
61     {
62       line = br.readLine();
63     }
64     while (!line.contains("-------"))
65     {
66       line = br.readLine();
67     }
68     line = br.readLine();
69
70     int index = 0;
71
72     while (!"  ------ inclusion threshold ------".equals(line)
73             && !"".equals(line))
74     {
75
76       Scanner scanner = new Scanner(line);
77       String evalue = scanner.next();
78
79       if (evalue.equals("+") || evalue.equals("-"))
80       {
81         evalue = scanner.next();
82       }
83
84       String score = scanner.next();
85       checkSequenceOrder(index, scanner);
86       SequenceI seq = seqs[index];
87       addScoreAnnotations(evalue, score, seq);
88       scanner.close();
89       line = br.readLine();
90       index++;
91     }
92
93     br.close();
94   }
95
96   void checkSequenceOrder(int index, Scanner scanner)
97   {
98     String seqName = null;
99
100     for (int i = 0; i < 7; i++)
101     {
102       seqName = scanner.next();
103     }
104
105     if (!seqs[index].getName().equals(seqName))
106     {
107       SequenceI temp = seqs[index];
108
109       for (int j = 0; j < seqs.length; j++)
110       {
111         if (seqs[j].getName().equals(seqName))
112         {
113           seqs[index] = seqs[j];
114           seqs[j] = temp;
115           break;
116         }
117       }
118     }
119   }
120
121   void addScoreAnnotations(String eValue, String bitScore, SequenceI seq)
122   {
123     String label = "Search Scores";
124     String description = "Full sequence bit score and E-Value";
125
126     try
127     {
128       AlignmentAnnotation annot = new AlignmentAnnotation(label,
129               description, null);
130
131       annot.label = label;
132       annot.description = description;
133
134       annot.setCalcId(JACKHMMER);
135
136       double dEValue = Double.parseDouble(eValue);
137       annot.setEValue(dEValue);
138
139       double dBitScore = Double.parseDouble(bitScore);
140       annot.setBitScore(dBitScore);
141
142       annot.setSequenceRef(seq);
143       seq.addAlignmentAnnotation(annot);
144
145     } catch (NumberFormatException e)
146     {
147       System.err.println("Error parsing " + label + " from " + eValue
148               + " & " + bitScore);
149     }
150   }
151
152   void buildArguments(List<String> args, File searchOutputFile,
153           File hitsAlignmentFile, File queryFile) throws IOException
154   {
155     args.add("-o");
156     args.add(getFilePath(searchOutputFile, true));
157     args.add("-A");
158     args.add(getFilePath(hitsAlignmentFile, true));
159
160     File databaseFile = null;
161
162     boolean useEvalueCutoff = false;
163     boolean useScoreCutoff = false;
164     String seqReportingEvalueCutoff = null;
165     String domReportingEvalueCutoff = null;
166     String seqReportingScoreCutoff = null;
167     String domReportingScoreCutoff = null;
168     String seqInclusionEvalueCutoff = null;
169     String domInclusionEvalueCutoff = null;
170     String seqInclusionScoreCutoff = null;
171     String domInclusionScoreCutoff = null;
172     databaseName = "Alignment";
173
174     if (params != null)
175     {
176       for (ArgumentI arg : params)
177       {
178         String name = arg.getName();
179
180         if (MessageManager.getString(REPORTING_CUTOFF_KEY).equals(name))
181         {
182           if (MessageManager.getString(CUTOFF_EVALUE)
183                   .equals(arg.getValue()))
184           {
185             useEvalueCutoff = true;
186           }
187           else if (MessageManager.getString(CUTOFF_SCORE)
188                   .equals(arg.getValue()))
189           {
190             useScoreCutoff = true;
191           }
192         }
193         else if (MessageManager.getString(REPORTING_SEQ_EVALUE_KEY)
194                 .equals(name))
195         {
196           seqReportingEvalueCutoff = arg.getValue();
197         }
198         else if (MessageManager.getString(REPORTING_SEQ_SCORE_KEY)
199                 .equals(name))
200         {
201           seqReportingScoreCutoff = arg.getValue();
202         }
203         else if (MessageManager.getString(REPORTING_DOM_EVALUE_KEY)
204                 .equals(name))
205         {
206           domReportingEvalueCutoff = arg.getValue();
207         }
208         else if (MessageManager.getString(REPORTING_DOM_SCORE_KEY)
209                 .equals(name))
210         {
211           domReportingScoreCutoff = arg.getValue();
212         }
213         else if (MessageManager.getString(INCLUSION_SEQ_EVALUE_KEY)
214                 .equals(name))
215         {
216           seqInclusionEvalueCutoff = arg.getValue();
217         }
218         else if (MessageManager.getString(INCLUSION_SEQ_SCORE_KEY)
219                 .equals(name))
220         {
221           seqInclusionScoreCutoff = arg.getValue();
222         }
223         else if (MessageManager.getString(INCLUSION_DOM_EVALUE_KEY)
224                 .equals(name))
225         {
226           domInclusionEvalueCutoff = arg.getValue();
227         }
228         else if (MessageManager.getString(INCLUSION_DOM_SCORE_KEY)
229                 .equals(name))
230         {
231           domInclusionScoreCutoff = arg.getValue();
232         }
233         else if (MessageManager.getString(DATABASE_KEY).equals(name))
234         {
235           databaseFile = new File(arg.getValue());
236           if (!arg.getValue().isEmpty())
237           {
238             searchAlignment = false;
239           }
240         }
241       }
242     }
243
244     if (useEvalueCutoff)
245     {
246       args.add("-E");
247       args.add(seqReportingEvalueCutoff);
248       args.add("--domE");
249       args.add(domReportingEvalueCutoff);
250
251       args.add("--incE");
252       args.add(seqInclusionEvalueCutoff);
253       args.add("--incdomE");
254       args.add(domInclusionEvalueCutoff);
255     }
256     else if (useScoreCutoff)
257     {
258       args.add("-T");
259       args.add(seqReportingScoreCutoff);
260       args.add("--domT");
261       args.add(domReportingScoreCutoff);
262
263       args.add("--incT");
264       args.add(seqInclusionEvalueCutoff);
265       args.add("--incdomT");
266       args.add(domInclusionEvalueCutoff);
267     }
268
269     // if (!dbFound || MessageManager.getString(THIS_ALIGNMENT_KEY)
270     // .equals(dbPath))
271     if (searchAlignment)
272     {
273       /*
274        * no external database specified for search, so
275        * export current alignment as 'database' to search
276        */
277       databaseFile = FileUtils.createTempFile("database", ".sto");
278       AlignmentI al = af.getViewport().getAlignment();
279       AlignmentI copy = new Alignment(al);
280
281       deleteHmmSequences(copy);
282
283       if (searchAlignment)
284       {
285         sequencesHash = stashSequences(copy.getSequencesArray());
286       }
287
288       exportStockholm(copy.getSequencesArray(), databaseFile, null);
289     }
290
291     args.add(getFilePath(queryFile, true));
292     args.add(getFilePath(databaseFile, true));
293   }
294 }