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