/* * BioJava development code * * This code may be freely distributed and modified under the * terms of the GNU Lesser General Public Licence. This should * be distributed with the code. If you do not have a copy, * see: * * http://www.gnu.org/copyleft/lesser.html * * Copyright for this code is held jointly by the individual * authors. These should be listed in @author doc comments. * * For more information on the BioJava project and its aims, * or to join the biojava-l mailing list, visit the home page * at: * * http://www.biojava.org/ * * Created on 2011-11-20 * */ package org.biojava.nbio.ws.alignment.qblast; import org.biojava.nbio.ws.alignment.RemotePairwiseAlignmentProperties; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; import static org.biojava.nbio.ws.alignment.qblast.BlastAlignmentParameterEnum.*; /** * This class wraps a QBlast search request parameter {@code Map} by adding several convenient parameter addition * methods. Other QBlast URL API parameters should be added using * {@link #setAlignmentOption(BlastAlignmentParameterEnum, String)} * <p/> * Required parameters are {@code PROGRAM} and {@code DATABASE}, other parameters are optional * * @author Sylvain Foisy, Diploide BioIT * @author Gediminas Rimsa */ public class NCBIQBlastAlignmentProperties implements RemotePairwiseAlignmentProperties { private static final long serialVersionUID = 7158270364392309841L; private Map<BlastAlignmentParameterEnum, String> param = new HashMap<BlastAlignmentParameterEnum, String>(); /** * This method forwards to {@link #getAlignmentOption(BlastAlignmentParameterEnum)}. Consider using it instead. */ @Override public String getAlignmentOption(String key) { return getAlignmentOption(BlastAlignmentParameterEnum.valueOf(key)); } /** * This method forwards to {@link #setAlignmentOption(BlastAlignmentParameterEnum, String)}. Consider using it * instead. */ @Override public void setAlignementOption(String key, String val) { setAlignmentOption(BlastAlignmentParameterEnum.valueOf(key), val); } /** * Gets parameters, which are currently set */ @Override public Set<String> getAlignmentOptions() { Set<String> result = new HashSet<String>(); for (BlastAlignmentParameterEnum parameter : param.keySet()) { result.add(parameter.name()); } return result; } /** * Gets the value of specified parameter or {@code null} if it is not set. */ public String getAlignmentOption(BlastAlignmentParameterEnum key) { return param.get(key); } /** * Sets the value of specified parameter */ public void setAlignmentOption(BlastAlignmentParameterEnum key, String val) { param.put(key, val); } /** * Removes given parameter */ public void removeAlignmentOption(BlastAlignmentParameterEnum key) { param.remove(key); } /** * @return {@linkplain BlastProgramEnum} used for blast run */ public BlastProgramEnum getBlastProgram() { BlastProgramEnum program = BlastProgramEnum.valueOf(getAlignmentOption(PROGRAM)); boolean isMegablast = BlastProgramEnum.blastn == program && getAlignmentOption(MEGABLAST).equals("on"); return !isMegablast ? program : BlastProgramEnum.megablast; } /** * Sets the program to be used with blastall * * @param program : one of blastall programs */ public void setBlastProgram(BlastProgramEnum program) { if (BlastProgramEnum.megablast != program) { setAlignmentOption(PROGRAM, program.name()); removeAlignmentOption(MEGABLAST); } else { setAlignmentOption(PROGRAM, BlastProgramEnum.blastn.name()); setAlignmentOption(MEGABLAST, "on"); } } /** * @return name of database used with blastall */ public String getBlastDatabase() { return getAlignmentOption(DATABASE); } /* * TODO: update comment when URL is available: * A quite exhaustive list of the databases available for QBlast * requests can be found here: <p> http://< to_be_completed > <p> Blastall equivalent: -d */ /** * Sets the database to be used with blastall * <p> * A list of available databases can be acquired by calling {@link NCBIQBlastService#printRemoteBlastInfo()} * <p> * Blastall equivalent: -d * * @param db : a valid name to a NCBI blastable database */ public void setBlastDatabase(String database) { setAlignmentOption(DATABASE, database); } /** * @return double value of EXPECT parameter used for blast run */ public double getBlastExpect() { if (param.containsKey(EXPECT)) { return Double.parseDouble(getAlignmentOption(EXPECT)); } return 10; } /** * Sets the EXPECT parameter to be use with blastall * <p> * Example: if you want a EXPECT of 1e-10, pass {@code Double.parseDouble("1e-10")} as a parameter * <p> * Blastall equivalent: -e * * @param expect: a double value of EXPECT parameter */ public void setBlastExpect(double expect) { setAlignmentOption(EXPECT, Double.toString(expect)); } /** * Returns the value of the WORD_SIZE parameter used for this blast run * * @return int value of WORD_SIZE used by this search * @throws IllegalArgumentException when program type is not set and program type is not supported */ public int getBlastWordSize() { if (param.containsKey(WORD_SIZE)) { return Integer.parseInt(getAlignmentOption(WORD_SIZE)); } // return default word size value try { BlastProgramEnum programType = getBlastProgram(); switch (programType) { case blastn: return 11; case megablast: return 28; case blastp: case blastx: case tblastn: case tblastx: return 3; default: throw new UnsupportedOperationException("Blast program " + programType.name() + " is not supported."); } } catch (IllegalArgumentException e) { throw new IllegalArgumentException("Blast program " + getBlastProgram() + " is not supported.", e); } } /** * Sets the WORD_SIZE parameter to be use with blastall * <p> * <b>WARNING!!</b> At this point, the method does not verify the validity of your choice; for example, word size of * greater than 5 with blastp returns error messages from QBlast. Word size range depends on the algorithm chosen. * <p> * More at https://www.ncbi.nlm.nih.gov/staff/tao/URLAPI/new/node74.html * <p> * Blastall equivalent: -W * * @param word: an int used to set WORD_SIZE */ public void setBlastWordSize(int word) { setAlignmentOption(WORD_SIZE, Integer.toString(word)); } /** * Returns the value for the GAP_CREATION parameter (first half of GAPCOSTS parameter) * * @return an integer value for gap creation used by this search, -1 if not set or not a number */ public int getBlastGapCreation() { String gapCosts = getAlignmentOption(GAPCOSTS); try { String gapCreation = gapCosts.split("\\+")[0]; return Integer.parseInt(gapCreation); } catch (Exception e) { return -1; } } /** * Returns the value for the gap extension parameter (second half of GAPCOSTS parameter) * * @return an integer for the value for gap extension used by this search, -1 if not set or not a number */ public int getBlastGapExtension() { String gapCosts = getAlignmentOption(GAPCOSTS); try { String gapExtension = gapCosts.split("\\+")[1]; return Integer.parseInt(gapExtension); } catch (Exception e) { return -1; } } /** * Returns the actual string for the GAPCOSTS parameter which is used to build the URL * * @return the string representation of the GAPCOSTS parameter formatted for the URL */ public String getBlastGapCosts() { return getAlignmentOption(GAPCOSTS); } /** * Sets the GAPCOSTS parameter * * @param gapCreation integer to use as gap creation value * @param gapExtension integer to use as gap extension value */ public void setBlastGapCosts(int gapCreation, int gapExtension) { String gc = Integer.toString(gapCreation); String ge = Integer.toString(gapExtension); setAlignmentOption(GAPCOSTS, gc + "+" + ge); } /** * Returns the value of the specified substitution matrix * * @return matrix: the name of the specified substitution matrix */ public String getBlastMatrix() { return getAlignmentOption(MATRIX_NAME); } /** * Sets the value for the MATRIX parameter to use for blastall * <p> * Blastall equivalent: -M * * @param matrix : a String to use as gap creation value * @see BlastMatrixEnum */ public void setBlastMatrix(BlastMatrixEnum matrix) { setAlignmentOption(MATRIX_NAME, matrix.name()); boolean gapCostsSet = getBlastGapCreation() != -1 || getBlastGapExtension() != -1; if (!gapCostsSet) { /* * Setting default values for -G/-E if no other values have been set is necessary because, since BLOSUM62 is * default, the expected values are -G 11 -E 1. If your matrix choice is different, the request will fail, * implicitly expecting GAPCOSTS=11+1 */ switch (matrix) { case PAM30: setBlastGapCosts(9, 1); break; case PAM70: setBlastGapCosts(10, 1); break; case PAM250: setBlastGapCosts(14, 2); break; case BLOSUM45: setBlastGapCosts(15, 2); break; case BLOSUM50: setBlastGapCosts(13, 2); break; case BLOSUM80: case BLOSUM90: setBlastGapCosts(10, 1); break; case BLOSUM62: break; default: break; } } } /** * Sets the QUERY_FROM and QUERY_TO parameters to be use by blast. Do not use if you want to use the whole sequence.<br/> * Blastall equivalent: -L * * @param start QUERY_FROM parameter * @param end QUERY_TO parameter */ public void setBlastFromToPosition(int start, int end) { if (start >= end) { throw new IllegalArgumentException("Start index must be less than end index"); } setAlignmentOption(QUERY_FROM, String.valueOf(start)); setAlignmentOption(QUERY_TO, String.valueOf(end)); } /** * @return an integer value for the QUERY_FROM parameter * @see #setBlastFromToPosition(int, int) */ public int getBlastFromPosition() { return Integer.parseInt(getAlignmentOption(QUERY_FROM)); } /** * @return QUERY_TO parameter * @see #setBlastFromToPosition(int, int) */ public int getBlastToPosition() { return Integer.parseInt(getAlignmentOption(QUERY_TO)); } /** * This method is to be used if a request is to use non-default values at submission. Useful for the following * blastall parameters: * <ul> * <li>-r: integer to reward for match. Default = 1</li> * <li>-q: negative integer for penalty to allow mismatch. Default = -3</li> * <li>-y: dropoff for blast extensions in bits, using default if not specified. Default = 20 for blastn, 7 for all * others (except megablast for which it is not applicable).</li> * <li>-X: X dropoff value for gapped alignment, in bits. Default = 30 for blastn/megablast, 15 for all others.</li> * <li>-Z: final X dropoff value for gapped alignement, in bits. Default = 50 for blastn, 25 for all others (except * megablast for which it is not applicable)</li> * <li>-P: equals 0 for multiple hits 1-pass, 1 for single hit 1-pass. Does not apply to blastn ou megablast.</li> * <li>-A: multiple hits window size. Default = 0 (for single hit algorithm)</li> * <li>-I: number of database sequences to save hits for. Default = 500</li> * <li>-Y: effective length of the search space. Default = 0 (0 represents using the whole space)</li> * <li>-z: a real specifying the effective length of the database to use. Default = 0 (0 represents the real size)</li> * <li>-c: an integer representing pseudocount constant for PSI-BLAST. Default = 7</li> * <li>-F: any filtering directive</li> * </ul> * <p> * WARNING!! This method is still very much in flux and might not work as expected... * </p> * <p> * You have to be aware that at no moment is there any error checking on the use of these parameters by this class. * </p> * * @param advancedOptions : a String with any number of optional parameters with an associated value. */ public void setBlastAdvancedOptions(String advancedOptions) { // Escaping white spaces with + char to comply with QBlast specifications setAlignmentOption(OTHER_ADVANCED, advancedOptions.replaceAll(" ", "+")); } /** * @return the String with the advanced options */ public String getBlastAdvancedOptions() { return getAlignmentOption(OTHER_ADVANCED); } }