/* * Eoulsan development code * * This code may be freely distributed and modified under the * terms of the GNU Lesser General Public License version 2.1 or * later and CeCILL-C. This should be distributed with the code. * If you do not have a copy, see: * * http://www.gnu.org/licenses/lgpl-2.1.txt * http://www.cecill.info/licences/Licence_CeCILL-C_V1-en.txt * * Copyright for this code is held jointly by the Genomic platform * of the Institut de Biologie de l'École normale supérieure and * the individual authors. These should be listed in @author doc * comments. * * For more information on the Eoulsan project and its aims, * or to join the Eoulsan Google group, visit the home page * at: * * http://outils.genomique.biologie.ens.fr/eoulsan * */ package fr.ens.biologie.genomique.eoulsan.bio; /** * This class define a method to compute tm for oligonucletides. * @since 1.0 * @author Laurent Jourdren * @author Sebastian Bassi <sbassi@genesdigitales.com> */ public class MeltingTemp { // universal gas constant in Cal/degrees C*Mol private static final float R = 1.987f; /** * Returns DNA tm using nearest neighbor thermodynamics. This method is * adapted from bioPython MeltingTemp script. * @param s Sequence * @param dnac DNA concentration [nM] * @param saltc salt concentration [mM] * @return the tm of the sequence */ public static final float tmstalucDNA(final String s, final float dnac, final float saltc) { float dh = 0; // DeltaH. Enthalpy float ds = 0; // deltaS Entropy final String sup = s.toUpperCase(); final float[] tcRes = tercorrDNA(sup, ds, dh); // double vsTC = tcRes[0]; float vs = tcRes[0]; float vh = tcRes[1]; // DNA/DNA // Allawi and SantaLucia (1997). Biochemistry 36 : 10581-10594 vh = vh + (overcount(sup, "AA")) * 7.9f + (overcount(sup, "TT")) * 7.9f + (overcount(sup, "AT")) * 7.2f + (overcount(sup, "TA")) * 7.2f + (overcount(sup, "CA")) * 8.5f + (overcount(sup, "TG")) * 8.5f + (overcount(sup, "GT")) * 8.4f + (overcount(sup, "AC")) * 8.4f; vh = vh + (overcount(sup, "CT")) * 7.8f + (overcount(sup, "AG")) * 7.8f + (overcount(sup, "GA")) * 8.2f + (overcount(sup, "TC")) * 8.2f; vh = vh + (overcount(sup, "CG")) * 10.6f + (overcount(sup, "GC")) * 9.8f + (overcount(sup, "GG")) * 8f + (overcount(sup, "CC")) * 8f; vs = vs + (overcount(sup, "AA")) * 22.2f + (overcount(sup, "TT")) * 22.2f + (overcount(sup, "AT")) * 20.4f + (overcount(sup, "TA")) * 21.3f; vs = vs + (overcount(sup, "CA")) * 22.7f + (overcount(sup, "TG")) * 22.7f + (overcount(sup, "GT")) * 22.4f + (overcount(sup, "AC")) * 22.4f; vs = vs + (overcount(sup, "CT")) * 21.0f + (overcount(sup, "AG")) * 21.0f + (overcount(sup, "GA")) * 22.2f + (overcount(sup, "TC")) * 22.2f; vs = vs + (overcount(sup, "CG")) * 27.2f + (overcount(sup, "GC")) * 24.4f + (overcount(sup, "GG")) * 19.9f + (overcount(sup, "CC")) * 19.9f; ds = vs; dh = vh; ds = ds - 0.368f * (s.length() - 1f) * (float) Math.log(saltc / 1e3f); final float k = (dnac / 4.0f) * 1e-9f; return ((1000f * (-dh)) / (-ds + (R * ((float) Math.log(k))))) - 273.15f; } /** * Returns RNA tm using nearest neighbor thermodynamics. This method is * adapted from bioPython MeltingTemp script. * @param s Sequence * @param dnac DNA concentration [nM] * @param saltc salt concentration [mM] * @return the tm of the sequence */ public static final float tmstalucRNA(final String s, final int dnac, final int saltc) { float dh = 0; // DeltaH. Enthalpy float ds = 0; // deltaS Entropy final String sup = s.toUpperCase(); final float[] tcRes = tercorrRNA(sup, ds, dh); // double vsTC = tcRes[0]; float vs = tcRes[0]; float vh = tcRes[1]; // RNA/RNA hybridisation of Xia et al (1998) // Biochemistry 37: 14719-14735 vh = vh + (overcount(sup, "AA")) * 6.82f + (overcount(sup, "TT")) * 6.6f + (overcount(sup, "AT")) * 9.38f + (overcount(sup, "TA")) * 7.69f + (overcount(sup, "CA")) * 10.44f + (overcount(sup, "TG")) * 10.5f + (overcount(sup, "GT")) * 11.4f + (overcount(sup, "AC")) * 10.2f; vh = vh + (overcount(sup, "CT")) * 10.48f + (overcount(sup, "AG")) * 7.6f + (overcount(sup, "GA")) * 12.44f + (overcount(sup, "TC")) * 13.3f; vh = vh + (overcount(sup, "CG")) * 10.64f + (overcount(sup, "GC")) * 14.88f + (overcount(sup, "GG")) * 13.39f + (overcount(sup, "CC")) * 12.2f; vs = vs + (overcount(sup, "AA")) * 19.0f + (overcount(sup, "TT")) * 18.4f + (overcount(sup, "AT")) * 26.7f + (overcount(sup, "TA")) * 20.5f; vs = vs + (overcount(sup, "CA")) * 26.9f + (overcount(sup, "TG")) * 27.8f + (overcount(sup, "GT")) * 29.5f + (overcount(sup, "AC")) * 26.2f; vs = vs + (overcount(sup, "CT")) * 27.1f + (overcount(sup, "AG")) * 19.2f + (overcount(sup, "GA")) * 32.5f + (overcount(sup, "TC")) * 35.5f; vs = vs + (overcount(sup, "CG")) * 26.7f + (overcount(sup, "GC")) * 36.9f + (overcount(sup, "GG")) * 32.7f + (overcount(sup, "CC")) * 29.7f; ds = vs; dh = vh; ds = ds - 0.368f * (s.length() - 1f) * (float) Math.log(saltc / 1e3f); final float k = (dnac / 4.0f) * 1e-9f; return ((1000f * (-dh)) / (-ds + (R * ((float) Math.log(k))))) - 273.15f; } private static float[] tercorrDNA(final String stri, final float ds, final float dh) { float deltah = 0; float deltas = 0; // DNA/DNA // Allawi and SantaLucia (1997). Biochemistry 36 : 10581-10594 if (stri.startsWith("G") || stri.startsWith("C")) { deltah = deltah - 0.1f; deltas = deltas + 2.8f; } else if (stri.startsWith("A") || stri.startsWith("T")) { deltah = deltah - 2.3f; deltas = deltas - 4.1f; } if (stri.endsWith("G") || stri.endsWith("C")) { deltah = deltah - 0.1f; deltas = deltas + 2.8f; } else if (stri.endsWith("A") || stri.endsWith("T")) { deltah = deltah - 2.3f; deltas = deltas - 4.1f; } final float dhL = dh + deltah; final float dsL = ds + deltas; return new float[] {dsL, dhL}; } private static float[] tercorrRNA(final String stri, final float ds, final float dh) { float deltah = 0; float deltas = 0; // RNA final char firstChar = stri.charAt(0); if (firstChar == 'G' || firstChar == 'C') { deltah = deltah - 3.61f; deltas = deltas - 1.5f; } else if (firstChar == 'A' || firstChar == 'T' || firstChar == 'U') { deltah = deltah - 3.72f; deltas = deltas + 10.5f; } if (stri.endsWith("G") || stri.endsWith("C")) { deltah = deltah - 3.61f; deltas = deltas - 1.5f; } else if (stri.endsWith("A") || stri.endsWith("T") || stri.endsWith("U")) { deltah = deltah - 3.72f; deltas = deltas + 10.5f; } final float dhL = dh + deltah; final float dsL = ds + deltas; return new float[] {dsL, dhL}; } /** * Returns how many p are on st, works even for overlapping. */ private static int overcount(final String st, final String p) { int ocu = 0; int x = 0; while (true) { final int i = st.indexOf(p, x); if (i == -1) { break; } ocu = ocu + 1; x = i + 1; } return ocu; } }