X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=src%2Fjalview%2Fhmmer%2FHmmerCommand.java;h=a30c524e8b21910baaaa557f7907fa2a5985ca95;hb=0d519ae0c45b0b9962b4589e84c262a71bb2f346;hp=f8f2cdeed5d78addce1c876b26c967e27991eb75;hpb=d31b51985d01217340aa5f6470d3fd3c2314e3eb;p=jalview.git diff --git a/src/jalview/hmmer/HmmerCommand.java b/src/jalview/hmmer/HmmerCommand.java index f8f2cde..a30c524 100644 --- a/src/jalview/hmmer/HmmerCommand.java +++ b/src/jalview/hmmer/HmmerCommand.java @@ -8,10 +8,12 @@ import jalview.datamodel.AlignmentI; import jalview.datamodel.AnnotatedCollectionI; import jalview.datamodel.Annotation; import jalview.datamodel.HiddenMarkovModel; +import jalview.datamodel.SequenceGroup; import jalview.datamodel.SequenceI; import jalview.gui.AlignFrame; import jalview.gui.JvOptionPane; import jalview.gui.Preferences; +import jalview.io.FastaFile; import jalview.io.HMMFile; import jalview.io.StockholmFile; import jalview.util.FileUtils; @@ -24,6 +26,7 @@ import java.io.File; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; +import java.nio.file.Paths; import java.util.ArrayList; import java.util.Hashtable; import java.util.List; @@ -44,6 +47,41 @@ public abstract class HmmerCommand implements Runnable protected final List params; + /* + * constants for i18n lookup of passed parameter names + */ + static final String DATABASE_KEY = "label.database"; + + static final String THIS_ALIGNMENT_KEY = "label.this_alignment"; + + static final String USE_ACCESSIONS_KEY = "label.use_accessions"; + + static final String AUTO_ALIGN_SEQS_KEY = "label.auto_align_seqs"; + + static final String NUMBER_OF_RESULTS_KEY = "label.number_of_results"; + + static final String TRIM_TERMINI_KEY = "label.trim_termini"; + + static final String RETURN_N_NEW_SEQ = "label.check_for_new_sequences"; + + static final String REPORTING_CUTOFF_KEY = "label.reporting_cutoff"; + + static final String CUTOFF_NONE = "label.default"; + + static final String CUTOFF_SCORE = "label.score"; + + static final String CUTOFF_EVALUE = "label.evalue"; + + static final String SEQ_EVALUE_KEY = "label.seq_evalue"; + + static final String DOM_EVALUE_KEY = "label.dom_evalue"; + + static final String SEQ_SCORE_KEY = "label.seq_score"; + + static final String DOM_SCORE_KEY = "label.dom_score"; + + static final String ARG_TRIM = "--trim"; + /** * Constructor * @@ -111,6 +149,12 @@ public abstract class HmmerCommand implements Runnable { ProcessBuilder pb = new ProcessBuilder(args); pb.redirectErrorStream(true); // merge syserr to sysout + if (Platform.isWindows()) + { + String path = pb.environment().get("Path"); + path = jalview.bin.Cache.getProperty("CYGWIN_PATH") + ";" + path; + pb.environment().put("Path", path); + } final Process p = pb.start(); new Thread(new Runnable() { @@ -167,6 +211,7 @@ public abstract class HmmerCommand implements Runnable } List wrapped = new ArrayList<>(); + // wrapped.add("C:\Users\tva\run"); wrapped.add(bash.getAbsolutePath()); wrapped.add("-c"); @@ -185,7 +230,7 @@ public abstract class HmmerCommand implements Runnable /** * Exports an alignment, and reference (RF) annotation if present, to the - * specified file, in Stockholm format + * specified file, in Stockholm format, removing all HMM sequences * * @param seqs * @param toFile @@ -193,13 +238,15 @@ public abstract class HmmerCommand implements Runnable * @throws IOException */ public void exportStockholm(SequenceI[] seqs, File toFile, - AnnotatedCollectionI annotated) throws IOException + AnnotatedCollectionI annotated) + throws IOException { if (seqs == null) { return; } AlignmentI newAl = new Alignment(seqs); + if (!newAl.isAligned()) { newAl.padGaps(); @@ -233,6 +280,17 @@ public abstract class HmmerCommand implements Runnable } } + for (SequenceI seq : newAl.getSequencesArray()) + { + if (seq.getAnnotation() != null) + { + for (AlignmentAnnotation ann : seq.getAnnotation()) + { + seq.removeAlignmentAnnotation(ann); + } + } + } + StockholmFile file = new StockholmFile(newAl); String output = file.print(seqs, false); PrintWriter writer = new PrintWriter(toFile); @@ -247,10 +305,14 @@ public abstract class HmmerCommand implements Runnable * @param cmd * command short name e.g. hmmalign * @return + * @throws IOException */ protected String getCommandPath(String cmd) + throws IOException { String binariesFolder = Cache.getProperty(Preferences.HMMER_PATH); + // ensure any symlink to the directory is resolved: + binariesFolder = Paths.get(binariesFolder).toRealPath().toString(); File file = FileUtils.getExecutable(cmd, binariesFolder); if (file == null && af != null) { @@ -258,7 +320,7 @@ public abstract class HmmerCommand implements Runnable .formatMessage("label.executable_not_found", cmd)); } - return file == null ? null : getFilePath(file); + return file == null ? null : getFilePath(file, true); } /** @@ -280,6 +342,25 @@ public abstract class HmmerCommand implements Runnable } } + // TODO is needed? + /** + * Exports a sequence to the specified file + * + * @param hmm + * @param hmmFile + * @throws IOException + */ + public void exportSequence(SequenceI seq, File seqFile) throws IOException + { + if (seq != null) + { + FastaFile file = new FastaFile(); + PrintWriter writer = new PrintWriter(seqFile); + writer.print(file.print(new SequenceI[] { seq }, false)); + writer.close(); + } + } + /** * Answers the HMM profile for the profile sequence the user selected (default * is just the first HMM sequence in the alignment) @@ -306,18 +387,44 @@ public abstract class HmmerCommand implements Runnable } /** + * Answers the HMM profile for the profile sequence the user selected (default + * is just the first HMM sequence in the alignment) + * + * @return + */ + protected SequenceI getSequence() + { + String alignToParamName = MessageManager + .getString("label.use_sequence"); + for (ArgumentI arg : params) + { + String name = arg.getName(); + if (name.equals(alignToParamName)) + { + String seqName = arg.getValue(); + SequenceI seq = alignment.findName(seqName); + return seq; + } + } + return null; + } + + /** * Answers an absolute path to the given file, in a format suitable for * processing by a hmmer command. On a Windows platform, the native Windows file * path is converted to Cygwin format, by replacing '\'with '/' and drive letter * X with /cygdrive/x. * * @param resultFile + * @param isInCygwin + * True if file is to be read/written from within the Cygwin + * shell. Should be false for any imports. * @return */ - protected String getFilePath(File resultFile) + protected String getFilePath(File resultFile, boolean isInCygwin) { String path = resultFile.getAbsolutePath(); - if (Platform.isWindows()) + if (Platform.isWindows() && isInCygwin) { // the first backslash escapes '\' for the regular expression argument path = path.replaceAll("\\" + File.separator, "/"); @@ -331,4 +438,87 @@ public abstract class HmmerCommand implements Runnable return path; } + + /** + * A helper method that deletes any HMM consensus sequence from the given + * collection, and from the parent alignment if ac is a subgroup + * + * @param ac + */ + void deleteHmmSequences(AnnotatedCollectionI ac) + { + List hmmSeqs = ac.getHmmSequences(); + for (SequenceI hmmSeq : hmmSeqs) + { + if (ac instanceof SequenceGroup) + { + ((SequenceGroup) ac).deleteSequence(hmmSeq, false); + AnnotatedCollectionI context = ac.getContext(); + if (context != null && context instanceof AlignmentI) + { + ((AlignmentI) context).deleteSequence(hmmSeq); + } + } + else + { + ((AlignmentI) ac).deleteSequence(hmmSeq); + } + } + } + + /** + * Sets the names of any duplicates within the given sequences to include their + * respective lengths. Deletes any duplicates that have the same name after this + * step + * + * @param seqs + */ + void renameDuplicates(AlignmentI al) + { + + SequenceI[] seqs = al.getSequencesArray(); + List wasRenamed = new ArrayList<>(); + + for (SequenceI seq : seqs) + { + wasRenamed.add(false); + } + + for (int i = 0; i < seqs.length; i++) + { + for (int j = 0; j < seqs.length; j++) + { + if (seqs[i].getName().equals(seqs[j].getName()) && i != j + && !wasRenamed.get(j)) + { + + wasRenamed.set(i, true); + String range = "/" + seqs[j].getStart() + "-" + seqs[j].getEnd(); + // setting sequence name to include range - to differentiate between + // sequences of the same name. Currently have to include the range twice + // because the range is removed (once) when setting the name + // TODO come up with a better way of doing this + seqs[j].setName(seqs[j].getName() + range + range); + } + + } + if (wasRenamed.get(i)) + { + String range = "/" + seqs[i].getStart() + "-" + seqs[i].getEnd(); + seqs[i].setName(seqs[i].getName() + range + range); + } + } + + for (int i = 0; i < seqs.length; i++) + { + for (int j = 0; j < seqs.length; j++) + { + if (seqs[i].getName().equals(seqs[j].getName()) && i != j) + { + al.deleteSequence(j); + } + } + } + } + }