LCOV - code coverage report
Current view: top level - sasa - sasa_LCPO.cpp (source / functions) Hit Total Coverage
Test: plumed test coverage Lines: 532 648 82.1 %
Date: 2026-03-30 13:16:06 Functions: 13 16 81.2 %

          Line data    Source code
       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
       2             : Copyright (c) 2021, Andrea Arsiccio
       3             : 
       4             : This software is provided 'as-is', without any express or implied
       5             : warranty. In no event will the authors be held liable for any damages
       6             : arising from the use of this software.
       7             : 
       8             : Permission is granted to anyone to use this software for any purpose,
       9             : including commercial applications, and to alter it and redistribute it
      10             : freely, subject to the following restrictions:
      11             : 
      12             : 1. The origin of this software must not be misrepresented; you must not
      13             :    claim that you wrote the original software. If you use this software
      14             :    in a product, an acknowledgment in the product documentation would be
      15             :    appreciated but is not required.
      16             : 2. Altered source versions must be plainly marked as such, and must not be
      17             :    misrepresented as being the original software.
      18             : 3. This notice may not be removed or altered from any source distribution.
      19             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
      20             : 
      21             : #include "Sasa.h"
      22             : #include "ActionRegister.h"
      23             : #include "core/PlumedMain.h"
      24             : #include "core/GenericMolInfo.h"
      25             : #include "core/ActionSet.h"
      26             : #include <cstdio>
      27             : #include <iostream>
      28             : #include <string>
      29             : #include <cmath>
      30             : #include <sstream>
      31             : #include <algorithm>
      32             : #include <iterator>
      33             : #include <fstream>
      34             : 
      35             : 
      36             : using namespace std;
      37             : 
      38             : namespace PLMD {
      39             : namespace sasa {
      40             : 
      41             : //+PLUMEDOC SASAMOD_COLVAR SASA_LCPO
      42             : /*
      43             : Calculates the solvent accessible surface area (SASA) of a protein molecule, or other properties related to it.
      44             : 
      45             : The atoms for which the SASA is desired should be indicated with the keyword ATOMS, and a pdb file of the protein must be provided in input with the MOLINFO keyword. The LCPO algorithm is used for the calculation (please, read and cite \cite Weiser1999). The radius of the solvent is assumed to be 0.14 nm, which is the radius of water molecules. Using the keyword NL_STRIDE it is also possible to specify the frequency with which the neighbor list for the calculation of the SASA is updated (the default is every 10 steps).
      46             : 
      47             : Different properties can be calculated and selected using the TYPE keyword:
      48             : 
      49             : 1) the total SASA (TOTAL);
      50             : 
      51             : 2) the free energy of transfer for the protein according to the transfer model (TRANSFER). This keyword can be used, for instance, to compute the transfer of a protein to different temperatures, as detailed in \cite Arsiccio-T-SASA-2021, or to different pressures, as detailed in \cite Arsiccio-P-SASA-2021, or to different osmolyte solutions, as detailed in \cite Arsiccio-C-SASA-2022.
      52             : 
      53             : 
      54             : When the TRANSFER keyword is used, a file with the free energy of transfer values for the sidechains and backbone atoms should be provided (using the keyword DELTAGFILE). Such file should have the following format:
      55             : 
      56             : \verbatim
      57             : ----------------Sample DeltaG.dat file---------------------
      58             : ALA     0.711019999999962
      59             : ARG     -2.24832799999996
      60             : ASN     -2.74838799999999
      61             : ASP     -2.5626376
      62             : CYS     3.89864000000006
      63             : GLN     -1.76192
      64             : GLU     -2.38664400000002
      65             : GLY     0
      66             : HIS     -3.58152799999999
      67             : ILE     2.42634399999986
      68             : LEU     1.77233599999988
      69             : LYS     -1.92576400000002
      70             : MET     -0.262827999999956
      71             : PHE     1.62028800000007
      72             : PRO     -2.15598800000001
      73             : SER     -1.60934800000004
      74             : THR     -0.591559999999987
      75             : TRP     1.22936000000027
      76             : TYR     0.775547999999958
      77             : VAL     2.12779200000011
      78             : BACKBONE        1.00066920000002
      79             : -----------------------------------------------------------
      80             : \endverbatim
      81             : 
      82             : where the second column is the free energy of transfer for each sidechain/backbone, in kJ/mol.
      83             : 
      84             : A Python script for the computation of free energy of transfer values to describe the effect of osmolyte concentration, temperature and pressure (according to \cite Arsiccio-C-SASA-2022, \cite Arsiccio-T-SASA-2021 and \cite Arsiccio-P-SASA-2021) is freely available at https://github.com/andrea-arsiccio/DeltaG-calculation. The script automatically outputs a DeltaG.dat file compatible with this SASA module.
      85             : 
      86             : If the DELTAGFILE is not provided, the program computes the free energy of transfer values as if they had to take into account the effect of temperature according to approaches 2 or 3 in the paper \cite Arsiccio-T-SASA-2021. Please read and cite this paper if using the transfer model for computing the effect of temperature in implicit solvent simulations. For this purpose, the keyword APPROACH should be added, and set to either 2 or 3.
      87             : 
      88             : The SASA usually makes sense when atoms used for the calculation are all part of the same molecule. When running with periodic boundary conditions, the atoms should be in the proper periodic image. This is done automatically since PLUMED 2.2, by considering the ordered list of atoms and rebuilding the broken entities using a procedure that is equivalent to that done in \ref WHOLEMOLECULES. Notice that rebuilding is local to this action. This is different from \ref WHOLEMOLECULES which actually modifies the coordinates stored in PLUMED.
      89             : 
      90             : In case you want to recover the old behavior you should use the NOPBC flag.
      91             : In that case you need to take care that atoms are in the correct periodic image.
      92             : 
      93             : The SASA may also be computed using the SASA_HASEL collective variable, which makes use of the algorithm described in \cite Hasel1988. SASA_HASEL is less accurate then SASA_LCPO, but the computation is faster.
      94             : 
      95             : 
      96             : 
      97             : \par Examples
      98             : 
      99             : The following input tells plumed to print the total SASA for atoms 10 to 20 in a protein chain.
     100             : \plumedfile
     101             : SASA_LCPO TYPE=TOTAL ATOMS=10-20 NL_STRIDE=10 LABEL=sasa
     102             : PRINT ARG=sasa STRIDE=1 FILE=colvar
     103             : \endplumedfile
     104             : 
     105             : 
     106             : The following input tells plumed to compute the transfer free energy for the protein chain containing atoms 10 to 20. Such transfer free energy is then used as a bias in the simulation (e.g., implicit solvent simulations). The free energy of transfer values are read from a file called DeltaG.dat.
     107             : 
     108             : \plumedfile
     109             : SASA_LCPO TYPE=TRANSFER ATOMS=10-20 NL_STRIDE=10 DELTAGFILE=DeltaG.dat LABEL=sasa
     110             : 
     111             : bias: BIASVALUE ARG=sasa
     112             : 
     113             : PRINT ARG=sasa,bias.* STRIDE=1 FILE=colvar
     114             : \endplumedfile
     115             : 
     116             : The following input tells plumed to compute the transfer free energy for the protein chain containing atoms 10 to 20. Such transfer free energy is then used as a bias in the simulation (e.g., implicit solvent simulations). The free energy of transfer values are computed according to \cite Arsiccio-T-SASA-2021, and take into account the effect of temperature using approach 2 as described in the paper.
     117             : 
     118             : \plumedfile
     119             : SASA_LCPO TYPE=TRANSFER ATOMS=10-20 NL_STRIDE=10 APPROACH=2 LABEL=sasa
     120             : 
     121             : bias: BIASVALUE ARG=sasa
     122             : 
     123             : PRINT ARG=sasa,bias.* STRIDE=1 FILE=colvar
     124             : \endplumedfile
     125             : 
     126             : */
     127             : //+ENDPLUMEDOC
     128             : 
     129             : class SASA_LCPO : public Colvar {
     130             : private:
     131             :   enum CV_TYPE {TOTAL, TRANSFER};
     132             :   int sasa_type;
     133             :   bool nopbc;
     134             :   double rs;
     135             :   string DeltaGValues;
     136             :   int approach;
     137             :   unsigned stride;
     138             :   unsigned nl_update;
     139             :   int firstStepFlag;
     140             :   double Ti;
     141             :   // cppcheck-suppress duplInheritedMember
     142             :   std::vector<AtomNumber> atoms;
     143             :   vector < vector < std::string > > AtomResidueName;
     144             :   vector < vector < double > > LCPOparam;
     145             :   unsigned natoms;
     146             :   vector < vector < double > > MaxSurf;
     147             :   vector < vector < double > > DeltaG;
     148             :   vector < vector < int > > Nlist;
     149             : public:
     150             :   static void registerKeywords(Keywords& keys);
     151             :   explicit SASA_LCPO(const ActionOptions&);
     152             :   void readPDB();
     153             :   map<string, vector<double> > setupLCPOparam();
     154             :   void readLCPOparam();
     155             :   void calcNlist();
     156             :   map<string, vector<double> > setupMaxSurfMap();
     157             :   void readMaxSurf();
     158             :   void readDeltaG();
     159             :   void computeDeltaG();
     160             :   virtual void calculate();
     161             : };
     162             : 
     163       13789 : PLUMED_REGISTER_ACTION(SASA_LCPO,"SASA_LCPO")
     164             : 
     165           6 : void SASA_LCPO::registerKeywords(Keywords& keys) {
     166           6 :   Colvar::registerKeywords(keys);
     167          12 :   keys.add("atoms","ATOMS","the group of atoms that you are calculating the SASA for");
     168          12 :   keys.add("compulsory","TYPE","TOTAL","The type of calculation you want to perform. Can be TOTAL or TRANSFER");
     169          12 :   keys.add("compulsory", "NL_STRIDE", "The frequency with which the neighbor list is updated.");
     170          12 :   keys.add("optional","DELTAGFILE","a file containing the free energy values for backbone and sidechains. Necessary only if TYPE = TRANSFER. A Python script for the computation of free energy of transfer values to describe the effect of osmolyte concentration, temperature and pressure is freely available at https://github.com/andrea-arsiccio/DeltaG-calculation. The script automatically outputs a DeltaG.dat file compatible with this SASA module. If TYPE = TRANSFER and no DELTAGFILE is provided, the free energy values are those describing the effect of temperature, and are computed using the temperature value passed by the MD engine");
     171          12 :   keys.add("optional","APPROACH","either approach 2 or 3. Necessary only if TYPE = TRANSFER and no DELTAGFILE is provided. If TYPE = TRANSFER and no DELTAGFILE is provided, the free energy values are those describing the effect of temperature, and the program must know if approach 2 or 3 (as described in Arsiccio and Shea, Protein Cold Denaturation in Implicit Solvent Simulations: A Transfer Free Energy Approach, J. Phys. Chem. B, 2021) needs to be used to compute them");
     172           6 : }
     173             : 
     174             : 
     175           2 : SASA_LCPO::SASA_LCPO(const ActionOptions&ao):
     176             :   PLUMED_COLVAR_INIT(ao),
     177           2 :   nopbc(false),
     178           4 :   DeltaGValues("absent"),
     179           2 :   Ti(0),
     180           2 :   stride(10),
     181           2 :   nl_update(0),
     182           2 :   firstStepFlag(0) {
     183           2 :   rs = 0.14;
     184           2 :   parse("DELTAGFILE",DeltaGValues);
     185           2 :   parse("APPROACH", approach);
     186           4 :   parseAtomList("ATOMS",atoms);
     187           2 :   if(atoms.size()==0) {
     188           0 :     error("no atoms specified");
     189             :   }
     190             :   std::string Type;
     191           2 :   parse("TYPE",Type);
     192           2 :   parse("NL_STRIDE", stride);
     193           2 :   parseFlag("NOPBC",nopbc);
     194           2 :   checkRead();
     195             : 
     196           2 :   if(Type=="TOTAL") {
     197           1 :     sasa_type=TOTAL;
     198           1 :   } else if(Type=="TRANSFER") {
     199           1 :     sasa_type=TRANSFER;
     200             :   } else {
     201           0 :     error("Unknown SASA type");
     202             :   }
     203             : 
     204           2 :   switch(sasa_type) {
     205           1 :   case TOTAL:
     206           1 :     log.printf("  TOTAL SASA;");
     207             :     break;
     208           1 :   case TRANSFER:
     209           1 :     log.printf("  TRANSFER MODEL;");
     210             :     break;
     211             :   }
     212             : 
     213           2 :   log.printf("  atoms involved : ");
     214         242 :   for(unsigned i=0; i<atoms.size(); ++i) {
     215         240 :     if(i%25==0) {
     216          10 :       log<<"\n";
     217             :     }
     218         240 :     log.printf("%d ",atoms[i].serial());
     219             :   }
     220           2 :   log.printf("\n");
     221             : 
     222           2 :   if(nopbc) {
     223           0 :     log<<"  PBC will be ignored\n";
     224             :   } else {
     225           2 :     log<<"  broken molecules will be rebuilt assuming atoms are in the proper order\n";
     226             :   }
     227             : 
     228             : 
     229           2 :   addValueWithDerivatives();
     230           2 :   setNotPeriodic();
     231           2 :   requestAtoms(atoms);
     232             : 
     233           2 :   natoms = getNumberOfAtoms();
     234           2 :   AtomResidueName.resize(2);
     235           2 :   LCPOparam.resize(natoms);
     236           2 :   MaxSurf.resize(natoms);
     237           2 :   DeltaG.resize(natoms+1);
     238           2 :   Nlist.resize(natoms);
     239             : 
     240             : 
     241           2 : }
     242             : 
     243             : 
     244             : //splits strings into tokens. Used to read into LCPO parameters file and into reference pdb file
     245             : template <class Container>
     246           0 : void split(const std::string& str, Container& cont) {
     247           0 :   std::istringstream iss(str);
     248           0 :   std::copy(std::istream_iterator<std::string>(iss),
     249           0 :             std::istream_iterator<std::string>(),
     250             :             std::back_inserter(cont));
     251           0 : }
     252             : 
     253             : 
     254             : //reads input PDB file provided with MOLINFO, and assigns atom and residue names to each atom involved in the CV
     255             : 
     256           2 : void SASA_LCPO::readPDB() {
     257           2 :   auto* moldat = plumed.getActionSet().selectLatest<GenericMolInfo*>(this);
     258           2 :   if( ! moldat ) {
     259           0 :     error("Unable to find MOLINFO in input");
     260             :   }
     261             :   AtomResidueName[0].clear();
     262             :   AtomResidueName[1].clear();
     263             : 
     264         242 :   for(unsigned i=0; i<natoms; i++) {
     265         240 :     string Aname = moldat->getAtomName(atoms[i]);
     266         240 :     string Rname = moldat->getResidueName(atoms[i]);
     267         240 :     AtomResidueName[0].push_back (Aname);
     268         240 :     AtomResidueName[1].push_back (Rname);
     269             :   }
     270             : 
     271           2 : }
     272             : 
     273             : //LCPO parameters database
     274           2 : map<string, vector<double> > SASA_LCPO::setupLCPOparam() {
     275             :   map<string, vector<double> > lcpomap;
     276           2 :   lcpomap["ALA_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
     277           2 :   lcpomap["ALA_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
     278           2 :   lcpomap["ALA_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
     279           2 :   lcpomap["ALA_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
     280           2 :   lcpomap["ALA_CB"] = { 1.7,  0.77887,  -0.28063,  -0.0012968,  0.00039328};
     281           2 :   lcpomap["ASP_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
     282           2 :   lcpomap["ASP_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
     283           2 :   lcpomap["ASP_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
     284           2 :   lcpomap["ASP_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
     285           2 :   lcpomap["ASP_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
     286           2 :   lcpomap["ASP_CG"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
     287           2 :   lcpomap["ASP_OD1"] = { 1.6,  0.77914,  -0.25262,  -0.0016056,  0.00035071};
     288           2 :   lcpomap["ASP_OD2"] = { 1.6,  0.77914,  -0.25262,  -0.0016056,  0.00035071};
     289           2 :   lcpomap["ASN_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
     290           2 :   lcpomap["ASN_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
     291           2 :   lcpomap["ASN_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
     292           2 :   lcpomap["ASN_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
     293           2 :   lcpomap["ASN_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
     294           2 :   lcpomap["ASN_CG"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
     295           2 :   lcpomap["ASN_OD1"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
     296           2 :   lcpomap["ASN_ND2"] = { 1.65,  0.73511,  -0.22116,  -0.00089148,  0.0002523};
     297           2 :   lcpomap["ARG_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
     298           2 :   lcpomap["ARG_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
     299           2 :   lcpomap["ARG_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
     300           2 :   lcpomap["ARG_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
     301           2 :   lcpomap["ARG_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
     302           2 :   lcpomap["ARG_CG"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
     303           2 :   lcpomap["ARG_CD"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
     304           2 :   lcpomap["ARG_NE"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
     305           2 :   lcpomap["ARG_NH1"] = { 1.65,  0.73511,  -0.22116,  -0.00089148,  0.0002523};
     306           2 :   lcpomap["ARG_NH2"] = { 1.65,  0.73511,  -0.22116,  -0.00089148,  0.0002523};
     307           2 :   lcpomap["ARG_CZ"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
     308           2 :   lcpomap["CYS_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
     309           2 :   lcpomap["CYS_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
     310           2 :   lcpomap["CYS_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
     311           2 :   lcpomap["CYS_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
     312           2 :   lcpomap["CYS_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
     313           2 :   lcpomap["CYS_SG"] = { 1.9,  0.54581,  -0.19477,  -0.0012873,  0.00029247};
     314           2 :   lcpomap["GLU_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
     315           2 :   lcpomap["GLU_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
     316           2 :   lcpomap["GLU_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
     317           2 :   lcpomap["GLU_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
     318           2 :   lcpomap["GLU_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
     319           2 :   lcpomap["GLU_CG"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
     320           2 :   lcpomap["GLU_CD"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
     321           2 :   lcpomap["GLU_OE1"] = { 1.6,  0.77914,  -0.25262,  -0.0016056,  0.00035071};
     322           2 :   lcpomap["GLU_OE2"] = { 1.6,  0.77914,  -0.25262,  -0.0016056,  0.00035071};
     323           2 :   lcpomap["GLN_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
     324           2 :   lcpomap["GLN_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
     325           2 :   lcpomap["GLN_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
     326           2 :   lcpomap["GLN_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
     327           2 :   lcpomap["GLN_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
     328           2 :   lcpomap["GLN_CG"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
     329           2 :   lcpomap["GLN_CD"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
     330           2 :   lcpomap["GLN_OE1"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
     331           2 :   lcpomap["GLN_NE2"] = { 1.65,  0.73511,  -0.22116,  -0.00089148,  0.0002523};
     332           2 :   lcpomap["GLY_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
     333           2 :   lcpomap["GLY_CA"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
     334           2 :   lcpomap["GLY_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
     335           2 :   lcpomap["GLY_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
     336           2 :   lcpomap["HIS_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
     337           2 :   lcpomap["HIS_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
     338           2 :   lcpomap["HIS_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
     339           2 :   lcpomap["HIS_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
     340           2 :   lcpomap["HIS_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
     341           2 :   lcpomap["HIS_CG"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
     342           2 :   lcpomap["HIS_ND1"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
     343           2 :   lcpomap["HIS_CE1"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
     344           2 :   lcpomap["HIS_NE2"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
     345           2 :   lcpomap["HIS_CD2"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
     346           2 :   lcpomap["ILE_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
     347           2 :   lcpomap["ILE_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
     348           2 :   lcpomap["ILE_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
     349           2 :   lcpomap["ILE_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
     350           2 :   lcpomap["ILE_CB"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
     351           2 :   lcpomap["ILE_CG2"] = { 1.7,  0.77887,  -0.28063,  -0.0012968,  0.00039328};
     352           2 :   lcpomap["ILE_CG1"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
     353           2 :   lcpomap["ILE_CD1"] = { 1.7,  0.77887,  -0.28063,  -0.0012968,  0.00039328};
     354           2 :   lcpomap["LEU_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
     355           2 :   lcpomap["LEU_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
     356           2 :   lcpomap["LEU_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
     357           2 :   lcpomap["LEU_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
     358           2 :   lcpomap["LEU_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
     359           2 :   lcpomap["LEU_CG"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
     360           2 :   lcpomap["LEU_CD1"] = { 1.7,  0.77887,  -0.28063,  -0.0012968,  0.00039328};
     361           2 :   lcpomap["LEU_CD2"] = { 1.7,  0.77887,  -0.28063,  -0.0012968,  0.00039328};
     362           2 :   lcpomap["LYS_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
     363           2 :   lcpomap["LYS_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
     364           2 :   lcpomap["LYS_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
     365           2 :   lcpomap["LYS_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
     366           2 :   lcpomap["LYS_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
     367           2 :   lcpomap["LYS_CG"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
     368           2 :   lcpomap["LYS_CD"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
     369           2 :   lcpomap["LYS_CE"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
     370           2 :   lcpomap["LYS_NZ"] = { 1.65,  0.73511,  -0.22116,  -0.00089148,  0.0002523};
     371           2 :   lcpomap["MET_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
     372           2 :   lcpomap["MET_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
     373           2 :   lcpomap["MET_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
     374           2 :   lcpomap["MET_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
     375           2 :   lcpomap["MET_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
     376           2 :   lcpomap["MET_CG"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
     377           2 :   lcpomap["MET_SD"] = { 1.9,  0.54581,  -0.19477,  -0.0012873,  0.00029247};
     378           2 :   lcpomap["MET_CE"] = { 1.7,  0.77887,  -0.28063,  -0.0012968,  0.00039328};
     379           2 :   lcpomap["PHE_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
     380           2 :   lcpomap["PHE_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
     381           2 :   lcpomap["PHE_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
     382           2 :   lcpomap["PHE_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
     383           2 :   lcpomap["PHE_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
     384           2 :   lcpomap["PHE_CG"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
     385           2 :   lcpomap["PHE_CD1"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
     386           2 :   lcpomap["PHE_CE1"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
     387           2 :   lcpomap["PHE_CZ"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
     388           2 :   lcpomap["PHE_CE2"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
     389           2 :   lcpomap["PHE_CD2"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
     390           2 :   lcpomap["PRO_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
     391           2 :   lcpomap["PRO_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
     392           2 :   lcpomap["PRO_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
     393           2 :   lcpomap["PRO_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
     394           2 :   lcpomap["PRO_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
     395           2 :   lcpomap["PRO_CG"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
     396           2 :   lcpomap["PRO_CD"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
     397           2 :   lcpomap["SER_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
     398           2 :   lcpomap["SER_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
     399           2 :   lcpomap["SER_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
     400           2 :   lcpomap["SER_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
     401           2 :   lcpomap["SER_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
     402           2 :   lcpomap["SER_OG"] = { 1.6,  0.77914,  -0.25262,  -0.0016056,  0.00035071};
     403           2 :   lcpomap["THR_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
     404           2 :   lcpomap["THR_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
     405           2 :   lcpomap["THR_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
     406           2 :   lcpomap["THR_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
     407           2 :   lcpomap["THR_CB"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
     408           2 :   lcpomap["THR_CG2"] = { 1.7,  0.77887,  -0.28063,  -0.0012968,  0.00039328};
     409           2 :   lcpomap["THR_OG1"] = { 1.6,  0.77914,  -0.25262,  -0.0016056,  0.00035071};
     410           2 :   lcpomap["TRP_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
     411           2 :   lcpomap["TRP_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
     412           2 :   lcpomap["TRP_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
     413           2 :   lcpomap["TRP_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
     414           2 :   lcpomap["TRP_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
     415           2 :   lcpomap["TRP_CG"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
     416           2 :   lcpomap["TRP_CD1"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
     417           2 :   lcpomap["TRP_NE1"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
     418           2 :   lcpomap["TRP_CE2"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
     419           2 :   lcpomap["TRP_CZ2"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
     420           2 :   lcpomap["TRP_CH2"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
     421           2 :   lcpomap["TRP_CZ3"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
     422           2 :   lcpomap["TRP_CE3"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
     423           2 :   lcpomap["TRP_CD2"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
     424           2 :   lcpomap["TYR_N"] = { 1.65,  0.062577,  -0.017874,  -8.312e-05,  1.9849e-05};
     425           2 :   lcpomap["TYR_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
     426           2 :   lcpomap["TYR_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
     427           2 :   lcpomap["TYR_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
     428           2 :   lcpomap["TYR_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
     429           2 :   lcpomap["TYR_CG"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
     430           2 :   lcpomap["TYR_CD1"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
     431           2 :   lcpomap["TYR_CE1"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
     432           2 :   lcpomap["TYR_CZ"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
     433           2 :   lcpomap["TYR_OH"] = { 1.6,  0.77914,  -0.25262,  -0.0016056,  0.00035071};
     434           2 :   lcpomap["TYR_CE2"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
     435           2 :   lcpomap["TYR_CD2"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
     436           2 :   lcpomap["VAL_N"] = { 1.65,  0.062577,  -0.017874,  -8.312e-05,  1.9849e-05};
     437           2 :   lcpomap["VAL_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
     438           2 :   lcpomap["VAL_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
     439           2 :   lcpomap["VAL_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
     440           2 :   lcpomap["VAL_CB"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
     441           2 :   lcpomap["VAL_CG1"] = { 1.7,  0.77887,  -0.28063,  -0.0012968,  0.00039328};
     442           2 :   lcpomap["VAL_CG2"] = { 1.7,  0.77887,  -0.28063,  -0.0012968,  0.00039328};
     443           2 :   return lcpomap;
     444             : }
     445             : 
     446             : //assigns LCPO parameters to each atom reading from database
     447           2 : void SASA_LCPO::readLCPOparam() {
     448             : 
     449         242 :   for(unsigned i=0; i<natoms; i++) {
     450         240 :     LCPOparam[i].clear();
     451             :   }
     452             : 
     453             :   map<string, vector<double> > lcpomap;
     454           4 :   lcpomap = setupLCPOparam();
     455             :   vector<double> LCPOparamVector;
     456             :   string identifier;
     457         242 :   for(unsigned i=0; i<natoms; i++) {
     458         240 :     if ((AtomResidueName[0][i][0]=='O') || (AtomResidueName[0][i][0]=='N') || (AtomResidueName[0][i][0]=='C') || (AtomResidueName[0][i][0]=='S')) {
     459         240 :       identifier = AtomResidueName[1][i]+"_"+AtomResidueName[0][i];
     460         120 :       LCPOparamVector = lcpomap.at(identifier);
     461         120 :       LCPOparam[i].push_back (LCPOparamVector[0]+rs*10);
     462         120 :       LCPOparam[i].push_back (LCPOparamVector[1]);
     463         120 :       LCPOparam[i].push_back (LCPOparamVector[2]);
     464         120 :       LCPOparam[i].push_back (LCPOparamVector[3]);
     465         120 :       LCPOparam[i].push_back (LCPOparamVector[4]);
     466             :     }
     467             :   }
     468             : 
     469             : 
     470         242 :   for(unsigned i=0; i<natoms; i++) {
     471         240 :     if (LCPOparam[i].size()==0 ) {
     472         120 :       if ((AtomResidueName[0][i][0]=='O') || (AtomResidueName[0][i][0]=='N') || (AtomResidueName[0][i][0]=='C') || (AtomResidueName[0][i][0]=='S')) {
     473           0 :         cout << "Could not find LCPO paramaters for atom " << AtomResidueName[0][i] << " of residue " << AtomResidueName[1][i] << endl;
     474           0 :         error ("missing LCPO parameters\n");
     475             :       }
     476             :     }
     477             :   }
     478             : 
     479           2 :   if (AtomResidueName[0][0] == "N") {
     480           2 :     LCPOparam[0][1] = 7.3511e-01;
     481           2 :     LCPOparam[0][2] = -2.2116e-01;
     482           2 :     LCPOparam[0][3] = -8.9148e-04;
     483           2 :     LCPOparam[0][4] = 2.5230e-04;
     484             :   }
     485             : 
     486           2 :   if (AtomResidueName[0][natoms-1] == "O") {
     487           2 :     LCPOparam[natoms-1][1] = 8.8857e-01;
     488           2 :     LCPOparam[natoms-1][2] = -3.3421e-01;
     489           2 :     LCPOparam[natoms-1][3] = -1.8683e-03;
     490           2 :     LCPOparam[natoms-1][4] = 4.9372e-04;
     491             :   }
     492           2 : }
     493             : 
     494             : 
     495             : //Max Surf values, used only if TYPE=TRANSFER
     496           1 : map<string, vector<double> > SASA_LCPO::setupMaxSurfMap() {
     497             :   // Max Surface Area for backbone and sidechain, in nm2
     498             :   map<string, vector<double> > valuemap;
     499           1 :   valuemap ["ALA"]= {0.671446,0.420263,};
     500           1 :   valuemap ["ARG"]= {0.578582,1.95454,};
     501           1 :   valuemap ["ASN"]= {0.559411,1.07102,};
     502           1 :   valuemap ["ASP"]= {0.558363,1.03971,};
     503           1 :   valuemap ["CYS"]= {0.609271,0.657612,};
     504           1 :   valuemap ["GLN"]= {0.565651,1.433031,};
     505           1 :   valuemap ["GLU"]= {0.572399,1.41848,};
     506           1 :   valuemap ["GLY"]= {0.861439,0,};
     507           1 :   valuemap ["HIS"]= {0.559929,1.143827,};
     508           1 :   valuemap ["ILE"]= {0.553491,1.25334,};
     509           1 :   valuemap ["LEU"]= {0.570103,1.260459,};
     510           1 :   valuemap ["LYS"]= {0.580304,1.687487,};
     511           1 :   valuemap ["MET"]= {0.5856,1.498954,};
     512           1 :   valuemap ["PHE"]= {0.54155,1.394861,};
     513           1 :   valuemap ["PRO"]= {0.456048,0.849461,};
     514           1 :   valuemap ["SER"]= {0.59074,0.714538,};
     515           1 :   valuemap ["THR"]= {0.559116,0.951644,};
     516           1 :   valuemap ["TRP"]= {0.55536,1.59324,};
     517           1 :   valuemap ["TYR"]= {0.451171,1.566918,};
     518           1 :   valuemap ["VAL"]= {0.454809,0.928685,};
     519           1 :   return valuemap;
     520             : }
     521             : 
     522             : 
     523             : 
     524             : //reads maximum surface values per residue type and assigns values to each atom, only used if sasa_type = TRANSFER
     525             : 
     526           1 : void SASA_LCPO::readMaxSurf() {
     527             :   map<string, vector<double> > valuemap;
     528           2 :   valuemap = setupMaxSurfMap();
     529             :   vector<double> MaxSurfVector;
     530             : 
     531         121 :   for(unsigned i=0; i<natoms; i++) {
     532         120 :     MaxSurf[i].clear();
     533         120 :     MaxSurfVector = valuemap.at(AtomResidueName[1][i]);
     534         120 :     MaxSurf[i].push_back (MaxSurfVector[0]*100);
     535         120 :     MaxSurf[i].push_back (MaxSurfVector[1]*100);
     536             :   }
     537           1 : }
     538             : 
     539             : //reads file with free energy values for sidechains and for the backbone, and assigns values to each atom. Only used if sasa_type = TRANSFER
     540             : 
     541           1 : void SASA_LCPO::readDeltaG() {
     542             : 
     543         121 :   for(unsigned i=0; i<natoms; i++) {
     544         120 :     DeltaG[i].clear();
     545             :   }
     546             : 
     547             :   string DeltaGline;
     548           1 :   fstream DeltaGFile;
     549           1 :   DeltaGFile.open(DeltaGValues);
     550           1 :   if (DeltaGFile) {
     551             :     int backboneflag = 0;
     552          23 :     while(getline(DeltaGFile, DeltaGline)) {
     553          22 :       if(!DeltaGline.empty()) {
     554             :         std::vector<std::string> DeltaGtoken;
     555          21 :         split(DeltaGline, DeltaGtoken);
     556        2541 :         for(unsigned i=0; i<natoms; i++) {
     557        2520 :           if (DeltaGtoken[0].compare(AtomResidueName[1][i])==0 ) {
     558         120 :             DeltaG[i].push_back (std::atof(DeltaGtoken[1].c_str()));
     559             :           }
     560             :         }
     561          21 :         if (DeltaGtoken[0].compare("BACKBONE")==0 ) {
     562             :           backboneflag = 1;
     563           1 :           DeltaG[natoms].push_back (std::atof(DeltaGtoken[1].c_str()));
     564             :         }
     565          21 :       }
     566             :     }
     567           1 :     if ( backboneflag == 0) {
     568           0 :       error("Cannot find backbone value in Delta G parameters file\n");
     569             :     }
     570             :   } else {
     571           0 :     error("Cannot open DeltaG file");
     572             :   }
     573             : 
     574         121 :   for(unsigned i=0; i<natoms; i++) {
     575         120 :     if (DeltaG[i].size()==0 ) {
     576           0 :       cout << "Delta G value for residue " << AtomResidueName[1][i] << " not found " << endl;
     577           0 :       error ("missing Delta G parameter\n");
     578             :     }
     579             :   }
     580             : 
     581           2 : }
     582             : 
     583             : //computes free energy values for the sidechains and for the backbone, and assigns values to each atom. Only used if sasa_type = TRANSFER, and if no DELTAGFILE is provided. In this case, the free energy values are those describing the effect of temperature, and the program must know if approach 2 or 3 (as described in Arsiccio and Shea, Protein Cold Denaturation in Implicit Solvent Simulations: A Transfer Free Energy Approach, JPCB, 2021) needs to be used to compute them.
     584             : 
     585           0 : void SASA_LCPO::computeDeltaG() {
     586             : 
     587           0 :   for(unsigned i=0; i<natoms; i++) {
     588           0 :     DeltaG[i].clear();
     589             :   }
     590             : 
     591             :   double T;
     592           0 :   T = plumed.getAtoms().getKbT()/plumed.getAtoms().getKBoltzmann();
     593             : 
     594           0 :   if (T != Ti) {
     595           0 :     for(unsigned i=0; i<natoms; i++) {
     596           0 :       if (approach==2) {
     597           0 :         if (AtomResidueName[1][i].compare("ALA")==0) {
     598           0 :           DeltaG[i].push_back (-2.995/1000*std::pow(T,2)+1.808*T-272.895);
     599             :         }
     600           0 :         if (AtomResidueName[1][i].compare("ARG")==0) {
     601           0 :           DeltaG[i].push_back (-3.182/1000*std::pow(T,2)+1.894*T-282.032);
     602             :         }
     603           0 :         if (AtomResidueName[1][i].compare("ASN")==0) {
     604           0 :           DeltaG[i].push_back (-1.047/1000*std::pow(T,2)+0.6068*T-87.846);
     605             :         }
     606           0 :         if (AtomResidueName[1][i].compare("ASP")==0) {
     607           0 :           DeltaG[i].push_back (-0.1794/1000*std::pow(T,2)+0.1091*T-16.526);
     608             :         }
     609           0 :         if (AtomResidueName[1][i].compare("CYS")==0) {
     610           0 :           DeltaG[i].push_back (-3.09/1000*std::pow(T,2)+1.835*T-272.26);
     611             :         }
     612           0 :         if (AtomResidueName[1][i].compare("GLN")==0) {
     613           0 :           DeltaG[i].push_back (-2.23/1000*std::pow(T,2)+1.335*T-199.707);
     614             :         }
     615           0 :         if (AtomResidueName[1][i].compare("GLU")==0) {
     616           0 :           DeltaG[i].push_back (-1.511/1000*std::pow(T,2)+0.8904*T-131.168);
     617             :         }
     618           0 :         if (AtomResidueName[1][i].compare("GLY")==0) {
     619           0 :           DeltaG[i].push_back (0);
     620             :         }
     621           0 :         if (AtomResidueName[1][i].compare("HIS")==0) {
     622           0 :           DeltaG[i].push_back (-3.482/1000*std::pow(T,2)+2.084*T-311.694);
     623             :         }
     624           0 :         if (AtomResidueName[1][i].compare("ILE")==0) {
     625           0 :           DeltaG[i].push_back (-6.364/1000*std::pow(T,2)+3.8*T-567.444);
     626             :         }
     627           0 :         if (AtomResidueName[1][i].compare("LEU")==0) {
     628           0 :           DeltaG[i].push_back (-7.466/1000*std::pow(T,2)+4.417*T-653.394);
     629             :         }
     630           0 :         if (AtomResidueName[1][i].compare("LYS")==0) {
     631           0 :           DeltaG[i].push_back (-2.091/1000*std::pow(T,2)+1.2458*T-185.549);
     632             :         }
     633           0 :         if (AtomResidueName[1][i].compare("MET")==0) {
     634           0 :           DeltaG[i].push_back (-3.807/1000*std::pow(T,2)+2.272*T-339.007);
     635             :         }
     636           0 :         if (AtomResidueName[1][i].compare("PHE")==0) {
     637           0 :           DeltaG[i].push_back (-7.828/1000*std::pow(T,2)+4.644*T-688.874);
     638             :         }
     639           0 :         if (AtomResidueName[1][i].compare("PRO")==0) {
     640           0 :           DeltaG[i].push_back (-2.347/1000*std::pow(T,2)+1.411*T-212.059);
     641             :         }
     642           0 :         if (AtomResidueName[1][i].compare("SER")==0) {
     643           0 :           DeltaG[i].push_back (1.813/1000*std::pow(T,2)-1.05*T+151.957);
     644             :         }
     645           0 :         if (AtomResidueName[1][i].compare("THR")==0) {
     646           0 :           DeltaG[i].push_back (-2.64/1000*std::pow(T,2)+1.591*T-239.516);
     647             :         }
     648           0 :         if (AtomResidueName[1][i].compare("TRP")==0) {
     649           0 :           DeltaG[i].push_back (-11.66/1000*std::pow(T,2)+6.916*T-1025.293);
     650             :         }
     651           0 :         if (AtomResidueName[1][i].compare("TYR")==0) {
     652           0 :           DeltaG[i].push_back (-7.513/1000*std::pow(T,2)+4.478*T-667.261);
     653             :         }
     654           0 :         if (AtomResidueName[1][i].compare("VAL")==0) {
     655           0 :           DeltaG[i].push_back (-4.902/1000*std::pow(T,2)+2.921*T-435.309);
     656             :         }
     657           0 :         DeltaG[natoms].push_back (-0.6962/1000*std::pow(T,2)+0.4426*T-70.015);
     658             :       }
     659           0 :       if (approach==3) {
     660           0 :         if (AtomResidueName[1][i].compare("ALA")==0) {
     661           0 :           DeltaG[i].push_back (-2.995/1000*std::pow(T,2)+1.808*T-272.105);
     662             :         }
     663           0 :         if (AtomResidueName[1][i].compare("ARG")==0) {
     664           0 :           DeltaG[i].push_back (-3.182/1000*std::pow(T,2)+1.894*T-284.086);
     665             :         }
     666           0 :         if (AtomResidueName[1][i].compare("ASN")==0) {
     667           0 :           DeltaG[i].push_back (-1.047/1000*std::pow(T,2)+0.6068*T-90.597);
     668             :         }
     669           0 :         if (AtomResidueName[1][i].compare("ASP")==0) {
     670           0 :           DeltaG[i].push_back (-0.1794/1000*std::pow(T,2)+0.1091*T-19.143);
     671             :         }
     672           0 :         if (AtomResidueName[1][i].compare("CYS")==0) {
     673           0 :           DeltaG[i].push_back (-3.09/1000*std::pow(T,2)+1.835*T-268.527);
     674             :         }
     675           0 :         if (AtomResidueName[1][i].compare("GLN")==0) {
     676           0 :           DeltaG[i].push_back (-2.23/1000*std::pow(T,2)+1.335*T-201.559);
     677             :         }
     678           0 :         if (AtomResidueName[1][i].compare("GLU")==0) {
     679           0 :           DeltaG[i].push_back (-1.511/1000*std::pow(T,2)+0.8904*T-133.543);
     680             :         }
     681           0 :         if (AtomResidueName[1][i].compare("GLY")==0) {
     682           0 :           DeltaG[i].push_back (0);
     683             :         }
     684           0 :         if (AtomResidueName[1][i].compare("HIS")==0) {
     685           0 :           DeltaG[i].push_back (-3.482/1000*std::pow(T,2)+2.084*T-315.398);
     686             :         }
     687           0 :         if (AtomResidueName[1][i].compare("ILE")==0) {
     688           0 :           DeltaG[i].push_back (-6.364/1000*std::pow(T,2)+3.8*T-564.825);
     689             :         }
     690           0 :         if (AtomResidueName[1][i].compare("LEU")==0) {
     691           0 :           DeltaG[i].push_back (-7.466/1000*std::pow(T,2)+4.417*T-651.483);
     692             :         }
     693           0 :         if (AtomResidueName[1][i].compare("LYS")==0) {
     694           0 :           DeltaG[i].push_back (-2.091/1000*std::pow(T,2)+1.2458*T-187.485);
     695             :         }
     696           0 :         if (AtomResidueName[1][i].compare("MET")==0) {
     697           0 :           DeltaG[i].push_back (-3.807/1000*std::pow(T,2)+2.272*T-339.242);
     698             :         }
     699           0 :         if (AtomResidueName[1][i].compare("PHE")==0) {
     700           0 :           DeltaG[i].push_back (-7.828/1000*std::pow(T,2)+4.644*T-687.134);
     701             :         }
     702           0 :         if (AtomResidueName[1][i].compare("PRO")==0) {
     703           0 :           DeltaG[i].push_back (-2.347/1000*std::pow(T,2)+1.411*T-214.211);
     704             :         }
     705           0 :         if (AtomResidueName[1][i].compare("SER")==0) {
     706           0 :           DeltaG[i].push_back (1.813/1000*std::pow(T,2)-1.05*T+150.289);
     707             :         }
     708           0 :         if (AtomResidueName[1][i].compare("THR")==0) {
     709           0 :           DeltaG[i].push_back (-2.64/1000*std::pow(T,2)+1.591*T-240.267);
     710             :         }
     711           0 :         if (AtomResidueName[1][i].compare("TRP")==0) {
     712           0 :           DeltaG[i].push_back (-11.66/1000*std::pow(T,2)+6.916*T-1024.284);
     713             :         }
     714           0 :         if (AtomResidueName[1][i].compare("TYR")==0) {
     715           0 :           DeltaG[i].push_back (-7.513/1000*std::pow(T,2)+4.478*T-666.484);
     716             :         }
     717           0 :         if (AtomResidueName[1][i].compare("VAL")==0) {
     718           0 :           DeltaG[i].push_back (-4.902/1000*std::pow(T,2)+2.921*T-433.013);
     719             :         }
     720           0 :         DeltaG[natoms].push_back (-0.6927/1000*std::pow(T,2)+0.4404*T-68.724);
     721             :       }
     722             :     }
     723             :   }
     724             : 
     725           0 :   Ti = T;
     726             : 
     727           0 :   if (firstStepFlag ==0) {
     728           0 :     if (approach!=2 && approach!=3) {
     729           0 :       cout << "Unknown approach " << approach << endl;
     730             :     }
     731           0 :     for(unsigned i=0; i<natoms; i++) {
     732           0 :       if (DeltaG[i].size()==0 ) {
     733           0 :         cout << "Delta G value for residue " << AtomResidueName[1][i] << " not found " << endl;
     734           0 :         error ("missing Delta G parameter\n");
     735             :       }
     736             :     }
     737             :   }
     738           0 : }
     739             : 
     740             : 
     741             : //calculates neighbor list
     742          24 : void SASA_LCPO::calcNlist() {
     743          24 :   if(!nopbc) {
     744          24 :     makeWhole();
     745             :   }
     746             : 
     747        2904 :   for(unsigned i = 0; i < natoms; i++) {
     748        2880 :     Nlist[i].clear();
     749             :   }
     750             : 
     751        2904 :   for(unsigned i = 0; i < natoms; i++) {
     752        2880 :     if (LCPOparam[i].size()>0) {
     753       87264 :       for (unsigned j = 0; j < i; j++) {
     754       85824 :         if (LCPOparam[j].size()>0) {
     755       42480 :           const Vector Delta_ij_vec = delta( getPosition(i), getPosition(j) );
     756       42480 :           double Delta_ij_mod = Delta_ij_vec.modulo()*10;
     757       42480 :           double overlapD = LCPOparam[i][0]+LCPOparam[j][0];
     758       42480 :           if (Delta_ij_mod < overlapD) {
     759       19030 :             Nlist.at(i).push_back (j);
     760       19030 :             Nlist.at(j).push_back (i);
     761             :           }
     762             :         }
     763             :       }
     764             :     }
     765             :   }
     766          24 : }
     767             : 
     768             : 
     769             : //calculates SASA according to LCPO algorithm
     770          24 : void SASA_LCPO::calculate() {
     771          24 :   if(!nopbc) {
     772          24 :     makeWhole();
     773             :   }
     774             : 
     775          24 :   if(getExchangeStep()) {
     776           0 :     nl_update = 0;
     777             :   }
     778          24 :   if (firstStepFlag ==0) {
     779           2 :     readPDB();
     780           2 :     readLCPOparam();
     781             :   }
     782          24 :   if (nl_update == 0) {
     783          24 :     calcNlist();
     784             :   }
     785             : 
     786             : 
     787             : 
     788             :   double S1, Aij, Ajk, Aijk, Aijt, Ajkt, Aikt;
     789             :   double dAdd;
     790          24 :   double sasa = 0;
     791          24 :   vector<Vector> derivatives( natoms );
     792          24 :   Tensor virial;
     793          24 :   vector <double> dAijdc_2t(3);
     794          24 :   vector <double> dSASA_2_neigh_dc(3);
     795          24 :   vector <double> ddij_di(3);
     796          24 :   vector <double> ddik_di(3);
     797             : 
     798          24 :   if( sasa_type==TOTAL ) {
     799        1452 :     for(unsigned i = 0; i < natoms; i++) {
     800        1440 :       derivatives[i][0] = 0.;
     801        1440 :       derivatives[i][1] = 0.;
     802        1440 :       derivatives[i][2] = 0.;
     803        1440 :       if ( LCPOparam[i].size()>1) {
     804         720 :         if (LCPOparam[i][1]>0.0) {
     805             :           Aij = 0.0;
     806             :           Aijk = 0.0;
     807             :           Ajk = 0.0;
     808         720 :           double ri = LCPOparam[i][0];
     809         720 :           S1 = 4*M_PI*ri*ri;
     810         720 :           vector <double> dAijdc_2(3, 0);
     811         720 :           vector <double> dAijdc_4(3, 0);
     812             : 
     813             : 
     814       19750 :           for (unsigned j = 0; j < Nlist[i].size(); j++) {
     815       19030 :             const Vector d_ij_vec = delta( getPosition(i), getPosition(Nlist[i][j]) );
     816       19030 :             double d_ij = d_ij_vec.modulo()*10;
     817             : 
     818       19030 :             double rj = LCPOparam[Nlist[i][j]][0];
     819       19030 :             Aijt = (2*M_PI*ri*(ri-d_ij/2-((ri*ri-rj*rj)/(2*d_ij))));
     820       19030 :             double sji = (2*M_PI*rj*(rj-d_ij/2+((ri*ri-rj*rj)/(2*d_ij))));
     821             : 
     822       19030 :             dAdd = M_PI*rj*(-(ri*ri-rj*rj)/(d_ij*d_ij)-1);
     823             : 
     824       19030 :             ddij_di[0] = -10*(getPosition(Nlist[i][j])[0]-getPosition(i)[0])/d_ij;
     825       19030 :             ddij_di[1] = -10*(getPosition(Nlist[i][j])[1]-getPosition(i)[1])/d_ij;
     826       19030 :             ddij_di[2] = -10*(getPosition(Nlist[i][j])[2]-getPosition(i)[2])/d_ij;
     827             : 
     828             :             Ajkt = 0.0;
     829             :             Aikt = 0.0;
     830             : 
     831       19030 :             vector <double> dSASA_3_neigh_dc(3, 0.0);
     832       19030 :             vector <double> dSASA_4_neigh_dc(3, 0.0);
     833       19030 :             vector <double> dSASA_3_neigh_dc2(3, 0.0);
     834       19030 :             vector <double> dSASA_4_neigh_dc2(3, 0.0);
     835             : 
     836       19030 :             dSASA_2_neigh_dc[0] = dAdd * ddij_di[0];
     837       19030 :             dSASA_2_neigh_dc[1] = dAdd * ddij_di[1];
     838       19030 :             dSASA_2_neigh_dc[2] = dAdd * ddij_di[2];
     839             : 
     840       19030 :             dAdd = M_PI*ri*((ri*ri-rj*rj)/(d_ij*d_ij)-1);
     841             : 
     842             : 
     843       19030 :             dAijdc_2t[0] = dAdd * ddij_di[0];
     844       19030 :             dAijdc_2t[1] = dAdd * ddij_di[1];
     845       19030 :             dAijdc_2t[2] = dAdd * ddij_di[2];
     846             : 
     847      560038 :             for (unsigned k = 0; k < Nlist[Nlist[i][j]].size(); k++) {
     848      541008 :               if (std::find (Nlist[i].begin(), Nlist[i].end(), Nlist[Nlist[i][j]][k]) !=  Nlist[i].end()) {
     849      370872 :                 const Vector d_jk_vec = delta( getPosition(Nlist[i][j]), getPosition(Nlist[Nlist[i][j]][k]) );
     850      370872 :                 const Vector d_ik_vec = delta( getPosition(i), getPosition(Nlist[Nlist[i][j]][k]) );
     851             : 
     852      370872 :                 double d_jk = d_jk_vec.modulo()*10;
     853      370872 :                 double d_ik = d_ik_vec.modulo()*10;
     854             : 
     855      370872 :                 double rk = LCPOparam[Nlist[Nlist[i][j]][k]][0];
     856      370872 :                 double sjk =  (2*M_PI*rj*(rj-d_jk/2-((rj*rj-rk*rk)/(2*d_jk))));
     857      370872 :                 Ajkt += sjk;
     858      370872 :                 Aikt += (2*M_PI*ri*(ri-d_ik/2-((ri*ri-rk*rk)/(2*d_ik))));
     859             : 
     860      370872 :                 dAdd = M_PI*ri*((ri*ri-rk*rk)/(d_ik*d_ik)-1);
     861             : 
     862      370872 :                 ddik_di[0] = -10*(getPosition(Nlist[Nlist[i][j]][k])[0]-getPosition(i)[0])/d_ik;
     863      370872 :                 ddik_di[1] = -10*(getPosition(Nlist[Nlist[i][j]][k])[1]-getPosition(i)[1])/d_ik;
     864      370872 :                 ddik_di[2] = -10*(getPosition(Nlist[Nlist[i][j]][k])[2]-getPosition(i)[2])/d_ik;
     865             : 
     866             : 
     867      370872 :                 dSASA_3_neigh_dc[0] += dAdd*ddik_di[0];
     868      370872 :                 dSASA_3_neigh_dc[1] += dAdd*ddik_di[1];
     869      370872 :                 dSASA_3_neigh_dc[2] += dAdd*ddik_di[2];
     870             : 
     871      370872 :                 dAdd = M_PI*rk*(-(ri*ri-rk*rk)/(d_ik*d_ik)-1);
     872             : 
     873      370872 :                 dSASA_3_neigh_dc2[0] += dAdd*ddik_di[0];
     874      370872 :                 dSASA_3_neigh_dc2[1] += dAdd*ddik_di[1];
     875      370872 :                 dSASA_3_neigh_dc2[2] += dAdd*ddik_di[2];
     876             : 
     877      370872 :                 dSASA_4_neigh_dc2[0] += sjk*dAdd*ddik_di[0];
     878      370872 :                 dSASA_4_neigh_dc2[1] += sjk*dAdd*ddik_di[1];
     879      370872 :                 dSASA_4_neigh_dc2[2] += sjk*dAdd*ddik_di[2];
     880             : 
     881             :               }
     882             :             }
     883       19030 :             dSASA_4_neigh_dc[0] = sji*dSASA_3_neigh_dc[0] + dSASA_4_neigh_dc2[0];
     884       19030 :             dSASA_4_neigh_dc[1] = sji*dSASA_3_neigh_dc[1] + dSASA_4_neigh_dc2[1];
     885       19030 :             dSASA_4_neigh_dc[2] = sji*dSASA_3_neigh_dc[2] + dSASA_4_neigh_dc2[2];
     886             : 
     887       19030 :             dSASA_3_neigh_dc[0] += dSASA_3_neigh_dc2[0];
     888       19030 :             dSASA_3_neigh_dc[1] += dSASA_3_neigh_dc2[1];
     889       19030 :             dSASA_3_neigh_dc[2] += dSASA_3_neigh_dc2[2];
     890             : 
     891       19030 :             dSASA_4_neigh_dc[0] += dSASA_2_neigh_dc[0] * Aikt;
     892       19030 :             dSASA_4_neigh_dc[1] += dSASA_2_neigh_dc[1] * Aikt;
     893       19030 :             dSASA_4_neigh_dc[2] += dSASA_2_neigh_dc[2] * Aikt;
     894             : 
     895             : 
     896       19030 :             derivatives[i][0] += (dSASA_2_neigh_dc[0]*LCPOparam[Nlist[i][j]][2] + dSASA_3_neigh_dc[0]*LCPOparam[Nlist[i][j]][3]+dSASA_4_neigh_dc[0]*LCPOparam[Nlist[i][j]][4])/10;
     897       19030 :             derivatives[i][1] += (dSASA_2_neigh_dc[1]*LCPOparam[Nlist[i][j]][2] + dSASA_3_neigh_dc[1]*LCPOparam[Nlist[i][j]][3]+dSASA_4_neigh_dc[1]*LCPOparam[Nlist[i][j]][4])/10;
     898       19030 :             derivatives[i][2] += (dSASA_2_neigh_dc[2]*LCPOparam[Nlist[i][j]][2] + dSASA_3_neigh_dc[2]*LCPOparam[Nlist[i][j]][3]+dSASA_4_neigh_dc[2]*LCPOparam[Nlist[i][j]][4])/10;
     899             : 
     900             : 
     901       19030 :             Aijk += (Aijt * Ajkt);
     902       19030 :             Aij += Aijt;
     903       19030 :             Ajk += Ajkt;
     904             : 
     905       19030 :             dAijdc_2[0] += dAijdc_2t[0];
     906       19030 :             dAijdc_2[1] += dAijdc_2t[1];
     907       19030 :             dAijdc_2[2] += dAijdc_2t[2];
     908             : 
     909             : 
     910       19030 :             dAijdc_4[0] += Ajkt*dAijdc_2t[0];
     911       19030 :             dAijdc_4[1] += Ajkt*dAijdc_2t[1];
     912       19030 :             dAijdc_4[2] += Ajkt*dAijdc_2t[2];
     913             : 
     914             : 
     915             :           }
     916         720 :           double sasai = (LCPOparam[i][1]*S1+LCPOparam[i][2]*Aij+LCPOparam[i][3]*Ajk+LCPOparam[i][4]*Aijk);
     917         720 :           if (sasai > 0 ) {
     918         715 :             sasa += sasai/100;
     919             :           }
     920         720 :           derivatives[i][0] += (dAijdc_2[0]*LCPOparam[i][2]+dAijdc_4[0]*LCPOparam[i][4])/10;
     921         720 :           derivatives[i][1] += (dAijdc_2[1]*LCPOparam[i][2]+dAijdc_4[1]*LCPOparam[i][4])/10;
     922         720 :           derivatives[i][2] += (dAijdc_2[2]*LCPOparam[i][2]+dAijdc_4[2]*LCPOparam[i][4])/10;
     923             :         }
     924             :       }
     925        1440 :       virial -= Tensor(getPosition(i),derivatives[i]);
     926             :     }
     927             :   }
     928             : 
     929             : 
     930             : 
     931          24 :   if( sasa_type==TRANSFER ) {
     932             : 
     933          12 :     if (firstStepFlag ==0) {
     934           1 :       readMaxSurf();
     935             :     }
     936             : 
     937          12 :     if (firstStepFlag ==0 && DeltaGValues != "absent") {
     938           1 :       readDeltaG();
     939             :     }
     940             : 
     941          12 :     if (DeltaGValues == "absent") {
     942           0 :       computeDeltaG();
     943             :     }
     944             : 
     945             : 
     946        1452 :     for(unsigned i = 0; i < natoms; i++) {
     947             : 
     948             : 
     949             : 
     950        1440 :       derivatives[i][0] = 0.;
     951        1440 :       derivatives[i][1] = 0.;
     952        1440 :       derivatives[i][2] = 0.;
     953             : 
     954        1440 :       if ( LCPOparam[i].size()>1) {
     955         720 :         if (LCPOparam[i][1]>0.0) {
     956             :           Aij = 0.0;
     957             :           Aijk = 0.0;
     958             :           Ajk = 0.0;
     959         720 :           double ri = LCPOparam[i][0];
     960         720 :           S1 = 4*M_PI*ri*ri;
     961         720 :           vector <double> dAijdc_2(3, 0);
     962         720 :           vector <double> dAijdc_4(3, 0);
     963             : 
     964             : 
     965       19750 :           for (unsigned j = 0; j < Nlist[i].size(); j++) {
     966       19030 :             const Vector d_ij_vec = delta( getPosition(i), getPosition(Nlist[i][j]) );
     967       19030 :             double d_ij = d_ij_vec.modulo()*10;
     968             : 
     969       19030 :             double rj = LCPOparam[Nlist[i][j]][0];
     970       19030 :             Aijt = (2*M_PI*ri*(ri-d_ij/2-((ri*ri-rj*rj)/(2*d_ij))));
     971       19030 :             double sji = (2*M_PI*rj*(rj-d_ij/2+((ri*ri-rj*rj)/(2*d_ij))));
     972             : 
     973       19030 :             dAdd = M_PI*rj*(-(ri*ri-rj*rj)/(d_ij*d_ij)-1);
     974       19030 :             ddij_di[0] = -10*(getPosition(Nlist[i][j])[0]-getPosition(i)[0])/d_ij;
     975       19030 :             ddij_di[1] = -10*(getPosition(Nlist[i][j])[1]-getPosition(i)[1])/d_ij;
     976       19030 :             ddij_di[2] = -10*(getPosition(Nlist[i][j])[2]-getPosition(i)[2])/d_ij;
     977             : 
     978             :             Ajkt = 0.0;
     979             :             Aikt = 0.0;
     980             : 
     981       19030 :             vector <double> dSASA_3_neigh_dc(3, 0.0);
     982       19030 :             vector <double> dSASA_4_neigh_dc(3, 0.0);
     983       19030 :             vector <double> dSASA_3_neigh_dc2(3, 0.0);
     984       19030 :             vector <double> dSASA_4_neigh_dc2(3, 0.0);
     985             : 
     986       19030 :             dSASA_2_neigh_dc[0] = dAdd * ddij_di[0];
     987       19030 :             dSASA_2_neigh_dc[1] = dAdd * ddij_di[1];
     988       19030 :             dSASA_2_neigh_dc[2] = dAdd * ddij_di[2];
     989             : 
     990       19030 :             dAdd = M_PI*ri*((ri*ri-rj*rj)/(d_ij*d_ij)-1);
     991             : 
     992       19030 :             dAijdc_2t[0] = dAdd * ddij_di[0];
     993       19030 :             dAijdc_2t[1] = dAdd * ddij_di[1];
     994       19030 :             dAijdc_2t[2] = dAdd * ddij_di[2];
     995             : 
     996      560038 :             for (unsigned k = 0; k < Nlist[Nlist[i][j]].size(); k++) {
     997      541008 :               if (std::find (Nlist[i].begin(), Nlist[i].end(), Nlist[Nlist[i][j]][k]) !=  Nlist[i].end()) {
     998      370872 :                 const Vector d_jk_vec = delta( getPosition(Nlist[i][j]), getPosition(Nlist[Nlist[i][j]][k]) );
     999      370872 :                 const Vector d_ik_vec = delta( getPosition(i), getPosition(Nlist[Nlist[i][j]][k]) );
    1000             : 
    1001      370872 :                 double d_jk = d_jk_vec.modulo()*10;
    1002      370872 :                 double d_ik = d_ik_vec.modulo()*10;
    1003             : 
    1004      370872 :                 double rk = LCPOparam[Nlist[Nlist[i][j]][k]][0];
    1005      370872 :                 double sjk =  (2*M_PI*rj*(rj-d_jk/2-((rj*rj-rk*rk)/(2*d_jk))));
    1006      370872 :                 Ajkt += sjk;
    1007      370872 :                 Aikt += (2*M_PI*ri*(ri-d_ik/2-((ri*ri-rk*rk)/(2*d_ik))));
    1008             : 
    1009      370872 :                 dAdd = M_PI*ri*((ri*ri-rk*rk)/(d_ik*d_ik)-1);
    1010             : 
    1011      370872 :                 ddik_di[0] = -10*(getPosition(Nlist[Nlist[i][j]][k])[0]-getPosition(i)[0])/d_ik;
    1012      370872 :                 ddik_di[1] = -10*(getPosition(Nlist[Nlist[i][j]][k])[1]-getPosition(i)[1])/d_ik;
    1013      370872 :                 ddik_di[2] = -10*(getPosition(Nlist[Nlist[i][j]][k])[2]-getPosition(i)[2])/d_ik;
    1014             : 
    1015             : 
    1016      370872 :                 dSASA_3_neigh_dc[0] += dAdd*ddik_di[0];
    1017      370872 :                 dSASA_3_neigh_dc[1] += dAdd*ddik_di[1];
    1018      370872 :                 dSASA_3_neigh_dc[2] += dAdd*ddik_di[2];
    1019             : 
    1020      370872 :                 dAdd = M_PI*rk*(-(ri*ri-rk*rk)/(d_ik*d_ik)-1);
    1021             : 
    1022      370872 :                 dSASA_3_neigh_dc2[0] += dAdd*ddik_di[0];
    1023      370872 :                 dSASA_3_neigh_dc2[1] += dAdd*ddik_di[1];
    1024      370872 :                 dSASA_3_neigh_dc2[2] += dAdd*ddik_di[2];
    1025             : 
    1026      370872 :                 dSASA_4_neigh_dc2[0] += sjk*dAdd*ddik_di[0];
    1027      370872 :                 dSASA_4_neigh_dc2[1] += sjk*dAdd*ddik_di[1];
    1028      370872 :                 dSASA_4_neigh_dc2[2] += sjk*dAdd*ddik_di[2];
    1029             : 
    1030             :               }
    1031             :             }
    1032       19030 :             dSASA_4_neigh_dc[0] = sji*dSASA_3_neigh_dc[0] + dSASA_4_neigh_dc2[0];
    1033       19030 :             dSASA_4_neigh_dc[1] = sji*dSASA_3_neigh_dc[1] + dSASA_4_neigh_dc2[1];
    1034       19030 :             dSASA_4_neigh_dc[2] = sji*dSASA_3_neigh_dc[2] + dSASA_4_neigh_dc2[2];
    1035             : 
    1036       19030 :             dSASA_3_neigh_dc[0] += dSASA_3_neigh_dc2[0];
    1037       19030 :             dSASA_3_neigh_dc[1] += dSASA_3_neigh_dc2[1];
    1038       19030 :             dSASA_3_neigh_dc[2] += dSASA_3_neigh_dc2[2];
    1039             : 
    1040       19030 :             dSASA_4_neigh_dc[0] += dSASA_2_neigh_dc[0] * Aikt;
    1041       19030 :             dSASA_4_neigh_dc[1] += dSASA_2_neigh_dc[1] * Aikt;
    1042       19030 :             dSASA_4_neigh_dc[2] += dSASA_2_neigh_dc[2] * Aikt;
    1043             : 
    1044       19030 :             if (AtomResidueName[0][Nlist[i][j]] == "N" || AtomResidueName[0][Nlist[i][j]] == "CA"  || AtomResidueName[0][Nlist[i][j]] == "C" || AtomResidueName[0][Nlist[i][j]] == "O") {
    1045       15720 :               derivatives[i][0] += ((dSASA_2_neigh_dc[0]*LCPOparam[Nlist[i][j]][2] + dSASA_3_neigh_dc[0]*LCPOparam[Nlist[i][j]][3]+dSASA_4_neigh_dc[0]*LCPOparam[Nlist[i][j]][4])/MaxSurf[Nlist[i][j]][0]*DeltaG[natoms][0])*10;
    1046       15720 :               derivatives[i][1] += ((dSASA_2_neigh_dc[1]*LCPOparam[Nlist[i][j]][2] + dSASA_3_neigh_dc[1]*LCPOparam[Nlist[i][j]][3]+dSASA_4_neigh_dc[1]*LCPOparam[Nlist[i][j]][4])/MaxSurf[Nlist[i][j]][0]*DeltaG[natoms][0])*10;
    1047       15720 :               derivatives[i][2] += ((dSASA_2_neigh_dc[2]*LCPOparam[Nlist[i][j]][2] + dSASA_3_neigh_dc[2]*LCPOparam[Nlist[i][j]][3]+dSASA_4_neigh_dc[2]*LCPOparam[Nlist[i][j]][4])/MaxSurf[Nlist[i][j]][0]*DeltaG[natoms][0])*10;
    1048             :             }
    1049             : 
    1050       19030 :             if (AtomResidueName[0][Nlist[i][j]] != "N" && AtomResidueName[0][Nlist[i][j]] != "CA"  && AtomResidueName[0][Nlist[i][j]] != "C" && AtomResidueName[0][Nlist[i][j]] != "O") {
    1051        3310 :               derivatives[i][0] += ((dSASA_2_neigh_dc[0]*LCPOparam[Nlist[i][j]][2] + dSASA_3_neigh_dc[0]*LCPOparam[Nlist[i][j]][3]+dSASA_4_neigh_dc[0]*LCPOparam[Nlist[i][j]][4])/MaxSurf[Nlist[i][j]][1]*DeltaG[Nlist[i][j]][0])*10;
    1052        3310 :               derivatives[i][1] += ((dSASA_2_neigh_dc[1]*LCPOparam[Nlist[i][j]][2] + dSASA_3_neigh_dc[1]*LCPOparam[Nlist[i][j]][3]+dSASA_4_neigh_dc[1]*LCPOparam[Nlist[i][j]][4])/MaxSurf[Nlist[i][j]][1]*DeltaG[Nlist[i][j]][0])*10;
    1053        3310 :               derivatives[i][2] += ((dSASA_2_neigh_dc[2]*LCPOparam[Nlist[i][j]][2] + dSASA_3_neigh_dc[2]*LCPOparam[Nlist[i][j]][3]+dSASA_4_neigh_dc[2]*LCPOparam[Nlist[i][j]][4])/MaxSurf[Nlist[i][j]][1]*DeltaG[Nlist[i][j]][0])*10;
    1054             :             }
    1055             : 
    1056       19030 :             Aijk += (Aijt * Ajkt);
    1057       19030 :             Aij += Aijt;
    1058       19030 :             Ajk += Ajkt;
    1059             : 
    1060       19030 :             dAijdc_2[0] += dAijdc_2t[0];
    1061       19030 :             dAijdc_2[1] += dAijdc_2t[1];
    1062       19030 :             dAijdc_2[2] += dAijdc_2t[2];
    1063             : 
    1064       19030 :             dAijdc_4[0] += Ajkt*dAijdc_2t[0];
    1065       19030 :             dAijdc_4[1] += Ajkt*dAijdc_2t[1];
    1066       19030 :             dAijdc_4[2] += Ajkt*dAijdc_2t[2];
    1067             : 
    1068             :           }
    1069         720 :           double sasai = (LCPOparam[i][1]*S1+LCPOparam[i][2]*Aij+LCPOparam[i][3]*Ajk+LCPOparam[i][4]*Aijk);
    1070             : 
    1071        2016 :           if (AtomResidueName[0][i] == "N" || AtomResidueName[0][i] == "CA"  || AtomResidueName[0][i] == "C" || AtomResidueName[0][i] == "O") {
    1072         576 :             if (sasai > 0 ) {
    1073         571 :               sasa += (sasai/MaxSurf[i][0]*DeltaG[natoms][0]);
    1074             :             }
    1075         576 :             derivatives[i][0] += ((dAijdc_2[0]*LCPOparam[i][2]+dAijdc_4[0]*LCPOparam[i][4])/MaxSurf[i][0]*DeltaG[natoms][0])*10;
    1076         576 :             derivatives[i][1] += ((dAijdc_2[1]*LCPOparam[i][2]+dAijdc_4[1]*LCPOparam[i][4])/MaxSurf[i][0]*DeltaG[natoms][0])*10;
    1077         576 :             derivatives[i][2] += ((dAijdc_2[2]*LCPOparam[i][2]+dAijdc_4[2]*LCPOparam[i][4])/MaxSurf[i][0]*DeltaG[natoms][0])*10;
    1078             :           }
    1079             : 
    1080        2016 :           if (AtomResidueName[0][i] != "N" && AtomResidueName[0][i] != "CA"  && AtomResidueName[0][i] != "C" && AtomResidueName[0][i] != "O") {
    1081         144 :             if (sasai > 0. ) {
    1082         144 :               sasa += (sasai/MaxSurf[i][1]*DeltaG[i][0]);
    1083             :             }
    1084         144 :             derivatives[i][0] += ((dAijdc_2[0]*LCPOparam[i][2]+dAijdc_4[0]*LCPOparam[i][4])/MaxSurf[i][1]*DeltaG[i][0])*10;
    1085         144 :             derivatives[i][1] += ((dAijdc_2[1]*LCPOparam[i][2]+dAijdc_4[1]*LCPOparam[i][4])/MaxSurf[i][1]*DeltaG[i][0])*10;
    1086         144 :             derivatives[i][2] += ((dAijdc_2[2]*LCPOparam[i][2]+dAijdc_4[2]*LCPOparam[i][4])/MaxSurf[i][1]*DeltaG[i][0])*10;
    1087             :           }
    1088             :         }
    1089             :       }
    1090        1440 :       virial -= Tensor(getPosition(i),derivatives[i]);
    1091             :     }
    1092             :   }
    1093             : 
    1094             : 
    1095        2904 :   for(unsigned i=0; i<natoms; i++) {
    1096        2880 :     setAtomsDerivatives(i,derivatives[i]);
    1097             :   }
    1098          24 :   setBoxDerivatives(virial);
    1099          24 :   setValue(sasa);
    1100          24 :   firstStepFlag = 1;
    1101          24 :   ++nl_update;
    1102          24 :   if (nl_update == stride) {
    1103          24 :     nl_update = 0;
    1104             :   }
    1105             : // setBoxDerivativesNoPbc();
    1106          24 : }
    1107             : 
    1108             : }//namespace sasa
    1109             : }//namespace PLMD

Generated by: LCOV version 1.16