Line data Source code
1 : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 : Copyright (c) 2013-2023 The plumed team
3 : (see the PEOPLE file at the root of the distribution for a list of names)
4 :
5 : See http://www.plumed.org for more information.
6 :
7 : This file is part of plumed, version 2.
8 :
9 : plumed is free software: you can redistribute it and/or modify
10 : it under the terms of the GNU Lesser General Public License as published by
11 : the Free Software Foundation, either version 3 of the License, or
12 : (at your option) any later version.
13 :
14 : plumed is distributed in the hope that it will be useful,
15 : but WITHOUT ANY WARRANTY; without even the implied warranty of
16 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 : GNU Lesser General Public License for more details.
18 :
19 : You should have received a copy of the GNU Lesser General Public License
20 : along with plumed. If not, see <http://www.gnu.org/licenses/>.
21 : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
22 : #include "Path.h"
23 : #include "core/ActionRegister.h"
24 : #include "core/ActionWithValue.h"
25 : #include "core/ActionWithArguments.h"
26 : #include "core/PlumedMain.h"
27 : #include "core/ActionSet.h"
28 : #include "tools/PDB.h"
29 :
30 : //+PLUMEDOC COLVAR PATH
31 : /*
32 : Path collective variables with a more flexible framework for the distance metric being used.
33 :
34 : The Path Collective Variables developed by Branduardi and co-workers \cite brand07 allow one
35 : to compute the progress along a high-dimensional path and the distance from the high-dimensional
36 : path. The progress along the path (s) is computed using:
37 :
38 : \f[
39 : s = \frac{ \sum_{i=1}^N i \exp( -\lambda R[X - X_i] ) }{ \sum_{i=1}^N \exp( -\lambda R[X - X_i] ) }
40 : \f]
41 :
42 : while the distance from the path (z) is measured using:
43 :
44 : \f[
45 : z = -\frac{1}{\lambda} \ln\left[ \sum_{i=1}^N \exp( -\lambda R[X - X_i] ) \right]
46 : \f]
47 :
48 : In these expressions \f$N\f$ high-dimensional frames (\f$X_i\f$) are used to describe the path in the high-dimensional
49 : space. The two expressions above are then functions of the distances from each of the high-dimensional frames \f$R[X - X_i]\f$.
50 : Within PLUMED there are multiple ways to define the distance from a high-dimensional configuration. You could calculate
51 : the RMSD distance or you could calculate the amount by which a set of collective variables change. As such this implementation
52 : of the path CV allows one to use all the difference distance metrics that are discussed in \ref dists. This is as opposed to
53 : the alternative implementation of path (\ref PATHMSD) which is a bit faster but which only allows one to use the RMSD distance.
54 :
55 : The \f$s\f$ and \f$z\f$ variables are calculated using the above formulas by default. However, there is an alternative method
56 : of calculating these collective variables, which is detailed in \cite bernd-path. This alternative method uses the tools of
57 : geometry (as opposed to algebra, which is used in the equations above). In this alternative formula the progress along the path
58 : \f$s\f$ is calculated using:
59 :
60 : \f[
61 : 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}
62 : \f]
63 :
64 : where \f$\mathbf{v}_1\f$ and \f$\mathbf{v}_3\f$ are the vectors connecting the current position to the closest and second closest node of the path,
65 : respectfully and \f$i_1\f$ and \f$i_2\f$ are the projections of the closest and second closest frames of the path. \f$\mathbf{v}_2\f$, meanwhile, is the
66 : vector connecting the closest frame to the second closest frame. The distance from the path, \f$z\f$ is calculated using:
67 :
68 : \f[
69 : 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 }
70 : \f]
71 :
72 : The symbols here are as they were for \f$s\f$. If you would like to use these equations to calculate \f$s\f$ and \f$z\f$ then you should use the GPATH flag.
73 : The values of \f$s\f$ and \f$z\f$ can then be referenced using the gspath and gzpath labels.
74 :
75 : \par Examples
76 :
77 : In the example below the path is defined using RMSD distance from frames.
78 :
79 : \plumedfile
80 : p1: PATH REFERENCE=file.pdb TYPE=OPTIMAL LAMBDA=500.0
81 : PRINT ARG=p1.spath,p1.zpath STRIDE=1 FILE=colvar FMT=%8.4f
82 : \endplumedfile
83 :
84 : The reference frames in the path are defined in the pdb file shown below. In this frame
85 : each configuration in the path is separated by a line containing just the word END.
86 :
87 : \auxfile{file.pdb}
88 : ATOM 1 CL ALA 1 -3.171 0.295 2.045 1.00 1.00
89 : ATOM 5 CLP ALA 1 -1.819 -0.143 1.679 1.00 1.00
90 : ATOM 6 OL ALA 1 -1.177 -0.889 2.401 1.00 1.00
91 : ATOM 7 NL ALA 1 -1.313 0.341 0.529 1.00 1.00
92 : END
93 : ATOM 1 CL ALA 1 -3.175 0.365 2.024 1.00 1.00
94 : ATOM 5 CLP ALA 1 -1.814 -0.106 1.685 1.00 1.00
95 : ATOM 6 OL ALA 1 -1.201 -0.849 2.425 1.00 1.00
96 : ATOM 7 NL ALA 1 -1.296 0.337 0.534 1.00 1.00
97 : END
98 : ATOM 1 CL ALA 1 -2.990 0.383 2.277 1.00 1.00
99 : ATOM 5 CLP ALA 1 -1.664 -0.085 1.831 1.00 1.00
100 : ATOM 6 OL ALA 1 -0.987 -0.835 2.533 1.00 1.00
101 : ATOM 7 NL ALA 1 -1.227 0.364 0.646 1.00 1.00
102 : END
103 : \endauxfile
104 :
105 : In the example below the path is defined using the values of two torsional angles (t1 and t2).
106 : In addition, the \f$s\f$ and \f$z\f$ are calculated using the geometric expressions described
107 : above rather than the algebraic expressions that are used by default.
108 :
109 : \plumedfile
110 : t1: TORSION ATOMS=5,7,9,15
111 : t2: TORSION ATOMS=7,9,15,17
112 : pp: PATH TYPE=EUCLIDEAN REFERENCE=epath.pdb GPATH NOSPATH NOZPATH
113 : PRINT ARG=pp.* FILE=colvar
114 : \endplumedfile
115 :
116 : Notice that the LAMBDA parameter is not required here as we are not calculating \f$s\f$ and \f$s\f$
117 : using the algebraic formulas defined earlier. The positions of the frames in the path are defined
118 : in the file epath.pdb. An extract from this file looks as shown below.
119 :
120 : \auxfile{epath.pdb}
121 : REMARK ARG=t1,t2 t1=-4.25053 t2=3.88053
122 : END
123 : REMARK ARG=t1,t2 t1=-4.11 t2=3.75
124 : END
125 : REMARK ARG=t1,t2 t1=-3.96947 t2=3.61947
126 : END
127 : \endauxfile
128 :
129 : The remarks in this pdb file tell PLUMED the labels that are being used to define the position in the
130 : high dimensional space and the values that these arguments have at each point on the path.
131 :
132 : */
133 : //+ENDPLUMEDOC
134 :
135 : //+PLUMEDOC COLVAR GPROPERTYMAP
136 : /*
137 : Property maps but with a more flexible framework for the distance metric being used.
138 :
139 : This colvar calculates a property map using the formalism developed by Spiwok \cite Spiwok:2011ce.
140 : In essence if you have the value of some property, \f$X_i\f$, that it takes at a set of high-dimensional
141 : positions then you calculate the value of the property at some arbitrary point in the high-dimensional space
142 : using:
143 :
144 : \f[
145 : X=\frac{\sum_i X_i*\exp(-\lambda D_i(x))}{\sum_i \exp(-\lambda D_i(x))}
146 : \f]
147 :
148 : Within PLUMED there are multiple ways to define the distance from a high-dimensional configuration, \f$D_i\f$. You could calculate
149 : the RMSD distance or you could calculate the amount by which a set of collective variables change. As such this implementation
150 : of the property map allows one to use all the different distance metric that are discussed in \ref dists. This is as opposed to
151 : the alternative implementation \ref PROPERTYMAP which is a bit faster but which only allows one to use the RMSD distance.
152 :
153 : \par Examples
154 :
155 : The input shown below can be used to calculate the interpolated values of two properties called X and Y based on the values
156 : that these properties take at a set of reference configurations and using the formula above. For this input the distances
157 : between the reference configurations and the instantaneous configurations are calculated using the OPTIMAL metric that is
158 : discussed at length in the manual pages on \ref RMSD.
159 :
160 : \plumedfile
161 : p2: GPROPERTYMAP REFERENCE=allv.pdb PROPERTY=X,Y LAMBDA=69087
162 : PRINT ARG=p2.X,p2.Y,p2.zpath STRIDE=1 FILE=colvar
163 : \endplumedfile
164 :
165 : The additional input file for this calculation, which contains the reference frames and the values of X and Y at these reference
166 : points has the following format.
167 :
168 : \auxfile{allv.pdb}
169 : REMARK X=1 Y=2
170 : ATOM 1 CL ALA 1 -3.171 0.295 2.045 1.00 1.00
171 : ATOM 5 CLP ALA 1 -1.819 -0.143 1.679 1.00 1.00
172 : ATOM 6 OL ALA 1 -1.177 -0.889 2.401 1.00 1.00
173 : ATOM 7 NL ALA 1 -1.313 0.341 0.529 1.00 1.00
174 : ATOM 8 HL ALA 1 -1.845 0.961 -0.011 1.00 1.00
175 : ATOM 9 CA ALA 1 -0.003 -0.019 0.021 1.00 1.00
176 : ATOM 10 HA ALA 1 0.205 -1.051 0.259 1.00 1.00
177 : ATOM 11 CB ALA 1 0.009 0.135 -1.509 1.00 1.00
178 : ATOM 15 CRP ALA 1 1.121 0.799 0.663 1.00 1.00
179 : ATOM 16 OR ALA 1 1.723 1.669 0.043 1.00 1.00
180 : ATOM 17 NR ALA 1 1.423 0.519 1.941 1.00 1.00
181 : ATOM 18 HR ALA 1 0.873 -0.161 2.413 1.00 1.00
182 : ATOM 19 CR ALA 1 2.477 1.187 2.675 1.00 1.00
183 : END
184 : FIXED
185 : REMARK X=2 Y=3
186 : ATOM 1 CL ALA 1 -3.175 0.365 2.024 1.00 1.00
187 : ATOM 5 CLP ALA 1 -1.814 -0.106 1.685 1.00 1.00
188 : ATOM 6 OL ALA 1 -1.201 -0.849 2.425 1.00 1.00
189 : ATOM 7 NL ALA 1 -1.296 0.337 0.534 1.00 1.00
190 : ATOM 8 HL ALA 1 -1.807 0.951 -0.044 1.00 1.00
191 : ATOM 9 CA ALA 1 0.009 -0.067 0.033 1.00 1.00
192 : ATOM 10 HA ALA 1 0.175 -1.105 0.283 1.00 1.00
193 : ATOM 11 CB ALA 1 0.027 0.046 -1.501 1.00 1.00
194 : ATOM 15 CRP ALA 1 1.149 0.725 0.654 1.00 1.00
195 : ATOM 16 OR ALA 1 1.835 1.491 -0.011 1.00 1.00
196 : ATOM 17 NR ALA 1 1.380 0.537 1.968 1.00 1.00
197 : ATOM 18 HR ALA 1 0.764 -0.060 2.461 1.00 1.00
198 : ATOM 19 CR ALA 1 2.431 1.195 2.683 1.00 1.00
199 : END
200 : \endauxfile
201 :
202 : */
203 : //+ENDPLUMEDOC
204 :
205 : namespace PLMD {
206 : namespace mapping {
207 :
208 : PLUMED_REGISTER_ACTION(Path,"PATH")
209 : PLUMED_REGISTER_ACTION(Path,"GPROPERTYMAP")
210 :
211 14 : void Path::registerKeywords( Keywords& keys ) {
212 14 : ActionShortcut::registerKeywords( keys );
213 14 : Path::registerInputFileKeywords( keys );
214 14 : keys.add("optional","PROPERTY","the property to be used in the index. This should be in the REMARK of the reference");
215 14 : keys.add("compulsory","LAMBDA","the lambda parameter is needed for smoothing, is in the units of plumed");
216 28 : keys.addOutputComponent("gspath","GPATH","scalar","the position along the path calculated using the geometric formula");
217 28 : keys.addOutputComponent("gzpath","GPATH","scalar","the distance from the path calculated using the geometric formula");
218 28 : keys.addOutputComponent("spath","default","scalar","the position along the path calculated");
219 28 : keys.addOutputComponent("zpath","default","scalar","the distance from the path calculated");
220 14 : }
221 :
222 32 : void Path::registerInputFileKeywords( Keywords& keys ) {
223 32 : keys.add("compulsory","REFERENCE","a pdb file containing the set of reference configurations");
224 32 : keys.add("compulsory","TYPE","OPTIMAL-FAST","the manner in which distances are calculated. More information on the different "
225 : "metrics that are available in PLUMED can be found in the section of the manual on "
226 : "\\ref dists");
227 64 : keys.addInputKeyword("optional","ARG","scalar","the list of arguments you would like to use in your definition of the path");
228 32 : keys.add("optional","COEFFICIENTS","the coefficients of the displacements along each argument that should be used when calculating the euclidean distance");
229 32 : keys.addFlag("NOPBC",false,"ignore the periodic boundary conditions when calculating distances");
230 32 : keys.addFlag("NOSPATH",false,"do not calculate the spath CV");
231 32 : keys.addFlag("NOZPATH",false,"do not calculate the zpath CV");
232 32 : keys.addFlag("GPATH",false,"calculate the trigonometric path");
233 32 : keys.needsAction("DRMSD");
234 32 : keys.needsAction("RMSD");
235 32 : keys.needsAction("LOWEST");
236 32 : keys.needsAction("GPATH");
237 32 : keys.needsAction("EUCLIDEAN_DISTANCE");
238 32 : keys.needsAction("CUSTOM");
239 32 : keys.needsAction("SUM");
240 32 : keys.needsAction("COMBINE");
241 32 : keys.needsAction("NORMALIZED_EUCLIDEAN_DISTANCE");
242 32 : keys.needsAction("PDB2CONSTANT");
243 32 : keys.needsAction("CONSTANT");
244 32 : }
245 :
246 10 : Path::Path( const ActionOptions& ao ):
247 : Action(ao),
248 10 : ActionShortcut(ao) {
249 : bool nospath, nozpath, gpath;
250 10 : parseFlag("NOSPATH",nospath);
251 10 : parseFlag("NOZPATH",nozpath);
252 10 : parseFlag("GPATH",gpath);
253 10 : if( gpath ) {
254 0 : readInputLine( getShortcutLabel() + "_gpath: GPATH " + convertInputLineToString() );
255 0 : readInputLine( getShortcutLabel() + "_gspath: COMBINE ARG=" + getShortcutLabel() + "_gpath.s PERIODIC=NO");
256 0 : readInputLine( getShortcutLabel() + "_gzpath: COMBINE ARG=" + getShortcutLabel() + "_gpath.z PERIODIC=NO");
257 : }
258 10 : if( nospath && nozpath ) {
259 0 : return;
260 : }
261 : // Setup the properties
262 : std::vector<std::string> properties, pnames;
263 10 : if( getName()=="PATH") {
264 7 : properties.resize(1);
265 : } else {
266 6 : parseVector("PROPERTY",pnames);
267 3 : properties.resize( pnames.size() );
268 : }
269 : std::string type, reference_data, reference;
270 20 : parse("REFERENCE",reference);
271 : std::vector<std::string> argnames;
272 10 : parseVector("ARG",argnames);
273 10 : parse("TYPE",type);
274 10 : if( type.find("DRMSD")!=std::string::npos ) {
275 2 : readInputLine( getShortcutLabel() + "_data: DRMSD SQUARED TYPE=" + type + " REFERENCE=" + reference );
276 : } else {
277 9 : readInputFrames( reference, type, argnames, false, this, reference_data );
278 : }
279 : // Find the shortest distance to the frames
280 20 : readInputLine( getShortcutLabel() + "_mindist: LOWEST ARG=" + getShortcutLabel() + "_data");
281 : // Now create all other parts of the calculation
282 : std::string lambda;
283 10 : parse("LAMBDA",lambda);
284 : // Now create MATHEVAL object to compute exponential functions
285 20 : readInputLine( getShortcutLabel() + "_weights: CUSTOM ARG=" + getShortcutLabel() + "_data," + getShortcutLabel() + "_mindist FUNC=exp(-(x-y)*" + lambda + ") PERIODIC=NO" );
286 : // Create denominator
287 20 : readInputLine( getShortcutLabel() + "_denom: SUM ARG=" + getShortcutLabel() + "_weights PERIODIC=NO");
288 : // Now compte zpath variable
289 10 : if( !nozpath ) {
290 20 : readInputLine( getShortcutLabel() + "_z: CUSTOM ARG=" + getShortcutLabel() + "_denom," + getShortcutLabel() + "_mindist FUNC=y-log(x)/" + lambda + " PERIODIC=NO");
291 20 : readInputLine( getShortcutLabel() + "_zpath: COMBINE ARG=" + getShortcutLabel() + "_z PERIODIC=NO");
292 : }
293 : // Now get coefficients for properies for spath
294 10 : readPropertyInformation( pnames, getShortcutLabel(), reference, this );
295 : // Now create COMBINE objects to compute numerator of path
296 23 : for(unsigned i=0; i<properties.size(); ++i) {
297 13 : if( pnames.size()>0 ) {
298 12 : readInputLine( pnames[i] + "_numer_prod: CUSTOM ARG=" + getShortcutLabel() + "_weights," + pnames[i] + "_ref FUNC=x*y PERIODIC=NO");
299 12 : readInputLine( pnames[i] + "_numer: SUM ARG=" + pnames[i] + "_numer_prod PERIODIC=NO");
300 12 : readInputLine( getShortcutLabel() + "_" + pnames[i] + ": CUSTOM ARG=" + pnames[i] + "_numer," + getShortcutLabel() + "_denom FUNC=x/y PERIODIC=NO");
301 7 : } else if( !nospath ) {
302 14 : readInputLine( getShortcutLabel() + "_s_prod: CUSTOM ARG=" + getShortcutLabel() + "_weights," + getShortcutLabel() + "_ind FUNC=x*y PERIODIC=NO");
303 14 : readInputLine( getShortcutLabel() + "_numer: SUM ARG=" + getShortcutLabel() + "_s_prod PERIODIC=NO");
304 14 : readInputLine( getShortcutLabel() + "_s: CUSTOM ARG=" + getShortcutLabel() + "_numer," + getShortcutLabel() + "_denom FUNC=x/y PERIODIC=NO");
305 14 : readInputLine( getShortcutLabel() + "_spath: COMBINE ARG=" + getShortcutLabel() + "_s PERIODIC=NO");
306 : }
307 : }
308 20 : }
309 :
310 19 : std::string Path::fixArgumentName( const std::string& argin ) {
311 19 : std::string argout = argin;
312 19 : std::size_t dot=argin.find(".");
313 19 : if( dot!=std::string::npos ) {
314 8 : argout = argin.substr(0,dot) + "_" + argin.substr(dot+1);
315 : }
316 19 : return argout;
317 : }
318 :
319 14 : void Path::readInputFrames( const std::string& reference, const std::string& type, std::vector<std::string>& argnames, const bool& displacements, ActionShortcut* action, std::string& reference_data ) {
320 14 : FILE* fp=std::fopen(reference.c_str(),"r");
321 14 : PDB pdb;
322 14 : if(!fp) {
323 0 : action->error("could not open reference file " + reference );
324 : }
325 14 : bool do_read=pdb.readFromFilepointer(fp,false,0.1);
326 14 : if( !do_read ) {
327 0 : action->error("missing file " + reference );
328 : }
329 14 : if( pdb.getPositions().size()!=0 && argnames.size()==0 ) {
330 9 : reference_data = action->getShortcutLabel() + "_data_ref";
331 9 : if( displacements ) {
332 4 : action->readInputLine( action->getShortcutLabel() + "_data: RMSD DISPLACEMENT SQUARED REFERENCE=" + reference + " TYPE=" + type );
333 : } else {
334 14 : action->readInputLine( action->getShortcutLabel() + "_data: RMSD SQUARED REFERENCE=" + reference + " TYPE=" + type );
335 : }
336 5 : } else if( pdb.getPositions().size()!=0 ) {
337 0 : reference_data = action->getShortcutLabel() + "_atomdata_ref";
338 0 : if( displacements ) {
339 0 : action->readInputLine( action->getShortcutLabel() + "_atomdata: RMSD DISPLACEMENT SQUARED REFERENCE=" + reference + " TYPE=" + type );
340 : } else {
341 0 : action->readInputLine( action->getShortcutLabel() + "_atomdata: RMSD SQUARED REFERENCE=" + reference + " TYPE=" + type );
342 : }
343 5 : } else if( argnames.size()==0 ) {
344 0 : argnames.resize( pdb.getArgumentNames().size() );
345 0 : for(unsigned i=0; i<argnames.size(); ++i) {
346 0 : argnames[i] = pdb.getArgumentNames()[i];
347 : }
348 : }
349 : std::vector<Value*> theargs;
350 14 : if( argnames.size()>0 ) {
351 5 : ActionWithArguments::interpretArgumentList( argnames, action->plumed.getActionSet(), action, theargs );
352 : }
353 :
354 14 : if( theargs.size()>0 ) {
355 : std::string instargs, refargs;
356 20 : for(unsigned i=0; i<theargs.size(); ++i) {
357 15 : std::string iargn = fixArgumentName( theargs[i]->getName() );
358 30 : action->readInputLine( action->getShortcutLabel() + "_ref_" + iargn + ": PDB2CONSTANT REFERENCE=" + reference + " ARG=" + theargs[i]->getName() );
359 15 : if( i==0 ) {
360 5 : instargs=" ARG1=" + theargs[i]->getName();
361 10 : refargs=" ARG2=" + action->getShortcutLabel() + "_ref_" + iargn;
362 : } else {
363 10 : instargs +="," + theargs[i]->getName();
364 20 : refargs +="," + action->getShortcutLabel() + "_ref_" + iargn;
365 : }
366 15 : if( pdb.getPositions().size()==0 && i==0 ) {
367 10 : reference_data = action->getShortcutLabel() + "_ref_" + iargn;
368 : } else {
369 20 : reference_data += "," + action->getShortcutLabel() + "_ref_" + iargn;
370 : }
371 : }
372 5 : std::string comname="EUCLIDEAN_DISTANCE SQUARED";
373 : std::string coeffstr;
374 10 : action->parse("COEFFICIENTS",coeffstr);
375 5 : if( coeffstr.length()>0 ) {
376 1 : if( displacements ) {
377 0 : action->error("cannot use COEFFICIENTS arguments with GEOMETRIC PATH");
378 : }
379 2 : action->readInputLine( action->getShortcutLabel() + "_coeff: CONSTANT VALUES=" + coeffstr );
380 2 : action->readInputLine( action->getShortcutLabel() + "_coeff2: CUSTOM ARG=" + action->getShortcutLabel() + "_coeff FUNC=x*x PERIODIC=NO");
381 2 : comname = "NORMALIZED_EUCLIDEAN_DISTANCE SQUARED METRIC=" + action->getShortcutLabel() + "_coeff2";
382 4 : } else if( displacements ) {
383 : comname = "DISPLACEMENT";
384 : }
385 :
386 5 : if( pdb.getPositions().size()==0 ) {
387 10 : action->readInputLine( action->getShortcutLabel() + "_data: " + comname + instargs + refargs );
388 : } else {
389 0 : action->readInputLine( action->getShortcutLabel() + "_argdata: " + comname + instargs + refargs );
390 : }
391 : }
392 14 : }
393 :
394 15 : void Path::readPropertyInformation( const std::vector<std::string>& pnames, const std::string& lab, const std::string& refname, ActionShortcut* action ) {
395 15 : if( pnames.size()>0 ) {
396 15 : for(unsigned i=0; i<pnames.size(); ++i) {
397 20 : action->readInputLine( pnames[i] + ": CONSTANT VALUE=1");
398 20 : action->readInputLine( pnames[i] + "_ref: PDB2CONSTANT REFERENCE=" + refname + " ARG=" + pnames[i] );
399 : }
400 : } else {
401 10 : ActionWithValue* av=action->plumed.getActionSet().selectWithLabel<ActionWithValue*>( lab + "_data" );
402 10 : unsigned nfram = av->copyOutput(0)->getShape()[0];
403 10 : std::string indices = "VALUES=1";
404 430 : for(unsigned i=1; i<nfram; ++i) {
405 : std::string num;
406 420 : Tools::convert( i+1, num );
407 840 : indices += "," + num;
408 : }
409 20 : action->readInputLine( lab + "_ind: CONSTANT " + indices );
410 : }
411 15 : }
412 :
413 : }
414 : }
|