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);
00061   get_keyval (conf, "angleTol", theta_tol, 15.0);
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 colvar::alpha_angles::~alpha_angles()
00108 {
00109   while (theta.size() != 0) {
00110     delete theta.back();
00111     theta.pop_back();
00112   }
00113   while (hb.size() != 0) {
00114     delete hb.back();
00115     hb.pop_back();
00116   }
00117 }
00118 
00119 void colvar::alpha_angles::calc_value()
00120 {
00121   x.real_value = 0.0;
00122 
00123   if (theta.size()) {
00124 
00125     cvm::real const theta_norm = 
00126       (1.0-hb_coeff) / cvm::real (theta.size());
00127 
00128     for (size_t i = 0; i < theta.size(); i++) {
00129 
00130       (theta[i])->calc_value();
00131 
00132       cvm::real const t = ((theta[i])->value().real_value-theta_ref)/theta_tol;
00133       cvm::real const f = ( (1.0 - std::pow (t, (int) 2)) /
00134                             (1.0 - std::pow (t, (int) 4)) );
00135 
00136       x.real_value += theta_norm * f;
00137 
00138       if (cvm::debug())
00139         cvm::log ("Calpha-Calpha angle no. "+cvm::to_str (i+1)+" in \""+
00140                   this->name+"\" has a value of "+
00141                   (cvm::to_str ((theta[i])->value().real_value))+
00142                   " degrees, f = "+cvm::to_str (f)+".\n");
00143     }
00144   }
00145 
00146   if (hb.size()) {
00147 
00148     cvm::real const hb_norm =
00149       hb_coeff / cvm::real (hb.size());
00150 
00151     for (size_t i = 0; i < hb.size(); i++) {
00152       (hb[i])->calc_value();
00153       x.real_value += hb_norm * (hb[i])->value().real_value;
00154       if (cvm::debug())
00155         cvm::log ("Hydrogen bond no. "+cvm::to_str (i+1)+" in \""+
00156                   this->name+"\" has a value of "+
00157                   (cvm::to_str ((hb[i])->value().real_value))+".\n");
00158     }
00159   }
00160 }
00161 
00162 
00163 void colvar::alpha_angles::calc_gradients()
00164 {
00165   for (size_t i = 0; i < theta.size(); i++) 
00166     (theta[i])->calc_gradients();
00167 
00168   for (size_t i = 0; i < hb.size(); i++)
00169     (hb[i])->calc_gradients();
00170 }
00171 
00172 
00173 void colvar::alpha_angles::apply_force (colvarvalue const &force)
00174 {
00175 
00176   if (theta.size()) {
00177 
00178     cvm::real const theta_norm = 
00179       (1.0-hb_coeff) / cvm::real (theta.size());
00180     
00181     for (size_t i = 0; i < theta.size(); i++) {
00182 
00183       cvm::real const t = ((theta[i])->value().real_value-theta_ref)/theta_tol;
00184       cvm::real const f = ( (1.0 - std::pow (t, (int) 2)) /
00185                             (1.0 - std::pow (t, (int) 4)) );
00186 
00187       cvm::real const dfdt =
00188         1.0/(1.0 - std::pow (t, (int) 4)) * 
00189         ( (-2.0 * t) + (-1.0*f)*(-4.0 * std::pow (t, (int) 3)) );
00190 
00191       (theta[i])->apply_force (theta_norm * 
00192                                dfdt * (1.0/theta_tol) *
00193                                force.real_value );
00194     }
00195   }
00196 
00197   if (hb.size()) {
00198 
00199     cvm::real const hb_norm =
00200       hb_coeff / cvm::real (hb.size());
00201 
00202     for (size_t i = 0; i < hb.size(); i++) {
00203       (hb[i])->apply_force (0.5 * hb_norm * force.real_value);
00204     }
00205   }
00206 }
00207 
00208 
00210 // dihedral principal component
00212 
00213     // FIXME: this will not make collect_gradients work
00214     // because gradients in individual atom groups
00215     // are those of the sub-cvcs (angle, hb), not those
00216     // of this cvc (alpha)
00217     // This is true of all cvcs with sub-cvcs, and those
00218     // that do not calculate explicit gradients
00219     // SO: we need a flag giving the availability of 
00220     // atomic gradients
00221 colvar::dihedPC::dihedPC (std::string const &conf)
00222   : cvc (conf)
00223 {
00224   if (cvm::debug())
00225     cvm::log ("Initializing dihedral PC object.\n");
00226 
00227   function_type = "dihedPC";
00228   x.type (colvarvalue::type_scalar);
00229 
00230   std::string segment_id;
00231   get_keyval (conf, "psfSegID", segment_id, std::string ("MAIN"));
00232 
00233   std::vector<int> residues;
00234   {
00235     std::string residues_conf = "";
00236     key_lookup (conf, "residueRange", residues_conf);
00237     if (residues_conf.size()) {
00238       std::istringstream is (residues_conf);
00239       int initial, final;
00240       char dash;
00241       if ( (is >> initial) && (initial > 0) &&
00242            (is >> dash) && (dash == '-') &&
00243            (is >> final) && (final > 0) ) {
00244         for (int rnum = initial; rnum <= final; rnum++) {
00245           residues.push_back (rnum);
00246         }
00247       }
00248     } else {
00249       cvm::fatal_error ("Error: no residues defined in \"residueRange\".\n");
00250     }
00251   }
00252 
00253   if (residues.size() < 2) {
00254     cvm::fatal_error ("Error: dihedralPC requires at least two residues.\n");
00255   }
00256 
00257   std::string const &sid    = segment_id;
00258   std::vector<int> const &r = residues;
00259 
00260   std::string vecFileName;
00261   int         vecNumber;
00262   if (get_keyval (conf, "vectorFile", vecFileName, vecFileName)) {
00263     get_keyval (conf, "vectorNumber", vecNumber, 0); 
00264     if (vecNumber < 1)
00265       cvm::fatal_error ("A positive value of vectorNumber is required.");
00266 
00267     std::ifstream vecFile;
00268     vecFile.open (vecFileName.c_str());
00269     if (!vecFile.good())
00270       cvm::fatal_error ("Error opening dihedral PCA vector file " + vecFileName + " for reading");
00271 
00272     // TODO: adapt to different formats by setting this flag
00273     bool eigenvectors_as_columns = true;
00274 
00275     if (eigenvectors_as_columns) {
00276       // Carma-style dPCA file
00277       std::string line;
00278       cvm::real c;
00279       while (vecFile.good()) {
00280         getline(vecFile, line);
00281         if (line.length() < 2) break;
00282         std::istringstream ls (line);
00283         for (int i=0; i<vecNumber; i++) ls >> c;
00284         coeffs.push_back(c);
00285       }
00286     }
00287 /*  TODO Uncomment this when different formats are recognized
00288     else {
00289       // Eigenvectors as lines
00290       // Skip to the right line
00291       for (int i = 1; i<vecNumber; i++)
00292         vecFile.ignore(999999, '\n');
00293 
00294       if (!vecFile.good())
00295         cvm::fatal_error ("Error reading dihedral PCA vector file " + vecFileName);
00296 
00297       std::string line;
00298       getline(vecFile, line);
00299       std::istringstream ls (line);
00300       cvm::real c;
00301       while (ls.good()) {
00302         ls >> c;
00303         coeffs.push_back(c);
00304       }
00305     }
00306  */
00307     vecFile.close();
00308 
00309   } else {
00310     get_keyval (conf, "vector", coeffs, coeffs);
00311   }
00312 
00313   if ( coeffs.size() != 4 * (residues.size() - 1)) {
00314     cvm::fatal_error ("Error: wrong number of coefficients: " +
00315         cvm::to_str(coeffs.size()) + ". Expected " +
00316         cvm::to_str(4 * (residues.size() - 1)) +
00317         " (4 coeffs per residue, minus one residue).\n");
00318   }
00319 
00320   for (size_t i = 0; i < residues.size()-1; i++) {
00321     // Psi
00322     theta.push_back (new colvar::dihedral (cvm::atom (r[i  ], "N", sid),
00323                                            cvm::atom (r[i  ], "CA", sid),
00324                                            cvm::atom (r[i  ], "C", sid),
00325                                            cvm::atom (r[i+1], "N", sid)));
00326     // Phi (next res)
00327     theta.push_back (new colvar::dihedral (cvm::atom (r[i  ], "C", sid),
00328                                            cvm::atom (r[i+1], "N", sid),
00329                                            cvm::atom (r[i+1], "CA", sid),
00330                                            cvm::atom (r[i+1], "C", sid)));
00331   }
00332 
00333   if (cvm::debug())
00334     cvm::log ("Done initializing dihedPC object.\n");
00335 }
00336 
00337 
00338 colvar::dihedPC::dihedPC()
00339   : cvc ()
00340 {
00341   function_type = "dihedPC";
00342   x.type (colvarvalue::type_scalar);
00343 }
00344 
00345 
00346 colvar::dihedPC::~dihedPC()
00347 {
00348   while (theta.size() != 0) {
00349     delete theta.back();
00350     theta.pop_back();
00351   }
00352 }
00353 
00354 
00355 void colvar::dihedPC::calc_value()
00356 {
00357   x.real_value = 0.0;
00358   for (size_t i = 0; i < theta.size(); i++) {
00359     theta[i]->calc_value();
00360     cvm::real const t = (PI / 180.) * theta[i]->value().real_value;
00361     x.real_value += coeffs[2*i  ] * std::cos(t)
00362                   + coeffs[2*i+1] * std::sin(t);
00363   }
00364 }
00365 
00366 
00367 void colvar::dihedPC::calc_gradients()
00368 {
00369   for (size_t i = 0; i < theta.size(); i++) {
00370     theta[i]->calc_gradients();
00371   }
00372 }
00373 
00374 
00375 void colvar::dihedPC::apply_force (colvarvalue const &force)
00376 {
00377   for (size_t i = 0; i < theta.size(); i++) {
00378     cvm::real const t = (PI / 180.) * theta[i]->value().real_value;
00379     cvm::real const dcosdt = - (PI / 180.) * std::sin(t);
00380     cvm::real const dsindt =   (PI / 180.) * std::cos(t);
00381 
00382     theta[i]->apply_force((coeffs[2*i  ] * dcosdt +
00383                            coeffs[2*i+1] * dsindt) * force);
00384   }
00385 }

Generated on Fri May 25 04:07:13 2012 for NAMD by  doxygen 1.3.9.1