24 #include "tools/PDB.h"
28 #ifdef __PLUMED_HAS_CREGEX
36 void ActionWithArguments::registerKeywords(
Keywords& keys){
37 keys.
reserve(
"compulsory",
"ARG",
"the input for this action is the output from one or more other actions. The particular output that you used is referenced using that action of interests label. If the label appears on its own then the value of the relevant Action is taken. If * or *.* appears the information from all arguments is taken. Some actions have multi-component outputs, each component of the output has a specific label so for instance an action labelled dist may have three componets x, y and z. To take just the x component you should use dist.x, if you wish to take all three components then use dist.*");
40 void ActionWithArguments::parseArgumentList(
const std::string&key,std::vector<Value*>&arg){
41 vector<string> c; arg.clear(); parseVector(key,c); interpretArgumentList(c,arg);
44 void ActionWithArguments::interpretArgumentList(
const std::vector<std::string>& c, std::vector<Value*>&arg){
46 for(
unsigned i=0;i<c.size();i++){
48 std::size_t found1 = c[i].find(
"(");
50 if(found1!=std::string::npos){
51 found2=c[i].find(
")",found1+1,1);
52 if(found2!=std::string::npos){
54 #ifdef __PLUMED_HAS_CREGEX
56 std::string myregex=c[i].substr(found1,found2-found1+1);
57 log.printf(
" Evaluating regexp for this action: %s \n",myregex.c_str());
59 regex_t *preg = (regex_t*)malloc(
sizeof(regex_t));
61 if ((errcode=regcomp(preg, myregex.c_str() ,REG_EXTENDED|REG_NEWLINE))) {
65 errbuf_size = regerror(errcode, preg, NULL, 0);
66 if (!(errbuf=(
char*)malloc(errbuf_size))) {
67 plumed_merror(
"cannot allocate the buffer for error detection in regexp!");
69 regerror(errcode, preg, errbuf, errbuf_size);
72 plumed_massert(preg->re_nsub==1,
"I can parse with only one subexpression");
73 pmatch = (regmatch_t*)malloc(
sizeof(regmatch_t)*preg->re_nsub);
76 if( all.empty() ) error(
"your input file is not telling plumed to calculate anything");
77 for(
unsigned j=0;j<all.size();j++){
78 std::string thisargument=all[j]->getLabel();
79 std::vector<std::string> ss=all[j]->getComponentsVector();
80 for(
unsigned k=0;k<ss.size();++k){
82 unsigned ll=strlen(ss[k].c_str())+1;
85 strcpy(str,ss[k].c_str());
87 if(!regexec(preg, ppstr , preg->re_nsub, pmatch, 0)) {
88 log.printf(
" Something matched with \"%s\" : ",ss[k].c_str());
90 if (pmatch[0].rm_so != -1) {
92 size_t matchlen = pmatch[0].rm_eo - pmatch[0].rm_so;
93 submatch = (
char*)malloc(matchlen+1);
94 strncpy(submatch, ppstr+pmatch[0].rm_so, matchlen+1);
95 submatch[matchlen]=
'\0';
96 log.printf(
" subpattern %s\n", submatch);
98 std::string putativeVal(submatch);
99 if( all[j]->exists(putativeVal) ){
100 arg.push_back(all[j]->copyOutput(putativeVal));
101 log.printf(
" Action %s added! \n",putativeVal.c_str());
105 ppstr += pmatch[0].rm_eo;
106 }
while(!regexec(preg,ppstr,preg->re_nsub,pmatch,0));
115 plumed_merror(
"Regexp support not compiled!");
118 plumed_merror(
"did you want to use regexp to input arguments? enclose it between two round braces (...) with no spaces!");
121 std::size_t dot=c[i].find_first_of(
'.');
122 string a=c[i].substr(0,dot);
123 string name=c[i].substr(dot+1);
124 if(c[i].find(
".")!=string::npos){
125 if(a==
"*" && name==
"*"){
128 if( all.empty() ) error(
"your input file is not telling plumed to calculate anything");
129 for(
unsigned j=0;j<all.size();j++){
130 for(
int k=0;k<all[j]->getNumberOfComponents();++k) arg.push_back(all[j]->copyOutput(k));
132 }
else if ( name==
"*"){
136 std::string str=
" (hint! the actions in this ActionSet are: ";
137 str+=
plumed.getActionSet().getLabelList()+
")";
138 error(
"cannot find action named " + a + str);
141 }
else if ( a==
"*" ){
144 if( all.empty() ) error(
"your input file is not telling plumed to calculate anything");
146 for(
unsigned j=0;j<all.size();j++){
147 std::string flab; flab=all[j]->getLabel() +
"." + name;
148 if( all[j]->exists(flab) ){ arg.push_back(all[j]->copyOutput(flab)); nval++; }
150 if(nval==0) error(
"found no actions with a component called " + name );
155 std::string str=
" (hint! the actions in this ActionSet are: ";
156 str+=
plumed.getActionSet().getLabelList()+
")";
157 error(
"cannot find action named " + a +str);
159 if( !(action->
exists(c[i])) ){
160 std::string str=
" (hint! the components in this actions are: ";
162 error(
"action " + a +
" has no component named " + name + str);
170 if( all.empty() ) error(
"your input file is not telling plumed to calculate anything");
171 for(
unsigned j=0;j<all.size();j++){
172 for(
int k=0;k<all[j]->getNumberOfComponents();++k) arg.push_back(all[j]->copyOutput(k));
177 std::string str=
" (hint! the actions in this ActionSet are: ";
178 str+=
plumed.getActionSet().getLabelList()+
")";
179 error(
"cannot find action named " + c[i] + str );
181 if( !(action->
exists(c[i])) ){
182 std::string str=
" (hint! the components in this actions are: ";
184 error(
"action " + c[i] +
" has no component named " + c[i] +str);
193 void ActionWithArguments::expandArgKeywordInPDB(
PDB& pdb ){
194 std::vector<std::string> pdb_remark=pdb.
getRemark();
195 std::vector<std::string> arg_names;
196 bool found=Tools::parseVector(pdb_remark,
"ARG",arg_names);
198 std::vector<Value*> arg_vals;
199 interpretArgumentList( arg_names, arg_vals );
200 std::string new_args=
"ARG=" + arg_vals[0]->getName();
201 for(
unsigned i=1;i<arg_vals.size();++i) new_args = new_args +
"," + arg_vals[i]->getName();
206 void ActionWithArguments::requestArguments(
const vector<Value*> &arg){
207 plumed_massert(!lockRequestArguments,
"requested argument list can only be changed in the prepare() method");
210 std::string fullname,name;
211 for(
unsigned i=0;i<arguments.size();i++){
212 fullname=arguments[i]->getName();
213 if(fullname.find(
".")!=string::npos){
214 std::size_t dot=fullname.find_first_of(
'.');
215 name=fullname.substr(0,dot);
220 plumed_massert(action,
"cannot find action named (in requestArguments - this is weird)" + name);
221 addDependency(action);
227 lockRequestArguments(false)
235 for(
unsigned i=0;i<arg.size();i++)
log.
printf(
" %s",arg[i]->getName().c_str());
245 plumed_massert(a,
"cannot compute numerical derivatives for an action without values");
250 std::vector<double> value (nval*npar);
251 for(
int i=0;i<npar;i++){
256 for(
unsigned j=0;j<nval;j++){
262 for(
unsigned j=0;j<nval;j++){
269 plumed_massert(i<
arguments.size(),
" making projections with an index which is too large");
270 plumed_massert(j<
arguments.size(),
" making projections with an index which is too large");
virtual void calculateNumericalDerivatives(ActionWithValue *a=NULL)
Calculate the numerical derivatives N.B.
Log & log
Reference to the log stream.
void parseArgumentList(const std::string &key, std::vector< Value * > &args)
Parse a list of arguments.
A class for holding the value of a function together with its derivatives.
void requestArguments(const std::vector< Value * > &arg)
Setup the dependencies.
virtual void calculate()=0
Calculate an Action.
std::vector< Value * > arguments
Used to create a PLMD::Action that has some scalar or vectorial output that may or may not have some ...
void setArgKeyword(const std::string &new_args)
This is used to set the keyword ARG - this is so we we can use a1.
This class holds the keywords and their documentation.
std::string getComponentsList() const
get a string that contains all the available components
bool exists(const std::string &name) const
Check if a value with a particular name is present.
This class is used to bring the relevant information to the Action constructor.
void addForcesOnArguments(const std::vector< double > &forces)
Add forces to arguments (used in apply)
int printf(const char *fmt,...)
Formatted output with explicit format - a la printf.
Base class for all the input Actions.
Value * copyOutput(const std::string &name) const
Return a pointer to the value with name (this is used to retrieve values in other PLMD::Actions) You ...
double getProjection(unsigned i, unsigned j) const
Get the scalar product between the gradients of two variables.
static double projection(const Value &, const Value &)
void reserve(const std::string &t, const std::string &k, const std::string &d, const bool isvessel=false)
Reserve a keyword.
double getOutputQuantity(const unsigned j) const
Get the value of one of the components of the PLMD::Action.
const std::vector< std::string > & getRemark() const
Access to the lines of REMARK.
bool exists(const std::string &k) const
Check if there is a keyword with name k.
virtual void clearDerivatives()
Clear the derivatives of values wrt parameters.
int getNumberOfComponents() const
Returns the number of values defined.
const Keywords & keywords
void addDerivative(unsigned i, double d)
Add some derivative to the ith component of the derivatives array.
bool hasDerivatives() const
Check whether or not this particular quantity has derivatives.