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