Clover icon

Coverage Report

  1. Project Clover database Thu Dec 4 2025 14:43:25 GMT
  2. Package jalview.hmmer

File HMMAlign.java

 

Coverage histogram

../../img/srcFileCovDistChart0.png
60% of files have more coverage

Code metrics

32
105
7
1
340
228
27
0.26
15
7
3.86

Classes

Class Line # Actions
HMMAlign 32 105 27
0.00%
 

Contributing tests

No tests hitting this source file were found.

Source view

1    package jalview.hmmer;
2   
3    import jalview.analysis.AlignmentSorter;
4    import jalview.analysis.SeqsetUtils.SequenceInfo;
5    import jalview.datamodel.Alignment;
6    import jalview.datamodel.AlignmentI;
7    import jalview.datamodel.AlignmentOrder;
8    import jalview.datamodel.AlignmentView;
9    import jalview.datamodel.HiddenColumns;
10    import jalview.datamodel.HiddenMarkovModel;
11    import jalview.datamodel.SequenceI;
12    import jalview.gui.AlignFrame;
13    import jalview.gui.Desktop;
14    import jalview.gui.JvOptionPane;
15    import jalview.gui.SplitFrame;
16    import jalview.io.DataSourceType;
17    import jalview.io.StockholmFile;
18    import jalview.util.FileUtils;
19    import jalview.util.MessageManager;
20    import jalview.viewmodel.seqfeatures.FeatureRendererSettings;
21    import jalview.ws.params.ArgumentI;
22   
23    import java.io.File;
24    import java.io.IOException;
25    import java.util.ArrayList;
26    import java.util.Hashtable;
27    import java.util.List;
28    import java.util.Map;
29   
30    import javax.swing.JInternalFrame;
31   
 
32    public class HMMAlign extends HmmerCommand
33    {
34    static final String HMMALIGN = "hmmalign";
35   
36    private final AlignmentI dataset;
37   
38    /**
39    * Constructor for the HMMAlignThread
40    *
41    * @param af
42    * @param args
43    */
 
44  0 toggle public HMMAlign(AlignFrame af, List<ArgumentI> args)
45    {
46  0 super(af, args);
47  0 if (alignment.getDataset() != null)
48    {
49  0 dataset = alignment.getDataset();
50    }
51    else
52    {
53  0 dataset = null;
54    }
55    }
56   
57    /**
58    * Runs the HMMAlignThread: the data on the alignment or group is exported,
59    * then the command is executed in the command line and then the data is
60    * imported and displayed in a new frame (if true). The command is executed
61    * for each segment of the alignment. Call this method directly to execute
62    * synchronously, or via start() in a new Thread for asynchronously.
63    */
 
64  0 toggle @Override
65    public void run()
66    {
67  0 HiddenMarkovModel hmm = getHmmProfile();
68   
69  0 long msgId = System.currentTimeMillis();
70  0 af.setProgressBar(MessageManager.getString("status.running_hmmalign"),
71    msgId);
72   
73    // ensure alignments are the same length
74  0 alignment.padGaps();
75   
76  0 AlignmentView msa = af.gatherSequencesForAlignment();
77  0 SequenceI[][] subAlignments = msa.getVisibleContigs(alignment.getGapCharacter());
78   
79  0 List<AlignmentOrder> allOrders = new ArrayList<>();
80   
81  0 SequenceI[][] allResults = new SequenceI[subAlignments.length][];
82  0 int job = 0;
83  0 for (SequenceI[] seqs : subAlignments)
84    {
85  0 Map<String, SequenceInfo> sequencesHash = stashSequences(seqs);
86  0 try
87    {
88  0 File modelFile = FileUtils.createTempFile("hmm", ".hmm");
89  0 File alignmentFile = FileUtils.createTempFile("output", ".sto");
90  0 File resultFile = FileUtils.createTempFile("input", ".sto");
91   
92  0 exportStockholm(seqs, alignmentFile.getAbsoluteFile(), null);
93  0 exportHmm(hmm, modelFile.getAbsoluteFile());
94   
95  0 boolean ran = runCommand(modelFile, alignmentFile, resultFile);
96  0 if (!ran)
97    {
98  0 JvOptionPane.showInternalMessageDialog(af, MessageManager
99    .formatMessage("warn.command_failed", "hmmalign"));
100  0 return;
101    }
102   
103  0 SequenceI[] result = importData(resultFile, allOrders);
104  0 recoverSequences(sequencesHash, result);
105  0 allResults[job] = result;
106  0 modelFile.delete();
107  0 alignmentFile.delete();
108  0 resultFile.delete();
109    } catch (IOException e)
110    {
111  0 e.printStackTrace();
112    }
113  0 job++;
114    }
115   
116  0 String title = "hmmalign to " + hmm.getConsensusSequence().getName();
117  0 displayResults(allResults, allOrders, msa, title);
118   
119  0 af.setProgressBar("", msgId);
120    }
121   
122    /**
123    * Executes the hmmalign command and returns true if successful, false if an
124    * error is detected
125    *
126    * @param modelFile
127    * the HMM to align to
128    * @param alignmentFile
129    * the sequences to align
130    * @param resultFile
131    * the file to hold the results of alignment
132    * @return
133    * @throws IOException
134    */
 
135  0 toggle private boolean runCommand(File modelFile, File alignmentFile,
136    File resultFile) throws IOException
137    {
138  0 String command = getCommandPath(HMMALIGN);
139  0 if (command == null)
140    {
141  0 return false;
142    }
143  0 List<String> args = new ArrayList<>();
144  0 args.add(command);
145   
146  0 if (params != null)
147    {
148  0 for (ArgumentI arg : params)
149    {
150  0 String name = arg.getName();
151  0 if (MessageManager.getString("label.trim_termini").equals(name))
152    {
153  0 args.add(ARG_TRIM);
154    }
155    }
156    }
157  0 args.add("-o");
158  0 args.add(getFilePath(resultFile, true));
159  0 args.add(getFilePath(modelFile, true));
160  0 args.add(getFilePath(alignmentFile, true));
161   
162  0 return runCommand(args);
163    }
164   
165    /**
166    * Imports the data from the file holding the output of hmmalign
167    *
168    * @param resultFile
169    * @param allOrders
170    * a list of alignment orders to add to
171    *
172    * @return
173    * @throws IOException
174    */
 
175  0 toggle private SequenceI[] importData(File resultFile,
176    List<AlignmentOrder> allOrders) throws IOException
177    {
178  0 StockholmFile file = new StockholmFile(getFilePath(resultFile, false),
179    DataSourceType.FILE);
180  0 SequenceI[] result = file.getSeqsAsArray();
181  0 AlignmentOrder msaorder = new AlignmentOrder(result);
182  0 AlignmentSorter.recoverOrder(result);
183  0 allOrders.add(msaorder);
184   
185  0 return result;
186    }
187   
188    /**
189    * Displays the results of all 'jobs' in a new frame
190    *
191    * @param allResults
192    *
193    * @param allOrders
194    * @param msa
195    * @param title
196    */
 
197  0 toggle private void displayResults(SequenceI[][] allResults,
198    List<AlignmentOrder> allOrders, AlignmentView msa, String title)
199    {
200  0 AlignmentOrder[] arrOrders = allOrders
201    .toArray(new AlignmentOrder[allOrders.size()]);
202  0 Object[] newview = msa.getUpdatedView(allResults, arrOrders,
203    alignment.getGapCharacter());
204  0 SequenceI[] seqs = (SequenceI[]) newview[0];
205  0 HiddenColumns hidden = (HiddenColumns) newview[1];
206  0 Alignment al = new Alignment(seqs);
207  0 al.setProperty("Alignment Program", "hmmalign");
208  0 if (dataset != null)
209    {
210  0 al.setDataset(dataset);
211    }
212   
213  0 displayInNewFrame(al, allOrders, hidden, title);
214    }
215   
216    /**
217    * Displays the results in a new frame
218    *
219    * @param al
220    * The alignment containing the results
221    * @param alorders
222    * The order of the sequences in the alignment on which the jobs were
223    * run
224    * @param hidden
225    * Hidden columns in the previous alignment
226    * @param title
227    */
 
228  0 toggle private void displayInNewFrame(AlignmentI al,
229    List<AlignmentOrder> alorders, HiddenColumns hidden, String title)
230    {
231  0 AlignFrame alignFrame = new AlignFrame(al, hidden, AlignFrame.DEFAULT_WIDTH,
232    AlignFrame.DEFAULT_HEIGHT);
233  0 alignFrame.setTitle(title);
234   
235  0 FeatureRendererSettings featureSettings = af.getFeatureRenderer()
236    .getSettings();
237    // initialise with same renderer settings as in parent alignframe.
238  0 alignFrame.getFeatureRenderer().transferSettings(featureSettings);
239   
240  0 addSortByMenuItems(alignFrame, alorders);
241   
242    // TODO: refactor retrieve and show as new splitFrame as Desktop method
243   
244    /*
245    * If alignment was requested from one half of a SplitFrame, show in a
246    * SplitFrame with the other pane similarly aligned.
247    */
248  0 AlignFrame requestedBy = this.af;
249  0 if (requestedBy != null && requestedBy.getSplitViewContainer() != null
250    && requestedBy.getSplitViewContainer()
251    .getComplement(requestedBy) != null)
252    {
253  0 AlignmentI complement = requestedBy.getSplitViewContainer()
254    .getComplement(requestedBy);
255  0 String complementTitle = requestedBy.getSplitViewContainer()
256    .getComplementTitle(requestedBy);
257    // becomes null if the alignment window was closed before the alignment
258    // job finished.
259  0 AlignmentI copyComplement = new Alignment(complement);
260    // todo should this be done by copy constructor?
261  0 copyComplement.setGapCharacter(complement.getGapCharacter());
262    // share the same dataset (and the mappings it holds)
263  0 copyComplement.setDataset(complement.getDataset());
264  0 copyComplement.alignAs(al);
265  0 if (copyComplement.getHeight() > 0)
266    {
267  0 alignFrame.setTitle(this.af.getTitle());
268  0 AlignFrame af2 = new AlignFrame(copyComplement,
269    AlignFrame.DEFAULT_WIDTH, AlignFrame.DEFAULT_HEIGHT);
270  0 af2.setTitle(complementTitle);
271  0 String linkedTitle = MessageManager
272    .getString("label.linked_view_title");
273  0 JInternalFrame splitFrame = new SplitFrame(
274  0 al.isNucleotide() ? alignFrame : af2, al.isNucleotide() ? af2 : alignFrame);
275  0 Desktop.addInternalFrame(splitFrame, linkedTitle, -1, -1);
276  0 return;
277    }
278    }
279   
280    /*
281    * Not from SplitFrame, or failed to created a complementary alignment
282    */
283  0 Desktop.addInternalFrame(alignFrame, alignFrame.getTitle(), AlignFrame.DEFAULT_WIDTH,
284    AlignFrame.DEFAULT_HEIGHT);
285    }
286   
287    /**
288    * Adds sort order options to the AlignFrame menus
289    *
290    * @param alignFrame
291    * @param alorders
292    */
 
293  0 toggle protected void addSortByMenuItems(AlignFrame alignFrame,
294    List<AlignmentOrder> alorders)
295    {
296    // update orders
297  0 if (alorders.size() == 1)
298    {
299  0 alignFrame.addSortByOrderMenuItem("hmmalign" + " Ordering", alorders.get(0));
300    }
301    else
302    {
303    // construct a non-redundant ordering set
304  0 List<String> names = new ArrayList<>();
305  0 for (int i = 0, l = alorders.size(); i < l; i++)
306    {
307  0 String orderName = " Region " + i;
308  0 int j = i + 1;
309   
310  0 while (j < l)
311    {
312  0 if (alorders.get(i).equals(alorders.get(j)))
313    {
314  0 alorders.remove(j);
315  0 l--;
316  0 orderName += "," + j;
317    }
318    else
319    {
320  0 j++;
321    }
322    }
323   
324  0 if (i == 0 && j == 1)
325    {
326  0 names.add("");
327    }
328    else
329    {
330  0 names.add(orderName);
331    }
332    }
333  0 for (int i = 0, l = alorders.size(); i < l; i++)
334    {
335  0 alignFrame.addSortByOrderMenuItem("hmmalign" + (names.get(i)) + " Ordering",
336    alorders.get(i));
337    }
338    }
339    }
340    }