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