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