Line data Source code
1 : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 : Copyright (c) 2013-2018 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 : #include "Path.h" 23 : #include "tools/PDB.h" 24 : #include "core/ActionRegister.h" 25 : 26 : //+PLUMEDOC COLVAR GPATH 27 : /* 28 : Distance along and from a path calculated using geometric formulas 29 : 30 : The Path Collective Variables developed by Branduardi and that are described in the first paper that is cited below allow one 31 : to compute the progress along a high-dimensional path and the distance from the high-dimensional path. The method introduced in that 32 : paper is implemented in the shortcut [PATH](PATH.md). This action provides an implementation of the alternative method for calculating 33 : the position on and distance from the path that was proposed by Diaz Leines and Ensing in the second paper that is cited below. In their 34 : method, the progress along the path $s$ is calculated using: 35 : 36 : $$ 37 : s = i_2 + \textrm{sign}(i_2-i_1) \frac{ \sqrt{( \mathbf{v}_1\cdot\mathbf{v}_2 )^2 - |\mathbf{v}_3|^2(|\mathbf{v}_1|^2 - |\mathbf{v}_2|^2) } }{2|\mathbf{v}_3|^2} - \frac{\mathbf{v}_1\cdot\mathbf{v}_3 - |\mathbf{v}_3|^2}{2|\mathbf{v}_3|^2} 38 : $$ 39 : 40 : where $\mathbf{v}_1$ and $\mathbf{v}_3$ are the vectors connecting the current position to the closest and second closest node of the path, 41 : respectfully and $i_1$ and $i_2$ are the projections of the closest and second closest frames of the path. $\mathbf{v}_2$, meanwhile, is the 42 : vector connecting the closest frame to the second closest frame. The distance from the path, $z$ is calculated using: 43 : 44 : $$ 45 : z = \sqrt{ \left[ |\mathbf{v}_1|^2 - |\mathbf{v}_2| \left( \frac{ \sqrt{( \mathbf{v}_1\cdot\mathbf{v}_2 )^2 - |\mathbf{v}_3|^2(|\mathbf{v}_1|^2 - |\mathbf{v}_2|^2) } }{2|\mathbf{v}_3|^2} - \frac{\mathbf{v}_1\cdot\mathbf{v}_3 - |\mathbf{v}_3|^2}{2|\mathbf{v}_3|^2} \right) \right]^2 } 46 : $$ 47 : 48 : The symbols here are as they were for $s$. 49 : 50 : ## Examples 51 : 52 : The example input below shows how to use this shortcut. 53 : 54 : ```plumed 55 : #SETTINGS INPUTFILES=regtest/mapping/rt-adapt/mypath.pdb 56 : d1: DISTANCE ATOMS=1,2 COMPONENTS 57 : pp: GPATH ... 58 : ARG=d1.x,d1.y PROPERTY=path 59 : REFERENCE=regtest/mapping/rt-adapt/mypath.pdb 60 : ... 61 : PRINT ARG=d1.x,d1.y,pp.* FILE=colvar 62 : ``` 63 : 64 : The curved path here is defined using a series of points in a two dimensional space. Furthermore, the coordinates that these points should be projected at on the low dimensional path 65 : (the $i$ values in the equation for $s$ above) are specified in the `path` property of the input pdb file. 66 : 67 : The input below illustrates how to the positions of atoms to define the path: 68 : 69 : ```plumed 70 : ##SETTINGS INPUTFILES=regtest/trajectories/path_msd/all.pdb 71 : p1b: GPATH REFERENCE=regtest/trajectories/path_msd/all.pdb 72 : PRINT ARG=p1b.* FILE=colvar_b STRIDE=1 73 : ``` 74 : 75 : When an input like the one above is used the vectors $\mathbf{v}_1$, $\mathbf{v}_2$ and $\mathbf{v}_3$ from the expression above are computed using an [RMSD](RMSD.md) 76 : action with the DISPLACEMENT flag enabled. The instantaneous structure is thus aligned with the reference structures so as to remove motions due to translation of the center 77 : of mass and rotation of the reference frame. Furthermore, because we have not used the PROPERTY keyword in this input, the $i$ values in the equation for $s$ 78 : above are set equal to 1, 2, 3... 79 : 80 : */ 81 : //+ENDPLUMEDOC 82 : 83 : namespace PLMD { 84 : namespace mapping { 85 : 86 : class GeometricPathShortcut : public ActionShortcut { 87 : public: 88 : static void registerKeywords(Keywords& keys); 89 : explicit GeometricPathShortcut(const ActionOptions&); 90 : }; 91 : 92 : PLUMED_REGISTER_ACTION(GeometricPathShortcut,"GPATH") 93 : 94 17 : void GeometricPathShortcut::registerKeywords( Keywords& keys ) { 95 17 : ActionShortcut::registerKeywords( keys ); 96 17 : Path::registerInputFileKeywords( keys ); 97 17 : keys.add("optional","PROPERTY","read in path coordinates by finding option with this label in remark of pdb frames"); 98 34 : keys.addOutputComponent("s","default","scalar","the position on the path"); 99 34 : keys.addOutputComponent("z","default","scalar","the distance from the path"); 100 17 : keys.needsAction("DISPLACEMENT"); 101 17 : keys.needsAction("GEOMETRIC_PATH"); 102 17 : keys.needsAction("PDB2CONSTANT"); 103 17 : keys.needsAction("CONSTANT"); 104 17 : keys.addDOI("10.1063/1.2432340"); 105 17 : keys.addDOI("10.1103/PhysRevLett.109.020601"); 106 17 : } 107 : 108 5 : GeometricPathShortcut::GeometricPathShortcut( const ActionOptions& ao ): 109 : Action(ao), 110 5 : ActionShortcut(ao) { 111 : std::string mtype, reference_data; 112 5 : std::vector<std::string> argnames; 113 5 : parseVector("ARG",argnames); 114 10 : parse("TYPE", mtype); 115 : // Create list of reference configurations that PLUMED will use 116 : std::string reference; 117 10 : parse("REFERENCE",reference); 118 5 : FILE* fp=std::fopen(reference.c_str(),"r"); 119 5 : PDB mypdb; 120 5 : if(!fp) { 121 0 : error("could not open reference file " + reference ); 122 : } 123 5 : bool do_read=mypdb.readFromFilepointer(fp,false,0.1); 124 5 : if( !do_read ) { 125 0 : error("missing file " + reference ); 126 : } 127 5 : Path::readInputFrames( reference, mtype, argnames, true, this, reference_data ); 128 : // Now get coordinates on spath 129 5 : std::vector<std::string> pnames; 130 5 : parseVector("PROPERTY",pnames); 131 5 : Path::readPropertyInformation( pnames, getShortcutLabel(), reference, this ); 132 : // Create action that computes the geometric path variablesa 133 5 : std::string propstr = getShortcutLabel() + "_ind"; 134 5 : if( pnames.size()>0 ) { 135 0 : propstr = pnames[0] + "_ref"; 136 : } 137 5 : if( argnames.size()>0 ) { 138 5 : readInputLine( getShortcutLabel() + ": GEOMETRIC_PATH ARG=" + getShortcutLabel() + "_data " + " PROPERTY=" + propstr + " REFERENCE=" + reference_data + " METRIC={DIFFERENCE}"); 139 : } else { 140 : std::string num, align_str, displace_str; 141 4 : Tools::convert( mypdb.getOccupancy()[0], align_str ); 142 4 : Tools::convert( mypdb.getBeta()[0], displace_str ); 143 52 : for(unsigned j=1; j<mypdb.getAtomNumbers().size(); ++j ) { 144 48 : Tools::convert( mypdb.getOccupancy()[j], num ); 145 48 : align_str += "," + num; 146 48 : Tools::convert( mypdb.getBeta()[0], num ); 147 48 : displace_str += "," + num; 148 : } 149 12 : std::string metric = "RMSD DISPLACEMENT TYPE=" + mtype + " ALIGN=" + align_str + " DISPLACE=" + displace_str; 150 24 : readInputLine( getShortcutLabel() + ": GEOMETRIC_PATH ARG=" + getShortcutLabel() + "_data.disp " + " PROPERTY=" + propstr + " REFERENCE=" + reference_data + " METRIC={" + metric + "} METRIC_COMPONENT=disp"); 151 : } 152 111 : } 153 : 154 : 155 : } 156 : } 157 : 158 :