001package com.hfg.bio.seq.alignment.muscle; 002 003import java.io.ByteArrayInputStream; 004import java.io.File; 005import java.io.IOException; 006import java.io.InputStream; 007import java.util.Collection; 008import java.util.List; 009 010import com.hfg.bio.seq.BioSequence; 011import com.hfg.bio.seq.format.FASTA; 012import com.hfg.util.Executor; 013import com.hfg.util.StringBuilderPlus; 014import com.hfg.util.StringUtil; 015 016//============================================================================== 017/** 018 Wrapper for a Muscle multiple sequence alignment. 019 <div> 020 Command-line executable is downloadable from <pre>https://www.drive5.com/muscle</pre> 021 </div> 022 @author J. Alex Taylor, hairyfatguy.com 023 */ 024//============================================================================== 025// com.hfg XML/HTML Coding Library 026// 027// This library is free software; you can redistribute it and/or 028// modify it under the terms of the GNU Lesser General Public 029// License as published by the Free Software Foundation; either 030// version 2.1 of the License, or (at your option) any later version. 031// 032// This library is distributed in the hope that it will be useful, 033// but WITHOUT ANY WARRANTY; without even the implied warranty of 034// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 035// Lesser General Public License for more details. 036// 037// You should have received a copy of the GNU Lesser General Public 038// License along with this library; if not, write to the Free Software 039// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 040// 041// J. Alex Taylor, President, Founder, CEO, COO, CFO, OOPS hairyfatguy.com 042// jataylor@hairyfatguy.com 043//============================================================================== 044 045public class Muscle 046{ 047 private MuscleSettings mSettings; 048 049 private static MuscleSettings sDefaultSettings; 050 051 //########################################################################### 052 // CONSTRUCTORS 053 //########################################################################### 054 055 //--------------------------------------------------------------------------- 056 public Muscle() 057 { 058 this(null); 059 } 060 061 //--------------------------------------------------------------------------- 062 public Muscle(MuscleSettings inSettings) 063 { 064 mSettings = inSettings != null ? inSettings : getDefaultSettings(); 065 } 066 067 //########################################################################### 068 // PUBLIC METHODS 069 //########################################################################### 070 071 //--------------------------------------------------------------------------- 072 public MuscleSettings getSettings() 073 { 074 return mSettings; 075 } 076 077 //--------------------------------------------------------------------------- 078 public MuscleOutput run(List<? extends BioSequence> inQueries) 079 throws IOException 080 { 081 preflight(); 082 083 String cmd = generateCmd(); 084 085 Executor executor = new Executor(); 086 executor.setSTDIN(generateSTDIN(inQueries)); 087 executor.setCommand(cmd); 088 089 int exitStatus = executor.exec(); 090 091 MuscleOutput output = new MuscleOutput() 092 .setExitStatus(exitStatus) 093 .setStdErr(executor.getSTDERR()) 094 .setStdOut(executor.getSTDOUT()) 095 .setExecutedCmd(cmd) 096 .setMuscleVersion(getVersion()); 097 098 return output; 099 } 100 101 //########################################################################### 102 // PRIVATE METHODS 103 //########################################################################### 104 105 //--------------------------------------------------------------------------- 106 public static void setDefaultSettings(MuscleSettings inValue) 107 { 108 sDefaultSettings = inValue; 109 } 110 111 //--------------------------------------------------------------------------- 112 public static MuscleSettings getDefaultSettings() 113 { 114 return (sDefaultSettings != null ? sDefaultSettings : new MuscleSettings()); 115 } 116 117 //--------------------------------------------------------------------------- 118 private File getExecutable() 119 { 120 return (getSettings().getExecutable() != null ? new File(getSettings().getExecutableDir(), getSettings().getExecutable()) : null); 121 } 122 123 //--------------------------------------------------------------------------- 124 private void preflight() 125 throws IOException 126 { 127 File exe = getExecutable(); 128 if (null == exe) 129 { 130 throw new IOException("No Muscle executable was specified!"); 131 } 132 else if (! exe.exists()) 133 { 134 File exeDir = exe.getParentFile(); 135 if (exeDir != null 136 && !exeDir.exists()) 137 { 138 throw new IOException("The Muscle executable directory " + StringUtil.singleQuote(exeDir.getPath()) + " doesn't exist!"); 139 } 140 141 throw new IOException("The Muscle executable " + StringUtil.singleQuote(exe.getPath()) + " doesn't exist!"); 142 } 143 } 144 145 146 //--------------------------------------------------------------------------- 147 private String generateCmd() 148 { 149 StringBuilderPlus cmd = new StringBuilderPlus(getExecutable().getPath()).setDelimiter(" "); 150 151 if (getSettings().getOutputFormat() != null) 152 { 153 cmd.delimitedAppend("-" + getSettings().getOutputFormat().name()); 154 } 155 156 if (getSettings().getCommandLineParams() != null) 157 { 158 cmd.delimitedAppend(getSettings().getCommandLineParams()); 159 } 160 161 return cmd.toString(); 162 } 163 164 //--------------------------------------------------------------------------- 165 private InputStream generateSTDIN(Collection<? extends BioSequence> inQuery) 166 { 167 FASTA fasta = new FASTA(); 168 // TODO 169 return new ByteArrayInputStream(fasta.write(inQuery).getBytes()); 170 } 171 172 //--------------------------------------------------------------------------- 173 private String getVersion() 174 { 175 String version = null; 176 177 Executor executor = new Executor(); 178 executor.setCommand(getExecutable() + " -version"); 179 180 int exitStatus = executor.exec(); 181 if (0 == exitStatus) 182 { 183 // MUSCLE v3.8.31 by Robert C. Edgar 184 version = executor.getSTDOUT().split("\\s+")[1]; 185 } 186 187 return version; 188 } 189}