d822439485fd12163cadb30a6b5b979ccf939156
[jalview.git] / src / jalview / hmmer / JackHMMER.java
1 package jalview.hmmer;
2
3 import jalview.bin.Cache;
4 import jalview.datamodel.Alignment;
5 import jalview.datamodel.AlignmentI;
6 import jalview.datamodel.SequenceI;
7 import jalview.gui.AlignFrame;
8 import jalview.gui.Desktop;
9 import jalview.gui.JvOptionPane;
10 import jalview.io.DataSourceType;
11 import jalview.io.FileParse;
12 import jalview.io.StockholmFile;
13 import jalview.util.FileUtils;
14 import jalview.util.MessageManager;
15 import jalview.ws.params.ArgumentI;
16
17 import java.io.BufferedReader;
18 import java.io.File;
19 import java.io.FileReader;
20 import java.io.IOException;
21 import java.util.ArrayList;
22 import java.util.List;
23
24 import javax.swing.JOptionPane;
25
26 public class JackHMMER extends Search
27 {
28
29   /**
30    * Constructor for the JackhmmerThread
31    * 
32    * @param af
33    */
34   public JackHMMER(AlignFrame af, List<ArgumentI> args)
35   {
36     super(af, args);
37   }
38
39   /**
40    * Runs the JackhmmerThread: the data on the alignment or group is exported,
41    * then the command is executed in the command line and then the data is
42    * imported and displayed in a new frame. Call this method directly to execute
43    * synchronously, or via start() in a new Thread for asynchronously.
44    */
45   @Override
46   public void run()
47   {
48     SequenceI seq = getSequence();
49     if (seq == null)
50     {
51       // shouldn't happen if we got this far
52       Cache.log.error("Error: no sequence for jackhmmer");
53       return;
54     }
55
56     long msgId = System.currentTimeMillis();
57     af.setProgressBar(MessageManager.getString("status.running_search"),
58             msgId);
59
60     try
61     {
62       File seqFile = FileUtils.createTempFile("seq", ".sto");
63       File hitsAlignmentFile = FileUtils.createTempFile("hitAlignment",
64               ".sto");
65       File searchOutputFile = FileUtils.createTempFile("searchOutput",
66               ".txt");
67
68       exportStockholm(new SequenceI[] { seq }, seqFile.getAbsoluteFile(),
69               null);
70
71       boolean ran = runCommand(searchOutputFile, hitsAlignmentFile,
72               seqFile);
73       if (!ran)
74       {
75         JvOptionPane.showInternalMessageDialog(af, MessageManager
76                 .formatMessage("warn.command_failed", "jackhmmer"));
77         return;
78       }
79
80       importData(hitsAlignmentFile, seqFile, searchOutputFile);
81       // TODO make realignment of search results a step at this level
82       // and make it conditional on this.realign
83     } catch (IOException | InterruptedException e)
84     {
85       e.printStackTrace();
86     } finally
87     {
88       af.setProgressBar("", msgId);
89     }
90   }
91
92   /**
93    * Executes an jackhmmer search with the given sequence as input. The database
94    * to be searched is a local file as specified by the 'Database' parameter, or
95    * the current alignment (written to file) if none is specified.
96    * 
97    * @param searchOutputFile
98    * @param hitsAlignmentFile
99    * @param seqFile
100    * 
101    * @return
102    * @throws IOException
103    */
104   private boolean runCommand(File searchOutputFile, File hitsAlignmentFile,
105           File seqFile) throws IOException
106   {
107     String command = getCommandPath(JACKHMMER);
108     if (command == null)
109     {
110       return false;
111     }
112
113     List<String> args = new ArrayList<>();
114     args.add(command);
115     buildArguments(args, searchOutputFile, hitsAlignmentFile, seqFile);
116
117     return runCommand(args);
118   }
119
120   /**
121    * Imports the data from the temporary file to which the output of jackhmmer was
122    * directed.
123    */
124   private void importData(File inputAlignmentTemp, File seqTemp,
125           File searchOutputFile) throws IOException, InterruptedException
126   {
127     BufferedReader br = new BufferedReader(
128             new FileReader(inputAlignmentTemp));
129     try
130     {
131       if (br.readLine() == null)
132       {
133         JOptionPane.showMessageDialog(af,
134                 MessageManager.getString("label.no_sequences_found"));
135         return;
136       }
137       StockholmFile file = new StockholmFile(new FileParse(
138               inputAlignmentTemp.getAbsolutePath(), DataSourceType.FILE));
139       seqs = file.getSeqsAsArray();
140
141       if (searchAlignment)
142       {
143         recoverSequences(sequencesHash, seqs);
144       }
145
146       readTable(searchOutputFile);
147
148       int seqCount = seqs.length;
149
150       AlignmentI al = new Alignment(seqs);
151
152       AlignFrame alignFrame = new AlignFrame(al, AlignFrame.DEFAULT_WIDTH,
153               AlignFrame.DEFAULT_HEIGHT);
154       String ttl = "jackhmmer search of " + databaseName + " using "
155               + seqs[0].getName();
156       Desktop.addInternalFrame(alignFrame, ttl, AlignFrame.DEFAULT_WIDTH,
157               AlignFrame.DEFAULT_HEIGHT);
158
159       seqTemp.delete();
160       inputAlignmentTemp.delete();
161       searchOutputFile.delete();
162     } finally
163     {
164       if (br != null)
165       {
166         br.close();
167       }
168     }
169   }
170
171
172
173
174 }