Line data Source code
1 : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 : Copyright (c) 2016-2019 The plumed team
3 : (see the PEOPLE file at the root of the distribution for a list of names)
4 :
5 : See http://www.plumed.org for more information.
6 :
7 : This file is part of plumed, version 2.
8 :
9 : plumed is free software: you can redistribute it and/or modify
10 : it under the terms of the GNU Lesser General Public License as published by
11 : the Free Software Foundation, either version 3 of the License, or
12 : (at your option) any later version.
13 :
14 : plumed is distributed in the hope that it will be useful,
15 : but WITHOUT ANY WARRANTY; without even the implied warranty of
16 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 : GNU Lesser General Public License for more details.
18 :
19 : You should have received a copy of the GNU Lesser General Public License
20 : along with plumed. If not, see <http://www.gnu.org/licenses/>.
21 : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
22 :
23 : /* This class was originally written by Thomas Loehr */
24 :
25 : #include "Colvar.h"
26 : #include "ActionRegister.h"
27 : #include "core/ActionSet.h"
28 : #include "core/PlumedMain.h"
29 : #include "core/SetupMolInfo.h"
30 : #include "tools/OpenMP.h"
31 : #include <initializer_list>
32 :
33 : #define INV_PI_SQRT_PI 0.179587122
34 : #define KCAL_TO_KJ 4.184
35 : #define ANG_TO_NM 0.1
36 : #define ANG3_TO_NM3 0.001
37 :
38 : using namespace std;
39 :
40 : namespace PLMD {
41 : namespace colvar {
42 :
43 : //+PLUMEDOC COLVAR EEFSOLV
44 : /*
45 : Calculates EEF1 solvation free energy for a group of atoms.
46 :
47 : EEF1 is a solvent-accessible surface area based model, where the free energy of solvation is computed using a pairwise interaction term for non-hydrogen atoms:
48 : \f[
49 : \Delta G^\mathrm{solv}_i = \Delta G^\mathrm{ref}_i - \sum_{j \neq i} f_i(r_{ij}) V_j
50 : \f]
51 : where \f$\Delta G^\mathrm{solv}_i\f$ is the free energy of solvation, \f$\Delta G^\mathrm{ref}_i\f$ is the reference solvation free energy, \f$V_j\f$ is the volume of atom \f$j\f$ and
52 : \f[
53 : f_i(r) 4\pi r^2 = \frac{2}{\sqrt{\pi}} \frac{\Delta G^\mathrm{free}_i}{\lambda_i} \exp\left\{ - \frac{(r-R_i)^2}{\lambda^2_i}\right\}
54 : \f]
55 : where \f$\Delta G^\mathrm{free}_i\f$ is the solvation free energy of the isolated group, \f$\lambda_i\f$ is the correlation length equal to the width of the first solvation shell and \f$R_i\f$ is the van der Waals radius of atom \f$i\f$.
56 :
57 : The output from this collective variable, the free energy of solvation, can be used with the \ref BIASVALUE keyword to provide implicit solvation to a system. All parameters are designed to be used with a modified CHARMM36 force field. It takes only non-hydrogen atoms as input, these can be conveniently specified using the \ref GROUP action with the NDX_GROUP parameter. To speed up the calculation, EEFSOLV internally uses a neighbor list with a cutoff dependent on the type of atom (maximum of 1.95 nm). This cutoff can be extended further by using the NL_BUFFER keyword.
58 :
59 : \par Examples
60 :
61 : \plumedfile
62 : #SETTINGS MOLFILE=regtest/basic/rt32/helix.pdb
63 : MOLINFO MOLTYPE=protein STRUCTURE=peptide.pdb
64 : WHOLEMOLECULES ENTITY0=1-111
65 :
66 : # This allows us to select only non-hydrogen atoms
67 : protein-h: GROUP NDX_FILE=index.ndx NDX_GROUP=Protein-H
68 :
69 : # We extend the cutoff by 0.1 nm and update the neighbor list every 40 steps
70 : solv: EEFSOLV ATOMS=protein-h NL_STRIDE=40 NL_BUFFER=0.1
71 :
72 : # Here we actually add our calculated energy back to the potential
73 : bias: BIASVALUE ARG=solv
74 :
75 : PRINT ARG=solv FILE=SOLV
76 : \endplumedfile
77 :
78 : */
79 : //+ENDPLUMEDOC
80 :
81 6 : class EEFSolv : public Colvar {
82 : private:
83 : bool pbc;
84 : bool serial;
85 : double delta_g_ref;
86 : double nl_buffer;
87 : unsigned nl_stride;
88 : unsigned nl_update;
89 : vector<vector<unsigned> > nl;
90 : vector<vector<bool> > nlexpo;
91 : vector<vector<double> > parameter;
92 : void setupConstants(const vector<AtomNumber> &atoms, vector<vector<double> > ¶meter, bool tcorr);
93 : map<string, map<string, string> > setupTypeMap();
94 : map<string, vector<double> > setupValueMap();
95 : void update_neighb();
96 :
97 : public:
98 : static void registerKeywords(Keywords& keys);
99 : explicit EEFSolv(const ActionOptions&);
100 : void calculate() override;
101 : };
102 :
103 7838 : PLUMED_REGISTER_ACTION(EEFSolv,"EEFSOLV")
104 :
105 4 : void EEFSolv::registerKeywords(Keywords& keys) {
106 4 : Colvar::registerKeywords(keys);
107 16 : keys.add("atoms", "ATOMS", "The atoms to be included in the calculation, e.g. the whole protein.");
108 20 : keys.add("compulsory", "NL_BUFFER", "0.1", "The buffer to the intrinsic cutoff used when calculating pairwise interactions.");
109 20 : keys.add("compulsory", "NL_STRIDE", "40", "The frequency with which the neighbor list is updated.");
110 12 : keys.addFlag("SERIAL",false,"Perform the calculation in serial - for debug purpose");
111 12 : keys.addFlag("TEMP_CORRECTION", false, "Correct free energy of solvation constants for temperatures different from 298.15 K");
112 4 : }
113 :
114 3 : EEFSolv::EEFSolv(const ActionOptions&ao):
115 : PLUMED_COLVAR_INIT(ao),
116 : pbc(true),
117 : serial(false),
118 : delta_g_ref(0.),
119 : nl_buffer(0.1),
120 : nl_stride(40),
121 3 : nl_update(0)
122 : {
123 : vector<AtomNumber> atoms;
124 6 : parseAtomList("ATOMS", atoms);
125 : const unsigned size = atoms.size();
126 3 : bool tcorr = false;
127 6 : parseFlag("TEMP_CORRECTION", tcorr);
128 6 : parse("NL_BUFFER", nl_buffer);
129 6 : parse("NL_STRIDE", nl_stride);
130 :
131 3 : bool nopbc = !pbc;
132 6 : parseFlag("NOPBC", nopbc);
133 3 : pbc = !nopbc;
134 :
135 6 : parseFlag("SERIAL",serial);
136 :
137 3 : checkRead();
138 :
139 9 : log << " Bibliography " << plumed.cite("Lazaridis T, Karplus M, Proteins Struct. Funct. Genet. 35, 133 (1999)"); log << "\n";
140 :
141 3 : nl.resize(size);
142 3 : nlexpo.resize(size);
143 6 : parameter.resize(size, vector<double>(4, 0));
144 3 : setupConstants(atoms, parameter, tcorr);
145 :
146 3 : addValueWithDerivatives();
147 3 : setNotPeriodic();
148 3 : requestAtoms(atoms);
149 3 : }
150 :
151 18 : void EEFSolv::update_neighb() {
152 : const double lower_c2 = 0.24 * 0.24; // this is the cut-off for bonded atoms
153 : const unsigned size = getNumberOfAtoms();
154 :
155 1116 : for (unsigned i=0; i<size; i++) {
156 1080 : nl[i].clear();
157 : nlexpo[i].clear();
158 2160 : const Vector posi = getPosition(i);
159 : // Loop through neighboring atoms, add the ones below cutoff
160 32940 : for (unsigned j=i+1; j<size; j++) {
161 37314 : if(parameter[i][1]==0&¶meter[j][1]==0) continue;
162 62100 : const double d2 = delta(posi, getPosition(j)).modulo2();
163 31050 : if (d2 < lower_c2 && j < i+14) {
164 : // crude approximation for i-i+1/2 interactions,
165 : // we want to exclude atoms separated by less than three bonds
166 : continue;
167 : }
168 : // We choose the maximum lambda value and use a more conservative cutoff
169 29433 : double mlambda = 1./parameter[i][2];
170 58866 : if (1./parameter[j][2] > mlambda) mlambda = 1./parameter[j][2];
171 29433 : const double c2 = (2. * mlambda + nl_buffer) * (2. * mlambda + nl_buffer);
172 29433 : if (d2 < c2 ) {
173 15213 : nl[i].push_back(j);
174 30426 : if(parameter[i][2] == parameter[j][2] && parameter[i][3] == parameter[j][3]) {
175 3141 : nlexpo[i].push_back(true);
176 12072 : } else nlexpo[i].push_back(false);
177 : }
178 : }
179 : }
180 18 : }
181 :
182 18 : void EEFSolv::calculate() {
183 18 : if(pbc) makeWhole();
184 18 : if(getExchangeStep()) nl_update = 0;
185 18 : if(nl_update==0) update_neighb();
186 :
187 : const unsigned size=getNumberOfAtoms();
188 18 : double bias = 0.0;
189 18 : vector<Vector> deriv(size, Vector(0,0,0));
190 :
191 : unsigned stride;
192 : unsigned rank;
193 18 : if(serial) {
194 : stride=1;
195 : rank=0;
196 : } else {
197 18 : stride=comm.Get_size();
198 18 : rank=comm.Get_rank();
199 : }
200 :
201 18 : unsigned nt=OpenMP::getNumThreads();
202 18 : if(nt*stride*10>size) nt=1;
203 :
204 53 : #pragma omp parallel num_threads(nt)
205 : {
206 35 : vector<Vector> deriv_omp(size, Vector(0,0,0));
207 36 : #pragma omp for reduction(+:bias) nowait
208 : for (unsigned i=rank; i<size; i+=stride) {
209 1438 : const Vector posi = getPosition(i);
210 : double fedensity = 0.0;
211 719 : Vector deriv_i;
212 1470 : const double vdw_volume_i = parameter[i][0];
213 735 : const double delta_g_free_i = parameter[i][1];
214 735 : const double inv_lambda_i = parameter[i][2];
215 735 : const double vdw_radius_i = parameter[i][3];
216 :
217 : // The pairwise interactions are unsymmetric, but we can get away with calculating the distance only once
218 21670 : for (unsigned i_nl=0; i_nl<nl[i].size(); i_nl++) {
219 10116 : const unsigned j = nl[i][i_nl];
220 20232 : const double vdw_volume_j = parameter[j][0];
221 10116 : const double delta_g_free_j = parameter[j][1];
222 10116 : const double inv_lambda_j = parameter[j][2];
223 10116 : const double vdw_radius_j = parameter[j][3];
224 :
225 20232 : const Vector dist = delta(posi, getPosition(j));
226 10137 : const double rij = dist.modulo();
227 10099 : const double inv_rij = 1.0 / rij;
228 10099 : const double inv_rij2 = inv_rij * inv_rij;
229 10099 : const double fact_ij = inv_rij2 * delta_g_free_i * vdw_volume_j * INV_PI_SQRT_PI * inv_lambda_i;
230 10099 : const double fact_ji = inv_rij2 * delta_g_free_j * vdw_volume_i * INV_PI_SQRT_PI * inv_lambda_j;
231 :
232 : // in this case we can calculate a single exponential
233 10099 : if(!nlexpo[i][i_nl]) {
234 : // i-j interaction
235 14331 : if(inv_rij > 0.5*inv_lambda_i && delta_g_free_i!=0.)
236 : {
237 5514 : const double e_arg = (rij - vdw_radius_i)*inv_lambda_i;
238 5514 : const double expo = exp(-e_arg*e_arg);
239 5514 : const double fact = expo*fact_ij;
240 5514 : const double e_deriv = inv_rij*fact*(inv_rij + e_arg*inv_lambda_i);
241 5514 : const Vector dd = e_deriv*dist;
242 5514 : fedensity += fact;
243 5514 : deriv_i += dd;
244 11028 : if(nt>1) deriv_omp[j] -= dd;
245 0 : else deriv[j] -= dd;
246 : }
247 :
248 : // j-i interaction
249 8005 : if(inv_rij > 0.5*inv_lambda_j && delta_g_free_j!=0.)
250 : {
251 5153 : const double e_arg = (rij - vdw_radius_j)*inv_lambda_j;
252 5153 : const double expo = exp(-e_arg*e_arg);
253 5153 : const double fact = expo*fact_ji;
254 5153 : const double e_deriv = inv_rij*fact*(inv_rij + e_arg*inv_lambda_j);
255 5153 : const Vector dd = e_deriv*dist;
256 5154 : fedensity += fact;
257 5154 : deriv_i += dd;
258 10308 : if(nt>1) deriv_omp[j] -= dd;
259 0 : else deriv[j] -= dd;
260 : }
261 : } else {
262 : // i-j interaction
263 2094 : if(inv_rij > 0.5*inv_lambda_i)
264 : {
265 1620 : const double e_arg = (rij - vdw_radius_i)*inv_lambda_i;
266 1620 : const double expo = exp(-e_arg*e_arg);
267 1620 : const double fact = expo*(fact_ij + fact_ji);
268 1620 : const double e_deriv = inv_rij*fact*(inv_rij + e_arg*inv_lambda_i);
269 1620 : const Vector dd = e_deriv*dist;
270 1620 : fedensity += fact;
271 1620 : deriv_i += dd;
272 3240 : if(nt>1) deriv_omp[j] -= dd;
273 0 : else deriv[j] -= dd;
274 : }
275 : }
276 :
277 : }
278 1438 : if(nt>1) deriv_omp[i] += deriv_i;
279 0 : else deriv[i] += deriv_i;
280 719 : bias += 0.5*fedensity;
281 : }
282 72 : #pragma omp critical
283 6552 : if(nt>1) for(unsigned i=0; i<size; i++) deriv[i]+=deriv_omp[i];
284 : }
285 :
286 18 : if(!serial) {
287 18 : comm.Sum(bias);
288 36 : if(!deriv.empty()) comm.Sum(&deriv[0][0],3*deriv.size());
289 : }
290 :
291 18 : Tensor virial;
292 1098 : for(unsigned i=0; i<size; i++) {
293 2160 : setAtomsDerivatives(i, -deriv[i]);
294 2160 : virial += Tensor(getPosition(i), -deriv[i]);
295 : }
296 18 : setBoxDerivatives(-virial);
297 18 : setValue(delta_g_ref - bias);
298 :
299 : // Keep track of the neighbourlist updates
300 18 : nl_update++;
301 18 : if (nl_update == nl_stride) {
302 18 : nl_update = 0;
303 : }
304 18 : }
305 :
306 3 : void EEFSolv::setupConstants(const vector<AtomNumber> &atoms, vector<vector<double> > ¶meter, bool tcorr) {
307 : vector<vector<double> > parameter_temp;
308 9 : parameter_temp.resize(atoms.size(), vector<double>(7,0));
309 : map<string, vector<double> > valuemap;
310 : map<string, map<string, string> > typemap;
311 6 : valuemap = setupValueMap();
312 6 : typemap = setupTypeMap();
313 6 : vector<SetupMolInfo*> moldat = plumed.getActionSet().select<SetupMolInfo*>();
314 : bool cter=false;
315 3 : if (moldat.size() == 1) {
316 3 : log << " MOLINFO DATA found, using proper atom names\n";
317 363 : for(unsigned i=0; i<atoms.size(); ++i) {
318 :
319 : // Get atom and residue names
320 180 : string Aname = moldat[0]->getAtomName(atoms[i]);
321 180 : string Rname = moldat[0]->getResidueName(atoms[i]);
322 180 : string Atype = typemap[Rname][Aname];
323 :
324 : // Check for terminal COOH or COO- (different atomtypes & parameters!)
325 1080 : if (moldat[0]->getAtomName(atoms[i]) == "OT1" || moldat[0]->getAtomName(atoms[i]) == "OXT") {
326 : // We create a temporary AtomNumber object to access future atoms
327 : unsigned ai = atoms[i].index();
328 : AtomNumber tmp_an;
329 0 : tmp_an.setIndex(ai + 2);
330 0 : if (moldat[0]->getAtomName(tmp_an) == "HT2") {
331 : // COOH
332 : Atype = "OB";
333 : } else {
334 : // COO-
335 : Atype = "OC";
336 : }
337 : cter = true;
338 : }
339 540 : if (moldat[0]->getAtomName(atoms[i]) == "OT2" || (cter == true && moldat[0]->getAtomName(atoms[i]) == "O")) {
340 : unsigned ai = atoms[i].index();
341 : AtomNumber tmp_an;
342 0 : tmp_an.setIndex(ai + 1);
343 0 : if (moldat[0]->getAtomName(tmp_an) == "HT2") {
344 : // COOH
345 : Atype = "OH1";
346 : } else {
347 : // COO-
348 : Atype = "OC";
349 : }
350 : }
351 :
352 : // Check for H-atoms
353 : char type;
354 180 : char first = Aname.at(0);
355 :
356 : // GOLDEN RULE: type is first letter, if not a number
357 180 : if (!isdigit(first)) {
358 : type = first;
359 : // otherwise is the second
360 : } else {
361 0 : type = Aname.at(1);
362 : }
363 :
364 180 : if (type == 'H') {
365 0 : error("EEF1-SB does not allow the use of hydrogen atoms!\n");
366 : }
367 :
368 : // Lookup atomtype in table or throw exception if its not there
369 : try {
370 360 : parameter_temp[i] = valuemap.at(Atype);
371 0 : } catch (exception &e) {
372 0 : log << "Type: " << Atype << " Name: " << Aname << " Residue: " << Rname << "\n";
373 0 : error("Invalid atom type!\n");
374 : }
375 :
376 : // Temperature correction
377 180 : if (tcorr && parameter[i][1] > 0.0) {
378 : const double t0 = 298.15;
379 0 : const double delta_g_ref_t0 = parameter_temp[i][1];
380 0 : const double delta_h_ref_t0 = parameter_temp[i][3];
381 0 : const double delta_cp = parameter_temp[i][4];
382 0 : const double delta_s_ref_t0 = (delta_h_ref_t0 - delta_g_ref_t0) / t0;
383 0 : const double t = plumed.getAtoms().getKbT() / plumed.getAtoms().getKBoltzmann();
384 0 : parameter_temp[i][1] -= delta_s_ref_t0 * (t - t0) - delta_cp * t * std::log(t / t0) + delta_cp * (t - t0);
385 0 : parameter_temp[i][2] *= parameter_temp[i][1] / delta_g_ref_t0;
386 : }
387 180 : parameter[i][0] = parameter_temp[i][0];
388 180 : parameter[i][1] = parameter_temp[i][2];
389 180 : parameter[i][2] = parameter_temp[i][5];
390 180 : parameter[i][3] = parameter_temp[i][6];
391 : }
392 : } else {
393 0 : error("MOLINFO DATA not found\n");
394 : }
395 366 : for(unsigned i=0; i<atoms.size(); ++i) delta_g_ref += parameter_temp[i][1];
396 3 : }
397 :
398 3 : map<string, map<string, string> > EEFSolv::setupTypeMap() {
399 : map<string, map<string, string> > typemap;
400 1332 : typemap = {
401 : { "ACE", {
402 : {"CH3", "CT3"},
403 : {"HH31","HA3"},
404 : {"HH32","HA3"},
405 : {"HH33","HA3"},
406 : {"C", "C" },
407 : {"O", "O" }
408 : }
409 : },
410 : { "ALA", {
411 : {"N", "NH1"},
412 : {"HN", "H" },
413 : {"CA", "CT1"},
414 : {"HA", "HB1"},
415 : {"CB", "CT3"},
416 : {"HB1", "HA3"},
417 : {"HB2", "HA3"},
418 : {"HB3", "HA3"},
419 : {"C", "C" },
420 : {"O", "O" }
421 : }
422 : },
423 : { "ARG", {
424 : {"N", "NH1"},
425 : {"HN", "H" },
426 : {"CA", "CT1"},
427 : {"HA", "HB1"},
428 : {"CB", "CT2"},
429 : {"HB1", "HA2"},
430 : {"HB2", "HA2"},
431 : {"CG", "CT2"},
432 : {"HG1", "HA2"},
433 : {"HG2", "HA2"},
434 : {"CD", "CT2"},
435 : {"HD1", "HA2"},
436 : {"HD2", "HA2"},
437 : {"NE", "NC2"},
438 : {"HE", "HC" },
439 : {"CZ", "C" },
440 : {"NH1", "NC2"},
441 : {"HH11", "HC" },
442 : {"HH12", "HC" },
443 : {"NH2", "NC2"},
444 : {"HH21", "HC" },
445 : {"HH22", "HC" },
446 : {"C", "C" },
447 : {"O", "O" }
448 : }
449 : },
450 : { "ASN", {
451 : {"N", "NH1"},
452 : {"HN", "H" },
453 : {"CA", "CT1"},
454 : {"HA", "HB1"},
455 : {"CB", "CT2"},
456 : {"HB1", "HA2"},
457 : {"HB2", "HA2"},
458 : {"CG", "CC" },
459 : {"OD1", "O" },
460 : {"ND2", "NH2"},
461 : {"HD21", "H" },
462 : {"HD22", "H" },
463 : {"C", "C" },
464 : {"O", "O" }
465 : }
466 : },
467 : { "ASPP", {
468 : {"N", "NH1"},
469 : {"HN", "H" },
470 : {"CA", "CT1"},
471 : {"HA", "HB1"},
472 : {"CB", "CT2"},
473 : {"HB1", "HA2"},
474 : {"HB2", "HA2"},
475 : {"CG", "CD" },
476 : {"OD1", "OB" },
477 : {"OD2", "OH1"},
478 : {"HD2", "H" },
479 : {"C", "C" },
480 : {"O", "O" }
481 : }
482 : },
483 : { "ASP", {
484 : {"N", "NH1"},
485 : {"HN", "H" },
486 : {"CA", "CT1"},
487 : {"HA", "HB1"},
488 : {"CB", "CT2"},
489 : {"HB1", "HA2"},
490 : {"HB2", "HA2"},
491 : {"CG", "CC" },
492 : {"OD1", "OC" },
493 : {"OD2", "OC" },
494 : {"C", "C" },
495 : {"O", "O" }
496 : }
497 : },
498 : { "CYS", {
499 : {"N", "NH1"},
500 : {"HN", "H" },
501 : {"CA", "CT1"},
502 : {"HA", "HB1"},
503 : {"CB", "CT2"},
504 : {"HB1", "HA2"},
505 : {"HB2", "HA2"},
506 : {"SG", "S" },
507 : {"HG1", "HS" },
508 : {"C", "C" },
509 : {"O", "O" }
510 : }
511 : },
512 : { "GLN", {
513 : {"N", "NH1" },
514 : {"HN", "H" },
515 : {"CA", "CT1" },
516 : {"HA", "HB1" },
517 : {"CB", "CT2" },
518 : {"HB1", "HA2" },
519 : {"HB2", "HA2" },
520 : {"CG", "CT2" },
521 : {"HG1", "HA2" },
522 : {"HG2", "HA2" },
523 : {"CD", "CC" },
524 : {"OE1", "O" },
525 : {"NE2", "NH2" },
526 : {"HE21", "H" },
527 : {"HE22", "H" },
528 : {"C", "C" },
529 : {"O", "O" }
530 : }
531 : },
532 : { "GLUP", {
533 : {"N", "NH1"},
534 : {"HN", "H" },
535 : {"CA", "CT1"},
536 : {"HA", "HB1"},
537 : {"CB", "CT2"},
538 : {"HB1", "HA2"},
539 : {"HB2", "HA2"},
540 : {"CG", "CT2"},
541 : {"HG1", "HA2"},
542 : {"HG2", "HA2"},
543 : {"CD", "CD" },
544 : {"OE1", "OB" },
545 : {"OE2", "OH1"},
546 : {"HE2", "H" },
547 : {"C", "C" },
548 : {"O", "O" }
549 : }
550 : },
551 : { "GLU", {
552 : {"N", "NH1"},
553 : {"HN", "H" },
554 : {"CA", "CT1"},
555 : {"HA", "HB1"},
556 : {"CB", "CT2"},
557 : {"HB1", "HA2"},
558 : {"HB2", "HA2"},
559 : {"CG", "CT2"},
560 : {"HG1", "HA2"},
561 : {"HG2", "HA2"},
562 : {"CD", "CC" },
563 : {"OE1", "OC" },
564 : {"OE2", "OC" },
565 : {"C", "C" },
566 : {"O", "O" }
567 : }
568 : },
569 : { "GLY", {
570 : {"N", "NH1"},
571 : {"HN", "H" },
572 : {"CA", "CT2"},
573 : {"HA1", "HB2"},
574 : {"HA2", "HB2"},
575 : {"C", "C" },
576 : {"O", "O" }
577 : }
578 : },
579 : { "HSD", {
580 : {"N", "NH1"},
581 : {"HN", "H" },
582 : {"CA", "CT1"},
583 : {"HA", "HB1"},
584 : {"CB", "CT2"},
585 : {"HB1", "HA2"},
586 : {"HB2", "HA2"},
587 : {"ND1", "NR1"},
588 : {"HD1", "H" },
589 : {"CG", "CPH1"},
590 : {"CE1", "CPH2"},
591 : {"HE1", "HR1"},
592 : {"NE2", "NR2"},
593 : {"CD2", "CPH1"},
594 : {"HD2", "HR3"},
595 : {"C", "C" },
596 : {"O", "O" }
597 : }
598 : },
599 : { "HIS", {
600 : {"N", "NH1"},
601 : {"HN", "H" },
602 : {"CA", "CT1"},
603 : {"HA", "HB1"},
604 : {"CB", "CT2"},
605 : {"HB1", "HA2"},
606 : {"HB2", "HA2"},
607 : {"ND1", "NR2"},
608 : {"CG", "CPH1"},
609 : {"CE1", "CPH2"},
610 : {"HE1", "HR1"},
611 : {"NE2", "NR1"},
612 : {"HE2", "H" },
613 : {"CD2", "CPH1"},
614 : {"HD2", "HR3"},
615 : {"C", "C" },
616 : {"O", "O" }
617 : }
618 : },
619 : { "HSE", {
620 : {"N", "NH1"},
621 : {"HN", "H" },
622 : {"CA", "CT1"},
623 : {"HA", "HB1"},
624 : {"CB", "CT2"},
625 : {"HB1", "HA2"},
626 : {"HB2", "HA2"},
627 : {"ND1", "NR2"},
628 : {"CG", "CPH1"},
629 : {"CE1", "CPH2"},
630 : {"HE1", "HR1"},
631 : {"NE2", "NR1"},
632 : {"HE2", "H" },
633 : {"CD2", "CPH1"},
634 : {"HD2", "HR3"},
635 : {"C", "C" },
636 : {"O", "O" }
637 : }
638 : },
639 : { "HSP", {
640 : {"N", "NH1"},
641 : {"HN", "H" },
642 : {"CA", "CT1"},
643 : {"HA", "HB1"},
644 : {"CB", "CT2"},
645 : {"HB1", "HA2"},
646 : {"HB2", "HA2"},
647 : {"CD2", "CPH1"},
648 : {"HD2", "HR1"},
649 : {"CG", "CPH1"},
650 : {"NE2", "NR3"},
651 : {"HE2", "H" },
652 : {"ND1", "NR3"},
653 : {"HD1", "H" },
654 : {"CE1", "CPH2"},
655 : {"HE1", "HR2"},
656 : {"C", "C" },
657 : {"O", "O" }
658 : }
659 : },
660 : { "ILE", {
661 : {"N", "NH1"},
662 : {"HN", "H" },
663 : {"CA", "CT1"},
664 : {"HA", "HB1"},
665 : {"CB", "CT1"},
666 : {"HB", "HA1"},
667 : {"CG2", "CT3"},
668 : {"HG21", "HA3"},
669 : {"HG22", "HA3"},
670 : {"HG23", "HA3"},
671 : {"CG1", "CT2"},
672 : {"HG11", "HA2"},
673 : {"HG12", "HA2"},
674 : {"CD", "CT3"},
675 : {"HD1", "HA3"},
676 : {"HD2", "HA3"},
677 : {"HD3", "HA3"},
678 : {"C", "C" },
679 : {"O", "O" }
680 : }
681 : },
682 : { "LEU", {
683 : {"N", "NH1"},
684 : {"HN", "H" },
685 : {"CA", "CT1"},
686 : {"HA", "HB1"},
687 : {"CB", "CT2"},
688 : {"HB1", "HA2"},
689 : {"HB2", "HA2"},
690 : {"CG", "CT1"},
691 : {"HG", "HA1"},
692 : {"CD1", "CT3"},
693 : {"HD11", "HA3"},
694 : {"HD12", "HA3"},
695 : {"HD13", "HA3"},
696 : {"CD2", "CT3"},
697 : {"HD21", "HA3"},
698 : {"HD22", "HA3"},
699 : {"HD23", "HA3"},
700 : {"C", "C" },
701 : {"O", "O" }
702 : }
703 : },
704 : { "LYS", {
705 : {"N", "NH1"},
706 : {"HN", "H" },
707 : {"CA", "CT1"},
708 : {"HA", "HB1"},
709 : {"CB", "CT2"},
710 : {"HB1", "HA2"},
711 : {"HB2", "HA2"},
712 : {"CG", "CT2"},
713 : {"HG1", "HA2"},
714 : {"HG2", "HA2"},
715 : {"CD", "CT2"},
716 : {"HD1", "HA2"},
717 : {"HD2", "HA2"},
718 : {"CE", "CT2"},
719 : {"HE1", "HA2"},
720 : {"HE2", "HA2"},
721 : {"NZ", "NH3"},
722 : {"HZ1", "HC" },
723 : {"HZ2", "HC" },
724 : {"HZ3", "HC" },
725 : {"C", "C" },
726 : {"O", "O" }
727 : }
728 : },
729 : { "MET", {
730 : {"N", "NH1"},
731 : {"HN", "H" },
732 : {"CA", "CT1"},
733 : {"HA", "HB1"},
734 : {"CB", "CT2"},
735 : {"HB1", "HA2"},
736 : {"HB2", "HA2"},
737 : {"CG", "CT2"},
738 : {"HG1", "HA2"},
739 : {"HG2", "HA2"},
740 : {"SD", "S" },
741 : {"CE", "CT3"},
742 : {"HE1", "HA3"},
743 : {"HE2", "HA3"},
744 : {"HE3", "HA3"},
745 : {"C", "C" },
746 : {"O", "O" }
747 : }
748 : },
749 : { "NMA", {
750 : {"N", "NH1"},
751 : {"HN", "H" },
752 : {"CH3", "CT3"},
753 : {"HH31","HA3"},
754 : {"HH32","HA3"},
755 : {"HH33","HA3"},
756 : }
757 : },
758 : { "PHE", {
759 : {"N", "NH1"},
760 : {"HN", "H" },
761 : {"CA", "CT1"},
762 : {"HA", "HB1"},
763 : {"CB", "CT2"},
764 : {"HB1", "HA2"},
765 : {"HB2", "HA2"},
766 : {"CG", "CA" },
767 : {"CD1", "CA" },
768 : {"HD1", "HP" },
769 : {"CE1", "CA" },
770 : {"HE1", "HP" },
771 : {"CZ", "CA" },
772 : {"HZ", "HP" },
773 : {"CD2", "CA" },
774 : {"HD2", "HP" },
775 : {"CE2", "CA" },
776 : {"HE2", "HP" },
777 : {"C", "C" },
778 : {"O", "O" }
779 : }
780 : },
781 : { "PRO", {
782 : {"N", "N" },
783 : {"CD", "CP3"},
784 : {"HD1", "HA2"},
785 : {"HD2", "HA2"},
786 : {"CA", "CP1"},
787 : {"HA", "HB1"},
788 : {"CB", "CP2"},
789 : {"HB1", "HA2"},
790 : {"HB2", "HA2"},
791 : {"CG", "CP2"},
792 : {"HG1", "HA2"},
793 : {"HG2", "HA2"},
794 : {"C", "C" },
795 : {"O", "O" }
796 : }
797 : },
798 : { "SER", {
799 : {"N", "NH1"},
800 : {"HN", "H" },
801 : {"CA", "CT1"},
802 : {"HA", "HB1"},
803 : {"CB", "CT2"},
804 : {"HB1", "HA2"},
805 : {"HB2", "HA2"},
806 : {"OG", "OH1"},
807 : {"HG1", "H" },
808 : {"C", "C" },
809 : {"O", "O" }
810 : }
811 : },
812 : { "THR", {
813 : {"N", "NH1"},
814 : {"HN", "H" },
815 : {"CA", "CT1"},
816 : {"HA", "HB1"},
817 : {"CB", "CT1"},
818 : {"HB", "HA1"},
819 : {"OG1", "OH1"},
820 : {"HG1", "H" },
821 : {"CG2", "CT3"},
822 : {"HG21", "HA3"},
823 : {"HG22", "HA3"},
824 : {"HG23", "HA3"},
825 : {"C", "C" },
826 : {"O", "O" }
827 : }
828 : },
829 : { "TRP", {
830 : {"N", "NH1"},
831 : {"HN", "H" },
832 : {"CA", "CT1"},
833 : {"HA", "HB1"},
834 : {"CB", "CT2"},
835 : {"HB1", "HA2"},
836 : {"HB2", "HA2"},
837 : {"CG", "CY" },
838 : {"CD1", "CA" },
839 : {"HD1", "HP" },
840 : {"NE1", "NY" },
841 : {"HE1", "H" },
842 : {"CE2", "CPT"},
843 : {"CD2", "CPT"},
844 : {"CE3", "CAI"},
845 : {"HE3", "HP" },
846 : {"CZ3", "CA" },
847 : {"HZ3", "HP" },
848 : {"CZ2", "CAI"},
849 : {"HZ2", "HP" },
850 : {"CH2", "CA" },
851 : {"HH2", "HP" },
852 : {"C", "C" },
853 : {"O", "O" }
854 : }
855 : },
856 : { "TYR", {
857 : {"N", "NH1"},
858 : {"HN", "H" },
859 : {"CA", "CT1"},
860 : {"HA", "HB1"},
861 : {"CB", "CT2"},
862 : {"HB1", "HA2"},
863 : {"HB2", "HA2"},
864 : {"CG", "CA" },
865 : {"CD1", "CA" },
866 : {"HD1", "HP" },
867 : {"CE1", "CA" },
868 : {"HE1", "HP" },
869 : {"CZ", "CA" },
870 : {"OH", "OH1"},
871 : {"HH", "H" },
872 : {"CD2", "CA" },
873 : {"HD2", "HP" },
874 : {"CE2", "CA" },
875 : {"HE2", "HP" },
876 : {"C", "C" },
877 : {"O", "O" }
878 : }
879 : },
880 : { "VAL", {
881 : {"N", "NH1"},
882 : {"HN", "H" },
883 : {"CA", "CT1"},
884 : {"HA", "HB1"},
885 : {"CB", "CT1"},
886 : {"HB", "HA1"},
887 : {"CG1", "CT3"},
888 : {"HG11", "HA3"},
889 : {"HG12", "HA3"},
890 : {"HG13", "HA3"},
891 : {"CG2", "CT3"},
892 : {"HG21", "HA3"},
893 : {"HG22", "HA3"},
894 : {"HG23", "HA3"},
895 : {"C", "C" },
896 : {"O", "O" }
897 : }
898 : }
899 1338 : };
900 3 : return typemap;
901 : }
902 :
903 3 : map<string, vector<double> > EEFSolv::setupValueMap() {
904 : // Volume ∆Gref ∆Gfree ∆H ∆Cp λ vdw_radius
905 : map<string, vector<double> > valuemap;
906 99 : valuemap = {
907 : { "C", {
908 : ANG3_TO_NM3 * 14.720,
909 : KCAL_TO_KJ * 0.000,
910 : KCAL_TO_KJ * 0.000,
911 : KCAL_TO_KJ * 0.000,
912 : KCAL_TO_KJ * 0.0,
913 : 1. / (ANG_TO_NM * 3.5),
914 : 0.20,
915 : }
916 : },
917 : { "CD", {
918 : ANG3_TO_NM3 * 14.720,
919 : KCAL_TO_KJ * 0.000,
920 : KCAL_TO_KJ * 0.000,
921 : KCAL_TO_KJ * 0.000,
922 : KCAL_TO_KJ * 0.0,
923 : 1. / (ANG_TO_NM * 3.5),
924 : 0.20,
925 : }
926 : },
927 : { "CT1", {
928 : ANG3_TO_NM3 * 11.507,
929 : KCAL_TO_KJ * -0.187,
930 : KCAL_TO_KJ * -0.187,
931 : KCAL_TO_KJ * 0.876,
932 : KCAL_TO_KJ * 0.0,
933 : 1. / (ANG_TO_NM * 3.5),
934 : 0.20,
935 : }
936 : },
937 : { "CT2", {
938 : ANG3_TO_NM3 * 18.850,
939 : KCAL_TO_KJ * 0.372,
940 : KCAL_TO_KJ * 0.372,
941 : KCAL_TO_KJ * -0.610,
942 : KCAL_TO_KJ * 18.6,
943 : 1. / (ANG_TO_NM * 3.5),
944 : 0.20,
945 : }
946 : },
947 : { "CT2A", {
948 : ANG3_TO_NM3 * 18.666,
949 : KCAL_TO_KJ * 0.372,
950 : KCAL_TO_KJ * 0.372,
951 : KCAL_TO_KJ * -0.610,
952 : KCAL_TO_KJ * 18.6,
953 : 1. / (ANG_TO_NM * 3.5),
954 : 0.20,
955 : }
956 : },
957 : { "CT3", {
958 : ANG3_TO_NM3 * 27.941,
959 : KCAL_TO_KJ * 1.089,
960 : KCAL_TO_KJ * 1.089,
961 : KCAL_TO_KJ * -1.779,
962 : KCAL_TO_KJ * 35.6,
963 : 1. / (ANG_TO_NM * 3.5),
964 : 0.204,
965 : }
966 : },
967 : { "CPH1", {
968 : ANG3_TO_NM3 * 5.275,
969 : KCAL_TO_KJ * 0.057,
970 : KCAL_TO_KJ * 0.080,
971 : KCAL_TO_KJ * -0.973,
972 : KCAL_TO_KJ * 6.9,
973 : 1. / (ANG_TO_NM * 3.5),
974 : 0.18,
975 : }
976 : },
977 : { "CPH2", {
978 : ANG3_TO_NM3 * 11.796,
979 : KCAL_TO_KJ * 0.057,
980 : KCAL_TO_KJ * 0.080,
981 : KCAL_TO_KJ * -0.973,
982 : KCAL_TO_KJ * 6.9,
983 : 1. / (ANG_TO_NM * 3.5),
984 : 0.18,
985 : }
986 : },
987 : { "CPT", {
988 : ANG3_TO_NM3 * 4.669,
989 : KCAL_TO_KJ * -0.890,
990 : KCAL_TO_KJ * -0.890,
991 : KCAL_TO_KJ * 2.220,
992 : KCAL_TO_KJ * 6.9,
993 : 1. / (ANG_TO_NM * 3.5),
994 : 0.186,
995 : }
996 : },
997 : { "CY", {
998 : ANG3_TO_NM3 * 10.507,
999 : KCAL_TO_KJ * -0.890,
1000 : KCAL_TO_KJ * -0.890,
1001 : KCAL_TO_KJ * 2.220,
1002 : KCAL_TO_KJ * 6.9,
1003 : 1. / (ANG_TO_NM * 3.5),
1004 : 0.199,
1005 : }
1006 : },
1007 : { "CP1", {
1008 : ANG3_TO_NM3 * 25.458,
1009 : KCAL_TO_KJ * -0.187,
1010 : KCAL_TO_KJ * -0.187,
1011 : KCAL_TO_KJ * 0.876,
1012 : KCAL_TO_KJ * 0.0,
1013 : 1. / (ANG_TO_NM * 3.5),
1014 : 0.227,
1015 : }
1016 : },
1017 : { "CP2", {
1018 : ANG3_TO_NM3 * 19.880,
1019 : KCAL_TO_KJ * 0.372,
1020 : KCAL_TO_KJ * 0.372,
1021 : KCAL_TO_KJ * -0.610,
1022 : KCAL_TO_KJ * 18.6,
1023 : 1. / (ANG_TO_NM * 3.5),
1024 : 0.217,
1025 : }
1026 : },
1027 : { "CP3", {
1028 : ANG3_TO_NM3 * 26.731,
1029 : KCAL_TO_KJ * 0.372,
1030 : KCAL_TO_KJ * 0.372,
1031 : KCAL_TO_KJ * -0.610,
1032 : KCAL_TO_KJ * 18.6,
1033 : 1. / (ANG_TO_NM * 3.5),
1034 : 0.217,
1035 : }
1036 : },
1037 : { "CC", {
1038 : ANG3_TO_NM3 * 16.539,
1039 : KCAL_TO_KJ * 0.000,
1040 : KCAL_TO_KJ * 0.000,
1041 : KCAL_TO_KJ * 0.000,
1042 : KCAL_TO_KJ * 0.0,
1043 : 1. / (ANG_TO_NM * 3.5),
1044 : 0.20,
1045 : }
1046 : },
1047 : { "CAI", {
1048 : ANG3_TO_NM3 * 18.249,
1049 : KCAL_TO_KJ * 0.057,
1050 : KCAL_TO_KJ * 0.057,
1051 : KCAL_TO_KJ * -0.973,
1052 : KCAL_TO_KJ * 6.9,
1053 : 1. / (ANG_TO_NM * 3.5),
1054 : 0.199,
1055 : }
1056 : },
1057 : { "CA", {
1058 : ANG3_TO_NM3 * 18.249,
1059 : KCAL_TO_KJ * 0.057,
1060 : KCAL_TO_KJ * 0.057,
1061 : KCAL_TO_KJ * -0.973,
1062 : KCAL_TO_KJ * 6.9,
1063 : 1. / (ANG_TO_NM * 3.5),
1064 : 0.199,
1065 : }
1066 : },
1067 : { "N", {
1068 : ANG3_TO_NM3 * 0.000,
1069 : KCAL_TO_KJ * -1.000,
1070 : KCAL_TO_KJ * -1.000,
1071 : KCAL_TO_KJ * -1.250,
1072 : KCAL_TO_KJ * 8.8,
1073 : 1. / (ANG_TO_NM * 3.5),
1074 : 0.185,
1075 : }
1076 : },
1077 : { "NR1", {
1078 : ANG3_TO_NM3 * 15.273,
1079 : KCAL_TO_KJ * -5.950,
1080 : KCAL_TO_KJ * -5.950,
1081 : KCAL_TO_KJ * -9.059,
1082 : KCAL_TO_KJ * -8.8,
1083 : 1. / (ANG_TO_NM * 3.5),
1084 : 0.185,
1085 : }
1086 : },
1087 : { "NR2", {
1088 : ANG3_TO_NM3 * 15.111,
1089 : KCAL_TO_KJ * -3.820,
1090 : KCAL_TO_KJ * -3.820,
1091 : KCAL_TO_KJ * -4.654,
1092 : KCAL_TO_KJ * -8.8,
1093 : 1. / (ANG_TO_NM * 3.5),
1094 : 0.185,
1095 : }
1096 : },
1097 : { "NR3", {
1098 : ANG3_TO_NM3 * 15.071,
1099 : KCAL_TO_KJ * -5.950,
1100 : KCAL_TO_KJ * -5.950,
1101 : KCAL_TO_KJ * -9.059,
1102 : KCAL_TO_KJ * -8.8,
1103 : 1. / (ANG_TO_NM * 3.5),
1104 : 0.185,
1105 : }
1106 : },
1107 : { "NH1", {
1108 : ANG3_TO_NM3 * 10.197,
1109 : KCAL_TO_KJ * -5.950,
1110 : KCAL_TO_KJ * -5.950,
1111 : KCAL_TO_KJ * -9.059,
1112 : KCAL_TO_KJ * -8.8,
1113 : 1. / (ANG_TO_NM * 3.5),
1114 : 0.185,
1115 : }
1116 : },
1117 : { "NH2", {
1118 : ANG3_TO_NM3 * 18.182,
1119 : KCAL_TO_KJ * -5.950,
1120 : KCAL_TO_KJ * -5.950,
1121 : KCAL_TO_KJ * -9.059,
1122 : KCAL_TO_KJ * -8.8,
1123 : 1. / (ANG_TO_NM * 3.5),
1124 : 0.185,
1125 : }
1126 : },
1127 : { "NH3", {
1128 : ANG3_TO_NM3 * 18.817,
1129 : KCAL_TO_KJ * -20.000,
1130 : KCAL_TO_KJ * -20.000,
1131 : KCAL_TO_KJ * -25.000,
1132 : KCAL_TO_KJ * -18.0,
1133 : 1. / (ANG_TO_NM * 6.0),
1134 : 0.185,
1135 : }
1136 : },
1137 : { "NC2", {
1138 : ANG3_TO_NM3 * 18.215,
1139 : KCAL_TO_KJ * -10.000,
1140 : KCAL_TO_KJ * -10.000,
1141 : KCAL_TO_KJ * -12.000,
1142 : KCAL_TO_KJ * -7.0,
1143 : 1. / (ANG_TO_NM * 6.0),
1144 : 0.185,
1145 : }
1146 : },
1147 : { "NY", {
1148 : ANG3_TO_NM3 * 12.001,
1149 : KCAL_TO_KJ * -5.950,
1150 : KCAL_TO_KJ * -5.950,
1151 : KCAL_TO_KJ * -9.059,
1152 : KCAL_TO_KJ * -8.8,
1153 : 1. / (ANG_TO_NM * 3.5),
1154 : 0.185,
1155 : }
1156 : },
1157 : { "NP", {
1158 : ANG3_TO_NM3 * 4.993,
1159 : KCAL_TO_KJ * -20.000,
1160 : KCAL_TO_KJ * -20.000,
1161 : KCAL_TO_KJ * -25.000,
1162 : KCAL_TO_KJ * -18.0,
1163 : 1. / (ANG_TO_NM * 6.0),
1164 : 0.185,
1165 : }
1166 : },
1167 : { "O", {
1168 : ANG3_TO_NM3 * 11.772,
1169 : KCAL_TO_KJ * -5.330,
1170 : KCAL_TO_KJ * -5.330,
1171 : KCAL_TO_KJ * -5.787,
1172 : KCAL_TO_KJ * -8.8,
1173 : 1. / (ANG_TO_NM * 3.5),
1174 : 0.170,
1175 : }
1176 : },
1177 : { "OB", {
1178 : ANG3_TO_NM3 * 11.694,
1179 : KCAL_TO_KJ * -5.330,
1180 : KCAL_TO_KJ * -5.330,
1181 : KCAL_TO_KJ * -5.787,
1182 : KCAL_TO_KJ * -8.8,
1183 : 1. / (ANG_TO_NM * 3.5),
1184 : 0.170,
1185 : }
1186 : },
1187 : { "OC", {
1188 : ANG3_TO_NM3 * 12.003,
1189 : KCAL_TO_KJ * -10.000,
1190 : KCAL_TO_KJ * -10.000,
1191 : KCAL_TO_KJ * -12.000,
1192 : KCAL_TO_KJ * -9.4,
1193 : 1. / (ANG_TO_NM * 6.0),
1194 : 0.170,
1195 : }
1196 : },
1197 : { "OH1", {
1198 : ANG3_TO_NM3 * 15.528,
1199 : KCAL_TO_KJ * -5.920,
1200 : KCAL_TO_KJ * -5.920,
1201 : KCAL_TO_KJ * -9.264,
1202 : KCAL_TO_KJ * -11.2,
1203 : 1. / (ANG_TO_NM * 3.5),
1204 : 0.177,
1205 : }
1206 : },
1207 : { "OS", {
1208 : ANG3_TO_NM3 * 6.774,
1209 : KCAL_TO_KJ * -2.900,
1210 : KCAL_TO_KJ * -2.900,
1211 : KCAL_TO_KJ * -3.150,
1212 : KCAL_TO_KJ * -4.8,
1213 : 1. / (ANG_TO_NM * 3.5),
1214 : 0.177,
1215 : }
1216 : },
1217 : { "S", {
1218 : ANG3_TO_NM3 * 20.703,
1219 : KCAL_TO_KJ * -3.240,
1220 : KCAL_TO_KJ * -3.240,
1221 : KCAL_TO_KJ * -4.475,
1222 : KCAL_TO_KJ * -39.9,
1223 : 1. / (ANG_TO_NM * 3.5),
1224 : 0.20,
1225 : }
1226 : },
1227 : { "SM", {
1228 : ANG3_TO_NM3 * 21.306,
1229 : KCAL_TO_KJ * -3.240,
1230 : KCAL_TO_KJ * -3.240,
1231 : KCAL_TO_KJ * -4.475,
1232 : KCAL_TO_KJ * -39.9,
1233 : 1. / (ANG_TO_NM * 3.5),
1234 : 0.197,
1235 : }
1236 : }
1237 105 : };
1238 3 : return valuemap;
1239 : }
1240 : }
1241 5874 : }
|