From fbfd6859a047c36c6e59691e689fc5b4c1c0d58d Mon Sep 17 00:00:00 2001
From: carlocamilloni <carlo.camilloni@gmail.com>
Date: Tue, 2 Apr 2019 14:17:48 +0200
Subject: [PATCH] new protein related shortcut for MOLINFO @chi2, @chi3, @chi4
 and @chi5

---
 CHANGES/v2.5.md                      |  6 +++
 regtest/basic/rt66b/COLVAR.reference | 12 ++++-
 regtest/basic/rt66b/plumed.dat       |  6 ++-
 src/setup/MolInfo.cpp                |  4 ++
 src/tools/MolDataClass.cpp           | 72 +++++++++++++++++++++++++---
 5 files changed, 91 insertions(+), 9 deletions(-)

diff --git a/CHANGES/v2.5.md b/CHANGES/v2.5.md
index 27948cfb6..7e177b841 100644
--- a/CHANGES/v2.5.md
+++ b/CHANGES/v2.5.md
@@ -171,3 +171,9 @@ For users:
   - Fixed building of python interface on MacOS Mojave (see \issue{445}, thanks to Omar Valsson).
   - Numpy is not required anymore at build time (though it is required at runtime for our tests).
   - Raw python arrays can be passed as an alternative to Numpy ndarrays.
+
+## Version 2.5.2 ()
+
+For users:
+- New shortcuts are available for selecting protein atoms: `@chi2-#`, `@chi3-#`,`@chi4-#` and `@chi5-#`
+
diff --git a/regtest/basic/rt66b/COLVAR.reference b/regtest/basic/rt66b/COLVAR.reference
index 8321445a4..f22e84821 100644
--- a/regtest/basic/rt66b/COLVAR.reference
+++ b/regtest/basic/rt66b/COLVAR.reference
@@ -1,4 +1,4 @@
-#! FIELDS time t2 t3 t4 t4d t5 t6 t7 t8 t9 t10 t12 t13 t14
+#! FIELDS time t2 t3 t4 t4d t5 t6 t7 t8 t9 t10 t12 t13 t13b t13c t13d t13e t14
 #! SET min_t2 -pi
 #! SET max_t2 pi
 #! SET min_t3 -pi
@@ -23,6 +23,14 @@
 #! SET max_t12 pi
 #! SET min_t13 -pi
 #! SET max_t13 pi
+#! SET min_t13b -pi
+#! SET max_t13b pi
+#! SET min_t13c -pi
+#! SET max_t13c pi
+#! SET min_t13d -pi
+#! SET max_t13d pi
+#! SET min_t13e -pi
+#! SET max_t13e pi
 #! SET min_t14 -pi
 #! SET max_t14 pi
- 0.000000 -1.140  3.000  1.144  1.436 -2.773 -2.785 -1.264  0.044 -0.426  0.621  0.361 -0.867 -2.888
+ 0.000000 -1.140  3.000  1.144  1.436 -2.773 -2.785 -1.264  0.044 -0.426  0.621  0.361 -0.867  2.257 -0.479  0.621  3.123 -2.888
diff --git a/regtest/basic/rt66b/plumed.dat b/regtest/basic/rt66b/plumed.dat
index 8ec8b93ac..685e69713 100644
--- a/regtest/basic/rt66b/plumed.dat
+++ b/regtest/basic/rt66b/plumed.dat
@@ -14,11 +14,15 @@ t10: TORSION ATOMS=@v2-B_3
 t11: TORSION ATOMS=@v3-B_3
 t12: TORSION ATOMS=@v4-B_3
 t13: TORSION ATOMS=@phi-2
+t13b: TORSION ATOMS=@psi-2
+t13c: TORSION ATOMS=@chi1-2
+t13d: TORSION ATOMS=@chi2-2
+t13e: TORSION ATOMS=@omega-2
 # test chain_residue syntax where chain is a number
 t14: TORSION ATOMS=@chi-5_8
 
 c: CENTER ATOMS=@back-B4
 d: CENTER ATOMS=@base-B4
 
-PRINT ARG=t2,t3,t4,t4d,t5,t6,t7,t8,t9,t10,t12,t13,t14 FILE=COLVAR FMT=%6.3f
+PRINT ARG=t2,t3,t4,t4d,t5,t6,t7,t8,t9,t10,t12,t13,t13b,t13c,t13d,t13e,t14 FILE=COLVAR FMT=%6.3f
 
diff --git a/src/setup/MolInfo.cpp b/src/setup/MolInfo.cpp
index 0d0191df1..bcc7ad1ef 100644
--- a/src/setup/MolInfo.cpp
+++ b/src/setup/MolInfo.cpp
@@ -94,6 +94,10 @@ For protein residues, the following groups are available:
 @psi-#
 @omega-#
 @chi1-#
+@chi2-#
+@chi3-#
+@chi4-#
+@chi5-#
 \endverbatim
 
 that select the appropriate atoms that define each dihedral angle for residue #.
diff --git a/src/tools/MolDataClass.cpp b/src/tools/MolDataClass.cpp
index 11fa1ecf7..76ebd5e81 100644
--- a/src/tools/MolDataClass.cpp
+++ b/src/tools/MolDataClass.cpp
@@ -324,21 +324,81 @@ void MolDataClass::specialSymbol( const std::string& type, const std::string& sy
         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("N",resnum+1,chainid));
         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("CA",resnum+1,chainid));
       } else if( name=="chi1" && !isTerminalGroup("protein",resname) ) {
-        if ( resname=="GLY" || resname=="ALA" || resname=="SFO" ) plumed_merror("chi-1 is not defined for Alanine, Glycine and SFO");
+        if ( resname=="GLY" || resname=="ALA" || resname=="SFO" ) plumed_merror("chi-1 is not defined for ALA, GLY and SFO");
         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("N",resnum,chainid));
         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("CA",resnum,chainid));
         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("CB",resnum,chainid));
-        if(resname=="ILE"||resname=="VAL")
+        if(resname=="ILE"||resname=="VAL") {
           numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("CG1",resnum,chainid));
-        else if(resname=="CYS")
+        } else if(resname=="CYS") {
           numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("SG",resnum,chainid));
-        else if(resname=="THR")
+        } else if(resname=="THR") {
           numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("OG1",resnum,chainid));
-        else if(resname=="SER")
+        } else if(resname=="SER") {
           numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("OG",resnum,chainid));
-        else
+        } else {
           numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("CG",resnum,chainid));
+        }
+      } else if( name=="chi2" && !isTerminalGroup("protein",resname) ) {
+        if ( resname=="GLY" || resname=="ALA" || resname=="SFO" || resname=="CYS" || resname=="SER" ||
+             resname=="THR" || resname=="VAL" ) plumed_merror("chi-2 is not defined for ALA, GLY, CYS, SER, THR, VAL and SFO");
+        numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("CA",resnum,chainid));
+        numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("CB",resnum,chainid));
+
+        if(resname=="ILE") {
+          numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("CG1",resnum,chainid));
+        } else {
+          numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("CG",resnum,chainid));
+        }
+        if(resname=="ASN" || resname=="ASP") {
+          numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("OD1",resnum,chainid));
+        } else if(resname=="HIS") {
+          numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("ND1",resnum,chainid));
+        } else if(resname=="LEU" || resname=="PHE" || resname=="TRP" || resname=="TYR") {
+          numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("CD1",resnum,chainid));
+        } else if(resname=="MET") {
+          numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("SD",resnum,chainid));
+        } else {
+          numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("CD",resnum,chainid));
+        }
+      } else if( name=="chi3" && !isTerminalGroup("protein",resname) ) {
+        if (!( resname=="ARG" || resname=="GLN" || resname=="GLU" || resname=="LYS" ||
+               resname=="MET" )) plumed_merror("chi-3 is defined only for ARG, GLN, GLU, LYS and MET");
+        numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("CB",resnum,chainid));
+        numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("CG",resnum,chainid));
+
+        if(resname=="MET") {
+          numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("SD",resnum,chainid));
+        } else {
+          numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("CD",resnum,chainid));
+        }
+        if(resname=="GLN" || resname=="GLU") {
+          numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("OE1",resnum,chainid));
+        } else if(resname=="LYS" || resname=="MET") {
+          numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("CE",resnum,chainid));
+        } else {
+          numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("NE",resnum,chainid));
+        }
+      } else if( name=="chi4" && !isTerminalGroup("protein",resname) ) {
+        if (!( resname=="ARG" || resname=="LYS" )) plumed_merror("chi-4 is defined only for ARG and LYS");
+        numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("CG",resnum,chainid));
+        numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("CD",resnum,chainid));
+
+        if(resname=="ARG") {
+          numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("NE",resnum,chainid));
+          numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("CZ",resnum,chainid));
+        } else {
+          numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("CE",resnum,chainid));
+          numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("NZ",resnum,chainid));
+        }
+      } else if( name=="chi5" && !isTerminalGroup("protein",resname) ) {
+        if (!( resname=="ARG" )) plumed_merror("chi-5 is defined only for ARG");
+        numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("CD",resnum,chainid));
+        numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("NE",resnum,chainid));
+        numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("CZ",resnum,chainid));
+        numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("NH1",resnum,chainid));
       } else numbers.push_back(mypdb.getNamedAtomFromResidueAndChain(name,resnum,chainid));
+
     } else if( allowedResidue("rna",resname) || allowedResidue("dna",resname)) {
       std::string basetype;
       if(resname.find_first_of("A")!=std::string::npos) basetype+="A";
-- 
GitLab