3 import jalview.bin.Cache;
4 import jalview.datamodel.Alignment;
5 import jalview.datamodel.AlignmentAnnotation;
6 import jalview.datamodel.AlignmentI;
7 import jalview.datamodel.Annotation;
8 import jalview.datamodel.HiddenMarkovModel;
9 import jalview.datamodel.SequenceI;
10 import jalview.gui.AlignFrame;
11 import jalview.gui.Desktop;
12 import jalview.gui.JvOptionPane;
13 import jalview.io.DataSourceType;
14 import jalview.io.FileParse;
15 import jalview.io.StockholmFile;
16 import jalview.util.FileUtils;
17 import jalview.util.MessageManager;
18 import jalview.ws.params.ArgumentI;
19 import jalview.ws.params.simple.BooleanOption;
20 import jalview.ws.params.simple.Option;
22 import java.io.BufferedReader;
24 import java.io.FileReader;
25 import java.io.IOException;
26 import java.util.ArrayList;
27 import java.util.Collections;
28 import java.util.List;
30 import javax.swing.JOptionPane;
32 public class HMMSearch extends Search
35 boolean realign = false;
39 boolean returnNoOfNewSeqs = false;
41 int seqsToReturn = Integer.MAX_VALUE;
45 * Constructor for the HMMSearchThread
49 public HMMSearch(AlignFrame af, List<ArgumentI> args)
55 * Runs the HMMSearchThread: the data on the alignment or group is exported,
56 * then the command is executed in the command line and then the data is
57 * imported and displayed in a new frame. Call this method directly to execute
58 * synchronously, or via start() in a new Thread for asynchronously.
63 HiddenMarkovModel hmm = getHmmProfile();
66 // shouldn't happen if we got this far
67 Cache.log.error("Error: no hmm for hmmsearch");
71 SequenceI hmmSeq = hmm.getConsensusSequence();
72 long msgId = System.currentTimeMillis();
73 af.setProgressBar(MessageManager.getString("status.running_search"),
78 File hmmFile = FileUtils.createTempFile("hmm", ".hmm");
79 File hitsAlignmentFile = FileUtils.createTempFile("hitAlignment",
81 File searchOutputFile = FileUtils.createTempFile("searchOutput",
84 exportHmm(hmm, hmmFile.getAbsoluteFile());
86 boolean ran = runCommand(searchOutputFile, hitsAlignmentFile, hmmFile);
89 JvOptionPane.showInternalMessageDialog(af, MessageManager
90 .formatMessage("warn.command_failed", "hmmsearch"));
94 importData(hmmSeq, hitsAlignmentFile, hmmFile, searchOutputFile);
95 // TODO make realignment of search results a step at this level
96 // and make it conditional on this.realign
97 } catch (IOException | InterruptedException e)
103 af.setProgressBar("", msgId);
108 * Executes an hmmsearch with the given hmm as input. The database to be
109 * searched is a local file as specified by the 'Database' parameter, or the
110 * current alignment (written to file) if none is specified.
112 * @param searchOutputFile
113 * @param hitsAlignmentFile
117 * @throws IOException
119 private boolean runCommand(File searchOutputFile, File hitsAlignmentFile,
120 File hmmFile) throws IOException
122 String command = getCommandPath(HMMSEARCH);
128 List<String> args = new ArrayList<>();
130 buildArguments(args, searchOutputFile, hitsAlignmentFile, hmmFile);
132 return runCommand(args);
137 * Imports the data from the temporary file to which the output of hmmsearch
138 * was directed. The results are optionally realigned using hmmalign.
142 private void importData(SequenceI hmmSeq, File inputAlignmentTemp,
143 File hmmTemp, File searchOutputFile)
144 throws IOException, InterruptedException
146 BufferedReader br = new BufferedReader(
147 new FileReader(inputAlignmentTemp));
150 if (br.readLine() == null)
152 JOptionPane.showMessageDialog(af,
153 MessageManager.getString("label.no_sequences_found"));
156 StockholmFile file = new StockholmFile(new FileParse(
157 inputAlignmentTemp.getAbsolutePath(), DataSourceType.FILE));
158 seqs = file.getSeqsAsArray();
160 readDomainTable(searchOutputFile, false);
164 recoverSequences(sequencesHash, seqs);
167 // look for PP cons and ref seq in alignment only annotation
168 AlignmentAnnotation modelpos = null, ppcons = null;
169 for (AlignmentAnnotation aa : file.getAnnotations())
171 if (aa.sequenceRef == null)
173 if (aa.label.equals("Reference Positions")) // RF feature type in
178 if (aa.label.equals("Posterior Probability"))
186 int seqCount = Math.min(seqs.length, seqsToReturn);
187 SequenceI[] hmmAndSeqs = new SequenceI[seqCount + 1];
188 hmmSeq = hmmSeq.deriveSequence(); // otherwise all bad things happen
189 hmmAndSeqs[0] = hmmSeq;
190 System.arraycopy(seqs, 0, hmmAndSeqs, 1, seqCount);
191 if (modelpos != null)
193 // TODO need - get ungapped sequence method
195 hmmSeq.getDatasetSequence().getSequenceAsString());
196 Annotation[] refpos = modelpos.annotations;
197 // insert gaps to match with refseq positions
198 int gc = 0, lcol = 0;
199 for (int c = 0; c < refpos.length; c++)
201 if (refpos[c] != null && ("x".equals(refpos[c].displayCharacter)))
205 hmmSeq.insertCharAt(lcol + 1, gc, '-');
219 realignResults(hmmAndSeqs);
223 AlignmentI al = new Alignment(hmmAndSeqs);
226 al.addAnnotation(ppcons);
228 if (modelpos != null)
230 al.addAnnotation(modelpos);
232 AlignFrame alignFrame = new AlignFrame(al, AlignFrame.DEFAULT_WIDTH,
233 AlignFrame.DEFAULT_HEIGHT);
234 String ttl = "hmmSearch of " + databaseName + " using "
236 Desktop.addInternalFrame(alignFrame, ttl, AlignFrame.DEFAULT_WIDTH,
237 AlignFrame.DEFAULT_HEIGHT);
239 if (returnNoOfNewSeqs)
241 int nNew = checkForNewSequences();
242 JvOptionPane.showMessageDialog(af.alignPanel, nNew + " "
243 + MessageManager.getString("label.new_returned"));
250 inputAlignmentTemp.delete();
251 searchOutputFile.delete();
261 private int checkForNewSequences()
263 int nNew = seqs.length;
265 for (SequenceI resultSeq : seqs)
267 for (SequenceI aliSeq : alignment.getSequencesArray())
269 if (resultSeq.getName().equals(aliSeq.getName()))
282 * Realigns the given sequences using hmmalign, to the HMM profile sequence
283 * which is the first in the array, and opens the results in a new frame
287 protected void realignResults(SequenceI[] hmmAndSeqs)
290 * and align the search results to the HMM profile
292 AlignmentI al = new Alignment(hmmAndSeqs);
293 AlignFrame frame = new AlignFrame(al, 1, 1);
294 List<ArgumentI> alignArgs = new ArrayList<>();
295 String alignTo = hmmAndSeqs[0].getName();
296 List<String> options = Collections.singletonList(alignTo);
297 Option option = new Option(MessageManager.getString("label.use_hmm"),
298 "", true, alignTo, alignTo, options, null);
299 alignArgs.add(option);
302 alignArgs.add(new BooleanOption(
303 MessageManager.getString(TRIM_TERMINI_KEY),
304 MessageManager.getString("label.trim_termini_desc"), true,
307 HmmerCommand hmmalign = new HMMAlign(frame, alignArgs);
310 if (returnNoOfNewSeqs)
312 int nNew = checkForNewSequences();
313 JvOptionPane.showMessageDialog(frame.alignPanel,
314 nNew + " " + MessageManager.getString("label.new_returned"));