Exemplo n.º 1
0
/* Calculate the melting temperature of oligo s.  See
   oligotm.h for documentation of arguments.
*/
double 
oligotm(const  char *s,
     double DNA_nM,
     double K_mM,
     double divalent_conc,
     double dntp_conc,
     tm_method_type  tm_method,
     salt_correction_type salt_corrections)
{
   register int dh = 0, ds = 0;
  register char c;
  double delta_H, delta_S;
  double Tm; /* Melting temperature */
  double correction;
  int len, sym;
  const char* d = s;
   if(divalent_to_monovalent(divalent_conc, dntp_conc) == OLIGOTM_ERROR)
     return OLIGOTM_ERROR;
   
  /** K_mM = K_mM + divalent_to_monovalent(divalent_conc, dntp_conc); **/
  if (tm_method != breslauer_auto
      && tm_method != santalucia_auto)
    return OLIGOTM_ERROR;
  if (salt_corrections != schildkraut
      && salt_corrections != santalucia
      && salt_corrections != owczarzy)
    return OLIGOTM_ERROR;

  len = (strlen(s)-1);

  sym = symmetry(s); /*Add symmetry correction if seq is symmetrical*/
  if( tm_method == breslauer_auto ) {
    ds=108;
  }
  else {
    if(sym == 1) {
      ds+=14;
    }
	 
    /** Terminal AT penalty **/
      
    if(strncmp("A", s, 1)==0
       || strncmp("T", s, 1)==0)  {
      ds += -41;
      dh += -23;
    } else if (strncmp("C", s, 1)==0 
	       || strncmp("G", s, 1)==0) {
      ds += 28;
      dh += -1;
    }
    s+=len;
    if(strncmp("T", s, 1)==0 
       || strncmp("A", s, 1)==0) {
      ds += -41;
      dh += -23;
    } else if (strncmp("C", s, 1)==0 
	       || strncmp("G", s, 1)==0) {
      ds += 28;
      dh += -1;
    }
    s-=len;
  }
  /* Use a finite-state machine (DFA) to calucluate dh and ds for s. */
  c = *s; s++;
  if (tm_method == breslauer_auto) {
    if (c == 'A') goto A_STATE;
    else if (c == 'G') goto G_STATE;
    else if (c == 'T') goto T_STATE;
    else if (c == 'C') goto C_STATE;
    else if (c == 'N') goto N_STATE;
    else goto ERROR;
    STATE(A);
    STATE(T);
    STATE(G);
    STATE(C);
    STATE(N);
  } else {
    if (c == 'A') goto A_STATE2;
    else if (c == 'G') goto G_STATE2;
    else if (c == 'T') goto T_STATE2;
    else if (c == 'C') goto C_STATE2;
    else if (c == 'N') goto N_STATE2;
    else goto ERROR;
    STATE2(A);
    STATE2(T);
    STATE2(G);
    STATE2(C);
    STATE2(N);
  }
   
   
 DONE:  /* dh and ds are now computed for the given sequence. */
  delta_H = dh * -100.0;  /* 
			   * Nearest-neighbor thermodynamic values for dh
			   * are given in 100 cal/mol of interaction.
			   */
  delta_S = ds * -0.1;     /*
			    * Nearest-neighbor thermodynamic values for ds
			    * are in in .1 cal/K per mol of interaction.
			    */
  Tm=0;  /* Melting temperature */
  len=len+1;

   /**********************************************/
  if (salt_corrections == schildkraut) {
     K_mM = K_mM + divalent_to_monovalent(divalent_conc, dntp_conc);
     correction = 16.6 * log10(K_mM/1000.0) - T_KELVIN;
     Tm = delta_H / (delta_S + 1.987 * log(DNA_nM/4000000000.0)) + correction;
  } else if (salt_corrections== santalucia) {
    K_mM = K_mM + divalent_to_monovalent(divalent_conc, dntp_conc);
    delta_S = delta_S + 0.368 * (len - 1) * log(K_mM / 1000.0 );
    if(sym == 1) { /* primer is symmetrical */
      /* Equation A */
      Tm = delta_H / (delta_S + 1.987 * log(DNA_nM/1000000000.0)) - T_KELVIN;
    } else {
      /* Equation B */
      Tm = delta_H / (delta_S + 1.987 * log(DNA_nM/4000000000.0)) - T_KELVIN;
    }      
  } else if (salt_corrections == owczarzy) {
     double gcPercent=0;
     double free_divalent; /* conc of divalent cations minus dNTP conc */
     int i;
     for(i = 0; i <= len && d != NULL && d != '\0';) {
	if(*d == 'C' || *d == 'G') {
	   gcPercent++;
	}  
	d++;
	i++;
     }
     gcPercent = (double)gcPercent/((double)len);
     /**** BEGIN: UPDATED SALT BY OWCZARZY *****/
      /* different salt corrections for monovalent (Owczarzy et al.,2004) 
      and divalent cations (Owczarzy et al.,2008)
      */
     /* competition bw magnesium and monovalent cations, see Owczarzy et al., 2008 Figure 9 and Equation 16 */
     
     static const double crossover_point = 0.22; /* depending on the value of div_monov_ratio respect
					     to value of crossover_point Eq 16 (divalent corr, Owczarzy et al., 2008)
					     or Eq 22 (monovalent corr, Owczarzy et al., 2004) should be used */
     double div_monov_ratio;
     if(dntp_conc >= divalent_conc) {
	free_divalent = 0.00000000001; /* to not to get log(0) */
     } else {
	free_divalent = (divalent_conc - dntp_conc)/1000.0;
     }
     static double a = 0,b = 0,c = 0,d = 0,e = 0,f = 0,g = 0;
      if(K_mM==0) {
	 div_monov_ratio = 6.0;
      } else {
	 div_monov_ratio = (sqrt(free_divalent))/(K_mM/1000); /* if conc of monov cations is provided
								    a ratio is calculated to further calculate
								    the _correct_ correction */
      }
     if (div_monov_ratio < crossover_point) {
	/* use only monovalent salt correction, Eq 22 (Owczarzy et al., 2004) */
	correction
	  = (((4.29 * gcPercent) - 3.95) * Pow(10,-5) * log(K_mM / 1000.0))
	  + (9.40 * Pow(10, -6) * (pow(log(K_mM / 1000.0), 2)));
     } else {
	/* magnesium effects are dominant, Eq 16 (Owczarzy et al., 2008) is used */
		 b = -9.11 * Pow(10, -6);
		 c = 6.26 * Pow(10, -5);
		 e = -4.82 * Pow(10, -4);
		 f = 5.25 * Pow(10, -4);
		 a = 3.92 * Pow(10, -5);
		 d = 1.42 * Pow(10, -5);
		 g = 8.31 * Pow(10, -5);
	if(div_monov_ratio < 6.0) {
	   /* in particular ratio of conc of monov and div cations
	    *             some parameters of Eq 16 must be corrected (a,d,g) */
		a = 3.92 * Pow(10, -5) * (0.843 - (0.352 * sqrt(K_mM / 1000.0) * log(K_mM / 1000.0)));
		d = 1.42 * Pow(10, -5) * (1.279 - 4.03 * Pow(10, -3) * log(K_mM / 1000.0) - 8.03 * Pow(10, -3) * pow(log(K_mM / 1000.0), 2));
		g = 8.31 * Pow(10, -5) * (0.486 - 0.258 * log(K_mM / 1000.0) + 5.25 * Pow(10, -3) * pow(log(K_mM / 1000.0), 3));
	}
	
	correction = a + (b * log(free_divalent))
	  + gcPercent * (c + (d * log(free_divalent)))
	    + (1/(2 * (len - 1))) * (e + (f * log(free_divalent))
				     + g * (pow((log(free_divalent)),2)));
     }
     /**** END: UPDATED SALT BY OWCZARZY *****/
     if (sym == 1) {
	   /* primer is symmetrical */
	/* Equation A */
	Tm = 1/((1/(delta_H 
		    /
		    (delta_S + 1.9872 * log(DNA_nM/1000000000.0)))) + correction) - T_KELVIN;
     } else {
	/* Equation B */
	Tm = 1/((1/(delta_H
		    /
		    (delta_S + 1.9872 * log(DNA_nM/4000000000.0)))) + correction) - T_KELVIN;
     } 
  } /* END else if (salt_corrections == owczarzy) { */
   
   
   /***************************************/
   return Tm;
ERROR:  /* 
	  * length of s was less than 2 or there was an illegal character in
	  * s.
	  */
  return OLIGOTM_ERROR;
}
Exemplo n.º 2
0
double 
oligodg(const char *s,      /* The sequence. */
    int tm_method) 
{
   register int dg = 0;
   register char c;

  if (tm_method != breslauer_auto
      && tm_method != santalucia_auto)
    return OLIGOTM_ERROR;

   /* Use a finite-state machine (DFA) to calucluate dg s. */
   c = *s; s++;
   if(tm_method != breslauer_auto) {      
      dg=-1960; /* Initial dG */
      if(c == 'A' || c == 'T')  {
	 dg += -50; /* terminal AT penalty */
      }
      if (c == 'A') goto A_STATE2;
      else if (c == 'G') goto G_STATE2;
      else if (c == 'T') goto T_STATE2;
      else if (c == 'C') goto C_STATE2;
      else if (c == 'N') goto N_STATE2;
      else goto ERROR;
      STATE2(A);
      STATE2(T);
      STATE2(G);
      STATE2(C);
      STATE2(N);
     } else {
    if (c == 'A') goto A_STATE;
    else if (c == 'G') goto G_STATE;
    else if (c == 'T') goto T_STATE;
    else if (c == 'C') goto C_STATE;
    else if (c == 'N') goto N_STATE;
    else goto ERROR;
    STATE(A);
    STATE(T);
    STATE(G);
    STATE(C);
    STATE(N);

     }
DONE:  /* dg is now computed for the given sequence. */
   if(tm_method != breslauer_auto) {
      int sym;
      --s; --s; c = *s;
      if(c == 'A' || c == 'T')  {
	 dg += -50; /* terminal AT penalty */
      }
      sym = symmetry(s);
      if(sym==1)   {
	 dg +=-430; /* symmetry correction for dG */
      }
   }
   return dg / 1000.0;

 ERROR:  /* 
	  * length of s was less than 2 or there was an illegal character in
	  * s.
	  */
    return OLIGOTM_ERROR;
}
Exemplo n.º 3
0
/* Calculate the melting temperature of oligo s.  See
   oligotm.h for documentation of arguments.
*/
double 
oligotm(const  char *s,
     double DNA_nM,
     double K_mM,
     double divalent_conc,
     double dntp_conc,
     tm_method_type  tm_method,
     salt_correction_type salt_corrections)
{
  register int dh = 0, ds = 0;
  register char c;
  double delta_H, delta_S;
  double Tm; /* Melting temperature */
  double correction;
  int len, sym;
  const char* d = s;
   if(divalent_to_monovalent(divalent_conc, dntp_conc) == OLIGOTM_ERROR)
     return OLIGOTM_ERROR;
   
   K_mM = K_mM + divalent_to_monovalent(divalent_conc, dntp_conc);
  if (tm_method != breslauer_auto
      && tm_method != santalucia_auto)
    return OLIGOTM_ERROR;
  if (salt_corrections != schildkraut
      && salt_corrections != santalucia
      && salt_corrections != owczarzy)
    return OLIGOTM_ERROR;

  len = (strlen(s)-1);

  sym = symmetry(s); /*Add symmetry correction if seq is symmetrical*/
  if( tm_method == breslauer_auto ) {
    ds=108;
  }
  else {
    if(sym == 1) {
      ds+=14;
    }
	 
    /** Terminal AT penalty **/
      
    if(strncmp("A", s, 1)==0
       || strncmp("T", s, 1)==0)  {
      ds += -41;
      dh += -23;
    } else if (strncmp("C", s, 1)==0 
	       || strncmp("G", s, 1)==0) {
      ds += 28;
      dh += -1;
    }
    s+=len;
    if(strncmp("T", s, 1)==0 
       || strncmp("A", s, 1)==0) {
      ds += -41;
      dh += -23;
    } else if (strncmp("C", s, 1)==0 
	       || strncmp("G", s, 1)==0) {
      ds += 28;
      dh += -1;
    }
    s-=len;
  }
  /* Use a finite-state machine (DFA) to calucluate dh and ds for s. */
  c = *s; s++;
  if (tm_method == breslauer_auto) {
    if (c == 'A') goto A_STATE;
    else if (c == 'G') goto G_STATE;
    else if (c == 'T') goto T_STATE;
    else if (c == 'C') goto C_STATE;
    else if (c == 'N') goto N_STATE;
    else goto ERROR;
    STATE(A);
    STATE(T);
    STATE(G);
    STATE(C);
    STATE(N);
  } else {
    if (c == 'A') goto A_STATE2;
    else if (c == 'G') goto G_STATE2;
    else if (c == 'T') goto T_STATE2;
    else if (c == 'C') goto C_STATE2;
    else if (c == 'N') goto N_STATE2;
    else goto ERROR;
    STATE2(A);
    STATE2(T);
    STATE2(G);
    STATE2(C);
    STATE2(N);
  }
   
   
 DONE:  /* dh and ds are now computed for the given sequence. */
  delta_H = dh * -100.0;  /* 
			   * Nearest-neighbor thermodynamic values for dh
			   * are given in 100 cal/mol of interaction.
			   */
  delta_S = ds * -0.1;     /*
			    * Nearest-neighbor thermodynamic values for ds
			    * are in in .1 cal/K per mol of interaction.
			    */
  Tm=0;  /* Melting temperature */
  len=len+1;
  if (salt_corrections == schildkraut) {
    double correction=- 273.15 + 16.6 * log10(K_mM/1000.0);
    Tm = delta_H / (delta_S + 1.987 * log(DNA_nM/4000000000.0)) + correction;
  } else if (salt_corrections== santalucia) {
    delta_S = delta_S + 0.368 * (len - 1) * log(K_mM / 1000.0 );
    if(sym == 1) { /* primer is symmetrical */
      /* Equation A */
      Tm = delta_H / (delta_S + 1.987 * log(DNA_nM/1000000000.0)) - 273.15;
    } else {
      /* Equation B */
      Tm = delta_H / (delta_S + 1.987 * log(DNA_nM/4000000000.0)) - 273.15;
    }      
  } else if (salt_corrections == owczarzy) {
    double gcPercent=0;
    int i;
    for(i=0; i<=len && d != NULL && d != '\0';) {
      if(*d == 'C' || *d == 'G') {
	gcPercent++;
      }
      d++; 
      i++;
    }      
    gcPercent = (double)gcPercent/((double)len);

    /* double */ correction 
      = (((4.29 * gcPercent) - 3.95) * pow(10,-5) * log(K_mM / 1000.0))
      + (9.40 * pow(10,-6) * (pow(log(K_mM / 1000.0),2)));

    if (sym == 1) { /* primer is symmetrical */
      /* Equation A */
      Tm 
	= (1/((1/(delta_H 
		  / 
		  (delta_S + 1.9872 * log(DNA_nM/1000000000.0)))) + correction))
	- 273.15;
    } else {
      /* Equation B */
      Tm 
	= (1/((1/(delta_H 
		  / 
		  (delta_S + 1.9872 * log(DNA_nM/4000000000.0)))) + correction))
	- 273.15;
    }
            
  }
  return Tm;
 ERROR:  /* 
	  * length of s was less than 2 or there was an illegal character in
	  * s.
	  */
  return OLIGOTM_ERROR;
}