Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Class Members | File Members

colvarcomp_protein.C

Go to the documentation of this file.
00001 #include <cmath>
00002 
00003 #include "colvarmodule.h"
00004 #include "colvarvalue.h"
00005 #include "colvarparse.h"
00006 #include "colvar.h"
00007 #include "colvarcomp.h"
00008 
00009 
00011 // alpha component
00013 
00014 colvar::alpha_angles::alpha_angles (std::string const &conf)
00015   : cvc (conf)
00016 {
00017   if (cvm::debug())
00018     cvm::log ("Initializing alpha_angles object.\n");
00019 
00020   function_type = "alpha_angles";
00021   x.type (colvarvalue::type_scalar);
00022 
00023   std::string segment_id;
00024   get_keyval (conf, "psfSegID", segment_id, std::string ("MAIN"));
00025 
00026   std::vector<int> residues;
00027   {
00028     std::string residues_conf = "";
00029     key_lookup (conf, "residueRange", residues_conf);
00030     if (residues_conf.size()) {
00031       std::istringstream is (residues_conf);
00032       int initial, final;
00033       char dash;
00034       if ( (is >> initial) && (initial > 0) &&
00035            (is >> dash) && (dash == '-') &&
00036            (is >> final) && (final > 0) ) {
00037         for (int rnum = initial; rnum <= final; rnum++) {
00038           residues.push_back (rnum);
00039         }
00040       }
00041     } else {
00042       cvm::fatal_error ("Error: no residues defined in \"residueRange\".\n");
00043     }
00044   }
00045 
00046   if (residues.size() < 5) {
00047     cvm::fatal_error ("Error: not enough residues defined in \"residueRange\".\n");
00048   }
00049 
00050   std::string const &sid    = segment_id;
00051   std::vector<int> const &r = residues;
00052 
00053 
00054   get_keyval (conf, "hBondCoeff", hb_coeff, 0.5);
00055   if ( (hb_coeff < 0.0) || (hb_coeff > 1.0) ) {
00056     cvm::fatal_error ("Error: hBondCoeff must be defined between 0 and 1.\n");
00057   }
00058 
00059 
00060   get_keyval (conf, "angleRef", theta_ref, 88.0, parse_silent);
00061   get_keyval (conf, "angleTol", theta_tol, 15.0, parse_silent);
00062 
00063   if (hb_coeff < 1.0) {
00064 
00065     for (size_t i = 0; i < residues.size()-2; i++) {
00066       theta.push_back (new colvar::angle (cvm::atom (r[i  ], "CA", sid),
00067                                           cvm::atom (r[i+1], "CA", sid),
00068                                           cvm::atom (r[i+2], "CA", sid)));
00069     }
00070 
00071   } else {
00072     cvm::log ("The hBondCoeff specified will disable the Calpha-Calpha-Calpha angle terms.\n");
00073   }
00074 
00075   {
00076     cvm::real r0;
00077     size_t en, ed;
00078     get_keyval (conf, "hBondCutoff",   r0, (3.3 * cvm::unit_angstrom()));
00079     get_keyval (conf, "hBondExpNumer", en, 6);
00080     get_keyval (conf, "hBondExpDenom", ed, 8);
00081 
00082     if (hb_coeff > 0.0) {
00083 
00084       for (size_t i = 0; i < residues.size()-4; i++) {
00085         hb.push_back (new colvar::h_bond (cvm::atom (r[i  ], "O",  sid),
00086                                           cvm::atom (r[i+4], "N",  sid),
00087                                           r0, en, ed));
00088       }
00089 
00090     } else {
00091       cvm::log ("The hBondCoeff specified will disable the hydrogen bond terms.\n");
00092     }
00093   }
00094 
00095   if (cvm::debug())
00096     cvm::log ("Done initializing alpha_angles object.\n");
00097 }
00098 
00099 
00100 colvar::alpha_angles::alpha_angles()
00101   : cvc ()
00102 {
00103   function_type = "alpha_angles";
00104   x.type (colvarvalue::type_scalar);
00105 }
00106 
00107 
00108 void colvar::alpha_angles::calc_value()
00109 {
00110   x.real_value = 0.0;
00111 
00112   if (theta.size()) {
00113 
00114     cvm::real const theta_norm = 
00115       (1.0-hb_coeff) / cvm::real (theta.size());
00116 
00117     for (size_t i = 0; i < theta.size(); i++) {
00118 
00119       (theta[i])->calc_value();
00120 
00121       cvm::real const t = ((theta[i])->value().real_value-theta_ref)/theta_tol;
00122       cvm::real const f = ( (1.0 - ::pow (t, (int) 2)) /
00123                             (1.0 - ::pow (t, (int) 4)) );
00124 
00125       x.real_value += theta_norm * f;
00126 
00127       if (cvm::debug())
00128         cvm::log ("Calpha-Calpha angle no. "+cvm::to_str (i+1)+" in \""+
00129                   this->name+"\" has a value of "+
00130                   (cvm::to_str ((theta[i])->value().real_value))+
00131                   " degrees, f = "+cvm::to_str (f)+".\n");
00132     }
00133   }
00134 
00135   if (hb.size()) {
00136 
00137     cvm::real const hb_norm =
00138       hb_coeff / cvm::real (hb.size());
00139 
00140     for (size_t i = 0; i < hb.size(); i++) {
00141       (hb[i])->calc_value();
00142       x.real_value += hb_norm * (hb[i])->value().real_value;
00143       if (cvm::debug())
00144         cvm::log ("Hydrogen bond no. "+cvm::to_str (i+1)+" in \""+
00145                   this->name+"\" has a value of "+
00146                   (cvm::to_str ((hb[i])->value().real_value))+".\n");
00147     }
00148   }
00149 }
00150 
00151 
00152 void colvar::alpha_angles::calc_gradients()
00153 {
00154   for (size_t i = 0; i < theta.size(); i++) 
00155     (theta[i])->calc_gradients();
00156 
00157   for (size_t i = 0; i < hb.size(); i++)
00158     (hb[i])->calc_gradients();
00159 }
00160 
00161 
00162 void colvar::alpha_angles::apply_force (colvarvalue const &force)
00163 {
00164 
00165   if (theta.size()) {
00166 
00167     cvm::real const theta_norm = 
00168       (1.0-hb_coeff) / cvm::real (theta.size());
00169     
00170     for (size_t i = 0; i < theta.size(); i++) {
00171 
00172       cvm::real const t = ((theta[i])->value().real_value-theta_ref)/theta_tol;
00173       cvm::real const f = ( (1.0 - ::pow (t, (int) 2)) /
00174                             (1.0 - ::pow (t, (int) 4)) );
00175 
00176       cvm::real const dfdt =
00177         1.0/(1.0 - ::pow (t, (int) 4)) * 
00178         ( (-2.0 * t) + (-1.0*f)*(-4.0 * ::pow (t, (int) 3)) );
00179 
00180       (theta[i])->apply_force (theta_norm * 
00181                                dfdt * (1.0/theta_tol) *
00182                                force.real_value );
00183     }
00184   }
00185 
00186   if (hb.size()) {
00187 
00188     cvm::real const hb_norm =
00189       hb_coeff / cvm::real (hb.size());
00190 
00191     for (size_t i = 0; i < hb.size(); i++) {
00192       (hb[i])->apply_force (0.5 * hb_norm * force.real_value);
00193     }
00194   }
00195 }
00196 
00197 
00198 
00200 // alphaDihedrals component
00202 
00203 
00204 // Restraint function for the dihedral
00205 inline cvm::real dih_func (cvm::real const &w,
00206                            cvm::real const &w0)
00207 {
00208   return 0.5*(1.0 + ::cos (w-w0));
00209 }
00210 
00211 // Derivative
00212 inline cvm::real dih_deriv (cvm::real const &w,
00213                             cvm::real const &w0)
00214 {
00215   return (-0.5 * ::sin (w-w0));
00216 }
00217 
00218 
00219 colvar::alpha_dihedrals::alpha_dihedrals (std::string const &conf)
00220   : cvc (conf)
00221 {
00222   if (cvm::debug())
00223     cvm::log ("Initializing alpha_dihedrals object.\n");
00224 
00225   function_type = "alpha_dihedrals";
00226   x.type (colvarvalue::type_scalar);
00227 
00228   std::vector<int> residues;
00229 
00230   get_keyval (conf, "residues", residues, std::vector<int>());
00231 
00232   phi.reserve (residues.size());
00233   psi.reserve (residues.size());
00234   hb.reserve  (residues.size());
00235 
00236   get_keyval (conf, "phi_ref", phi_ref, -57.8, parse_silent);
00237   get_keyval (conf, "psi_ref", psi_ref, -47.0, parse_silent);
00238 
00239   if (residues.size() < 5) {
00240     cvm::fatal_error ("Error: not enough residues defined.\n");
00241   }
00242 
00243   std::string segment_id;
00244   get_keyval (conf, "segment_id", segment_id, std::string ("MAIN"));
00245 
00246   std::string const &sid    = segment_id;
00247   std::vector<int> const &r = residues;
00248   for (size_t i = 0; i < residues.size()-1; i++) {
00249 
00250     phi.push_back (new colvar::dihedral (cvm::atom (r[i  ], "C",  sid),
00251                                          cvm::atom (r[i+1], "N",  sid),
00252                                          cvm::atom (r[i+1], "CA", sid),
00253                                          cvm::atom (r[i+1], "C",  sid)));
00254 
00255     psi.push_back (new colvar::dihedral (cvm::atom (r[i  ], "N",  sid),
00256                                          cvm::atom (r[i  ], "CA", sid),
00257                                          cvm::atom (r[i  ], "C",  sid),
00258                                          cvm::atom (r[i+1], "N",  sid)));
00259   }
00260 
00261   for (size_t i = 0; i < residues.size()-4; i++) {
00262     hb.push_back (new colvar::h_bond (cvm::atom (r[i  ], "O",  sid),
00263                                       cvm::atom (r[i+4], "N",  sid),
00264                                       3.3 * cvm::unit_angstrom(),
00265                                       6, 8));
00266   }
00267 
00268   if (cvm::debug())
00269     cvm::log ("Done initializing alpha_dihedrals object.\n");
00270 }
00271 
00272 
00273 colvar::alpha_dihedrals::alpha_dihedrals()
00274   : cvc ()
00275 {
00276   function_type = "alpha_dihedrals";
00277   x.type (colvarvalue::type_scalar);
00278 }
00279 
00280 
00281 void colvar::alpha_dihedrals::calc_value()
00282 {
00283   x.real_value = 0.0;
00284 
00285   for (size_t i = 0; i < phi.size(); i++) {
00286 
00287     (phi[i])->calc_value();
00288     (psi[i])->calc_value();
00289 
00290     x.real_value += 0.5 *
00291       dih_func (((phi[i])->value()).real_value, phi_ref) *
00292       dih_func (((psi[i])->value()).real_value, psi_ref);
00293 
00294     if (cvm::debug())
00295       cvm::log ("Phi dihedral no. "+cvm::to_str (i+1)+" in \""+
00296                 this->name+"\" has a value of "+
00297                 (cvm::to_str ((phi[i])->value().real_value))+
00298                 " degrees.\n");
00299 
00300     if (cvm::debug())
00301       cvm::log ("Psi dihedral no. "+cvm::to_str (i+1)+" in \""+
00302                 this->name+"\" has a value of "+
00303                 (cvm::to_str ((psi[i])->value().real_value))+
00304                 " degrees.\n");
00305   }
00306 
00307   for (size_t i = 0; i < hb.size(); i++) {
00308     (hb[i])->calc_value();
00309     x.real_value += 0.5 * (hb[i])->value().real_value;
00310     if (cvm::debug())
00311       cvm::log ("Hydrogen bond no. "+cvm::to_str (i+1)+" in \""+
00312                 this->name+"\" has a value of "+
00313                 (cvm::to_str ((hb[i])->value().real_value))+".\n");
00314   }
00315 }
00316 
00317 
00318 void colvar::alpha_dihedrals::calc_gradients()
00319 {
00320   for (size_t i = 0; i < phi.size(); i++) {
00321     (phi[i])->calc_gradients();
00322     (psi[i])->calc_gradients();
00323   }
00324   for (size_t i = 0; i < hb.size(); i++) {
00325     (hb[i])->calc_gradients();
00326   }
00327 }
00328 
00329 
00330 void colvar::alpha_dihedrals::apply_force (colvarvalue const &force)
00331 {
00332   for (size_t i = 0; i < phi.size(); i++) {
00333 
00334     (phi[i])->apply_force ( 0.5 *
00335                             dih_func (((psi[i])->value()).real_value, psi_ref) *
00336                             dih_deriv (((phi[i])->value()).real_value, phi_ref) *
00337                             force.real_value );
00338 
00339     (psi[i])->apply_force ( 0.5 *
00340                             dih_func (((phi[i])->value()).real_value, phi_ref) *
00341                             dih_deriv (((psi[i])->value()).real_value, psi_ref) *
00342                             force.real_value );
00343   }
00344 
00345   for (size_t i = 0; i < hb.size(); i++) {
00346     (hb[i])->apply_force (0.5 * force.real_value);
00347   }
00348 }
00349 
00350 
00351 

Generated on Sat Nov 7 04:07:46 2009 for NAMD by  doxygen 1.3.9.1