Line data Source code
1 : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 : Copyright (c) 2012-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 "CLTool.h"
23 : #include "core/CLToolRegister.h"
24 : #include "tools/Tools.h"
25 : #include "core/Action.h"
26 : #include "core/ActionRegister.h"
27 : #include "core/PlumedMain.h"
28 : #include "tools/Communicator.h"
29 : #include "tools/Random.h"
30 : #include <cstdio>
31 : #include <string>
32 : #include <vector>
33 : #include <iostream>
34 : #include "tools/File.h"
35 : #include "core/Value.h"
36 : #include "tools/Matrix.h"
37 :
38 : namespace PLMD {
39 : namespace cltools {
40 :
41 : //+PLUMEDOC TOOLS sum_hills
42 : /*
43 : sum_hills is a tool that allows one to to use plumed to post-process an existing hills/colvar file
44 :
45 : \par Examples
46 :
47 : a typical case is about the integration of a hills file:
48 :
49 : \verbatim
50 : plumed sum_hills --hills PATHTOMYHILLSFILE
51 : \endverbatim
52 :
53 : The default name for the output file will be fes.dat
54 : Note that starting from this version plumed will automatically detect the
55 : number of the variables you have and their periodicity.
56 : Additionally, if you use flexible hills (multivariate Gaussian kernels), plumed will understand it from the HILLS file.
57 :
58 : The sum_hills tool will also accept multiple files that will be integrated one after the other
59 :
60 : \verbatim
61 : plumed sum_hills --hills PATHTOMYHILLSFILE1,PATHTOMYHILLSFILE2,PATHTOMYHILLSFILE3
62 : \endverbatim
63 :
64 : if you want to integrate out some variable you do
65 :
66 : \verbatim
67 : plumed sum_hills --hills PATHTOMYHILLSFILE --idw t1 --kt 0.6
68 : \endverbatim
69 :
70 : where with --idw you define the variables that you want
71 : all the others will be integrated out. --kt defines the temperature of the system in energy units.
72 : (be consistent with the units you have in your hills: plumed will not check this for you)
73 : If you need more variables then you may use a comma separated syntax
74 :
75 : \verbatim
76 : plumed sum_hills --hills PATHTOMYHILLSFILE --idw t1,t2 --kt 0.6
77 : \endverbatim
78 :
79 : You can define the output grid only with the number of bins you want
80 : while min/max will be detected for you
81 :
82 : \verbatim
83 : plumed sum_hills --bin 99,99 --hills PATHTOMYHILLSFILE
84 : \endverbatim
85 :
86 : or full grid specification
87 :
88 : \verbatim
89 : plumed sum_hills --bin 99,99 --min -pi,-pi --max pi,pi --hills PATHTOMYHILLSFILE
90 : \endverbatim
91 :
92 : You can of course use numbers instead of -pi/pi.
93 :
94 : You can use a --stride keyword to have a dump each bunch of hills you read
95 : \verbatim
96 : plumed sum_hills --stride 300 --hills PATHTOMYHILLSFILE
97 : \endverbatim
98 :
99 : You can also have, in case of well tempered metadynamics, only the negative
100 : bias instead of the free energy through the keyword --negbias
101 :
102 : \verbatim
103 : plumed sum_hills --negbias --hills PATHTOMYHILLSFILE
104 : \endverbatim
105 :
106 : Here the default name will be negativebias.dat
107 :
108 : From time to time you might need to use HILLS or a COLVAR file
109 : as it was just a simple set of points from which you want to build
110 : a free energy by using -(1/beta)log(P)
111 : then you use --histo
112 :
113 : \verbatim
114 : plumed sum_hills --histo PATHTOMYCOLVARORHILLSFILE --sigma 0.2,0.2 --kt 0.6
115 : \endverbatim
116 :
117 : in this case you need a --kt to do the reweighting and then you
118 : need also some width (with the --sigma keyword) for the histogram calculation (actually will be done with
119 : Gaussian kernels, so it will be a continuous histogram)
120 : Here the default output will be histo.dat.
121 : Note that also here you can have multiple input files separated by a comma.
122 :
123 : Additionally, if you want to do histogram and hills from the same file you can do as this
124 : \verbatim
125 : plumed sum_hills --hills --histo PATHTOMYCOLVARORHILLSFILE --sigma 0.2,0.2 --kt 0.6
126 : \endverbatim
127 : The two files can be eventually the same
128 :
129 : Another interesting thing one can do is monitor the difference in blocks as a metadynamics goes on.
130 : When the bias deposited is constant over the whole domain one can consider to be at convergence.
131 : This can be done with the --nohistory keyword
132 :
133 : \verbatim
134 : plumed sum_hills --stride 300 --hills PATHTOMYHILLSFILE --nohistory
135 : \endverbatim
136 :
137 : and similarly one can do the same for an histogram file
138 :
139 : \verbatim
140 : plumed sum_hills --histo PATHTOMYCOLVARORHILLSFILE --sigma 0.2,0.2 --kt 0.6 --nohistory
141 : \endverbatim
142 :
143 : just to check the hypothetical free energy calculated in single blocks of time during a simulation
144 : and not in a cumulative way
145 :
146 : Output format can be controlled via the --fmt field
147 :
148 : \verbatim
149 : plumed sum_hills --hills PATHTOMYHILLSFILE --fmt %8.3f
150 : \endverbatim
151 :
152 : where here we chose a float with length of 8 and 3 digits
153 :
154 : The output can be named in a arbitrary way :
155 :
156 : \verbatim
157 : plumed sum_hills --hills PATHTOMYHILLSFILE --outfile myfes.dat
158 : \endverbatim
159 :
160 : will produce a file myfes.dat which contains the free energy.
161 :
162 : If you use stride, this keyword is the suffix
163 :
164 : \verbatim
165 : plumed sum_hills --hills PATHTOMYHILLSFILE --outfile myfes_ --stride 100
166 : \endverbatim
167 :
168 : will produce myfes_0.dat, myfes_1.dat, myfes_2.dat etc.
169 :
170 : The same is true for the output coming from histogram
171 : \verbatim
172 : plumed sum_hills --histo HILLS --kt 2.5 --sigma 0.01 --outhisto myhisto.dat
173 : \endverbatim
174 :
175 : is producing a file myhisto.dat
176 : while, when using stride, this is the suffix
177 :
178 : \verbatim
179 : plumed sum_hills --histo HILLS --kt 2.5 --sigma 0.01 --outhisto myhisto_ --stride 100
180 : \endverbatim
181 :
182 : that gives myhisto_0.dat, myhisto_1.dat, myhisto_3.dat etc..
183 :
184 : */
185 : //+ENDPLUMEDOC
186 :
187 : class CLToolSumHills : public CLTool {
188 : public:
189 : static void registerKeywords( Keywords& keys );
190 : explicit CLToolSumHills(const CLToolOptions& co );
191 : int main(FILE* in,FILE*out,Communicator& pc) override;
192 : std::string description()const override;
193 : /// find a list of variables present, if they are periodic and which is the period
194 : /// return false if the file does not exist
195 : static bool findCvsAndPeriodic(const std::string & filename, std::vector< std::vector <std::string> > &cvs,std::vector<std::string> &pmin,std::vector<std::string> &pmax, bool &multivariate, std::string &lowI_, std::string &uppI_);
196 : };
197 :
198 5442 : void CLToolSumHills::registerKeywords( Keywords& keys ) {
199 5442 : CLTool::registerKeywords( keys );
200 10884 : keys.addFlag("--help-debug",false,"print special options that can be used to create regtests");
201 10884 : keys.add("optional","--hills","specify the name of the hills file");
202 10884 : keys.add("optional","--histo","specify the name of the file for histogram a colvar/hills file is good");
203 10884 : keys.add("optional","--stride","specify the stride for integrating hills file (default 0=never)");
204 10884 : keys.add("optional","--min","the lower bounds for the grid");
205 10884 : keys.add("optional","--max","the upper bounds for the grid");
206 10884 : keys.add("optional","--bin","the number of bins for the grid");
207 10884 : keys.add("optional","--spacing","grid spacing, alternative to the number of bins");
208 10884 : keys.add("optional","--idw","specify the variables to be used for the free-energy/histogram (default is all). With --hills the other variables will be integrated out, with --histo the other variables won't be considered");
209 10884 : keys.add("optional","--outfile","specify the output file for sumhills");
210 10884 : keys.add("optional","--outhisto","specify the output file for the histogram");
211 10884 : keys.add("optional","--kt","specify temperature in energy units for integrating out variables");
212 10884 : keys.add("optional","--sigma"," a vector that specify the sigma for binning (only needed when doing histogram ");
213 10884 : keys.addFlag("--negbias",false," print the negative bias instead of the free energy (only needed with well tempered runs and flexible hills) ");
214 10884 : keys.addFlag("--nohistory",false," to be used with --stride: it splits the bias/histogram in pieces without previous history ");
215 10884 : keys.addFlag("--mintozero",false," it translate all the minimum value in bias/histogram to zero (useful to compare results) ");
216 10884 : keys.add("optional","--fmt","specify the output format");
217 5442 : }
218 :
219 13 : CLToolSumHills::CLToolSumHills(const CLToolOptions& co ):
220 13 : CLTool(co) {
221 13 : inputdata=commandline;
222 13 : }
223 :
224 4 : std::string CLToolSumHills::description()const {
225 4 : return "sum the hills with plumed";
226 : }
227 :
228 9 : int CLToolSumHills::main(FILE* in,FILE*out,Communicator& pc) {
229 :
230 : // Read the hills input file name
231 : std::vector<std::string> hillsFiles;
232 : bool dohills;
233 18 : dohills=parseVector("--hills",hillsFiles);
234 : // Read the histogram file
235 : std::vector<std::string> histoFiles;
236 : bool dohisto;
237 9 : dohisto=parseVector("--histo",histoFiles);
238 :
239 9 : plumed_massert(dohisto || dohills,"you should use --histo or/and --hills command");
240 :
241 : std::vector< std::vector<std::string> > vcvs;
242 : std::vector<std::string> vpmin;
243 : std::vector<std::string> vpmax;
244 : std::string lowI_, uppI_;
245 9 : if(dohills) {
246 : // parse it as it was a restart
247 : bool vmultivariate;
248 8 : findCvsAndPeriodic(hillsFiles[0], vcvs, vpmin, vpmax, vmultivariate, lowI_, uppI_);
249 : }
250 :
251 : std::vector< std::vector<std::string> > hcvs;
252 : std::vector<std::string> hpmin;
253 : std::vector<std::string> hpmax;
254 :
255 : std::vector<std::string> sigma;
256 9 : if(dohisto) {
257 : bool hmultivariate;
258 1 : findCvsAndPeriodic(histoFiles[0], hcvs, hpmin, hpmax, hmultivariate, lowI_, uppI_);
259 : // here need also the vector of sigmas
260 2 : parseVector("--sigma",sigma);
261 1 : if(sigma.size()==0) {
262 0 : plumed_merror("you should define --sigma vector when using histogram");
263 : }
264 : lowI_=uppI_="-1."; // Interval is not use for histograms
265 : }
266 :
267 9 : if(dohisto && dohills) {
268 0 : plumed_massert(vcvs==hcvs,"variables for histogram and bias should have the same labels");
269 0 : plumed_massert(hpmin==vpmin,"variables for histogram and bias should have the same min for periodicity");
270 0 : plumed_massert(hpmax==vpmax,"variables for histogram and bias should have the same max for periodicity");
271 : }
272 :
273 : // now put into a neutral vector
274 :
275 : std::vector< std::vector<std::string> > cvs;
276 : std::vector<std::string> pmin;
277 : std::vector<std::string> pmax;
278 :
279 9 : if(dohills) {
280 8 : cvs=vcvs;
281 8 : pmin=vpmin;
282 8 : pmax=vpmax;
283 : }
284 9 : if(dohisto) {
285 1 : cvs=hcvs;
286 1 : pmin=hpmin;
287 1 : pmax=hpmax;
288 : }
289 :
290 :
291 : // setup grids
292 : unsigned grid_check=0;
293 9 : std::vector<std::string> gmin(cvs.size());
294 18 : if(parseVector("--min",gmin)) {
295 4 : if(gmin.size()!=cvs.size() && gmin.size()!=0) {
296 0 : plumed_merror("not enough values for --min");
297 : }
298 : grid_check++;
299 : }
300 9 : std::vector<std::string> gmax(cvs.size() );
301 18 : if(parseVector("--max",gmax)) {
302 4 : if(gmax.size()!=cvs.size() && gmax.size()!=0) {
303 0 : plumed_merror("not enough values for --max");
304 : }
305 4 : grid_check++;
306 : }
307 9 : std::vector<std::string> gbin(cvs.size());
308 : bool grid_has_bin;
309 : grid_has_bin=false;
310 18 : if(parseVector("--bin",gbin)) {
311 5 : if(gbin.size()!=cvs.size() && gbin.size()!=0) {
312 0 : plumed_merror("not enough values for --bin");
313 : }
314 : grid_has_bin=true;
315 : }
316 9 : std::vector<std::string> gspacing(cvs.size());
317 : bool grid_has_spacing;
318 : grid_has_spacing=false;
319 18 : if(parseVector("--spacing",gspacing)) {
320 1 : if(gspacing.size()!=cvs.size() && gspacing.size()!=0) {
321 0 : plumed_merror("not enough values for --spacing");
322 : }
323 : grid_has_spacing=true;
324 : }
325 : // allowed: no grids only bin
326 : // not allowed: partial grid definition
327 9 : plumed_massert( gmin.size()==gmax.size() && (gmin.size()==0 || gmin.size()==cvs.size() ),"you should specify --min and --max together with same number of components");
328 :
329 :
330 :
331 9 : PlumedMain plumed;
332 : std::string ss;
333 9 : unsigned nn=1;
334 : ss="setNatoms";
335 9 : plumed.cmd(ss,&nn);
336 9 : if(Communicator::initialized()) {
337 0 : plumed.cmd("setMPIComm",&pc.Get_comm());
338 : }
339 9 : plumed.cmd("init",&nn);
340 9 : std::vector <bool> isdone(cvs.size(),false);
341 26 : for(unsigned i=0; i<cvs.size(); i++) {
342 17 : if(!isdone[i]) {
343 : isdone[i]=true;
344 : std::vector<std::string> actioninput;
345 : std::vector <unsigned> inds;
346 17 : actioninput.push_back("FAKE");
347 34 : actioninput.push_back("ATOMS=1");
348 34 : actioninput.push_back("LABEL="+cvs[i][0]);
349 : std::vector<std::string> comps, periods;
350 17 : if(cvs[i].size()>1) {
351 1 : comps.push_back(cvs[i][1]);
352 1 : inds.push_back(i);
353 : }
354 17 : periods.push_back(pmin[i]);
355 17 : periods.push_back(pmax[i]);
356 25 : for(unsigned j=i+1; j<cvs.size(); j++) {
357 8 : if(cvs[i][0]==cvs[j][0] && !isdone[j]) {
358 0 : if(cvs[i].size()==1 || cvs[j].size()==1 ) {
359 0 : plumed_merror("you cannot have twice the same label and no components ");
360 : }
361 0 : if(cvs[j].size()>1) {
362 0 : comps.push_back(cvs[j][1]);
363 0 : periods.push_back(pmin[j]);
364 0 : periods.push_back(pmax[j]);
365 : isdone[j]=true;
366 0 : inds.push_back(j);
367 : }
368 : }
369 :
370 : }
371 : // drain all the components
372 : std::string addme;
373 17 : if(comps.size()>0) {
374 : addme="COMPONENTS=";
375 1 : for(unsigned i=0; i<comps.size()-1; i++) {
376 0 : addme+=comps[i]+",";
377 : }
378 : addme+=comps.back();
379 1 : actioninput.push_back(addme);
380 : }
381 : // periodicity (always explicit here)
382 : addme="PERIODIC=";
383 34 : for(unsigned j=0; j<periods.size()-1; j++) {
384 34 : addme+=periods[j]+",";
385 : }
386 : addme+=periods.back();
387 17 : actioninput.push_back(addme);
388 18 : for(unsigned j=0; j<inds.size(); j++) {
389 : unsigned jj;
390 1 : jj=inds[j];
391 1 : if(grid_check==2) {
392 : double gm;
393 : double pm;
394 1 : if(pmin[jj]!="none") {
395 1 : Tools::convert(gmin[jj],gm);
396 1 : Tools::convert(pmin[jj],pm);
397 1 : if( gm<pm ) {
398 0 : plumed_merror("Periodicity issue : GRID_MIN value ( "+gmin[jj]+" ) is less than periodicity in HILLS file in "+cvs[jj][0]+ " ( "+pmin[jj]+" ) ");
399 : }
400 : }
401 1 : if(pmax[jj]!="none") {
402 1 : Tools::convert(gmax[jj],gm);
403 1 : Tools::convert(pmax[jj],pm);
404 1 : if( gm>pm ) {
405 0 : plumed_merror("Periodicity issue : GRID_MAX value ( "+gmax[jj]+" ) is more than periodicity in HILLS file in "+cvs[jj][0]+ " ( "+pmax[jj]+" ) ");
406 : }
407 : }
408 : }
409 : }
410 :
411 : // for(unsigned i=0;i< actioninput.size();i++){
412 : // cerr<<"AA "<<actioninput[i]<<endl;
413 : // }
414 17 : plumed.readInputWords(actioninput,false);
415 34 : }
416 :
417 : }
418 9 : unsigned ncv=cvs.size();
419 : std::vector<std::string> actioninput;
420 : std::vector<std::string> idw;
421 : // check if the variables to be used are correct
422 18 : if(parseVector("--idw",idw)) {
423 4 : for(unsigned i=0; i<idw.size(); i++) {
424 : bool found=false;
425 6 : for(unsigned j=0; j<cvs.size(); j++) {
426 4 : if(cvs[j].size()>1) {
427 0 : if(idw[i]==cvs[j][0]+"."+cvs[j][1]) {
428 : found=true;
429 : }
430 : } else {
431 4 : if(idw[i]==cvs[j][0]) {
432 : found=true;
433 : }
434 : }
435 : }
436 2 : if(!found) {
437 0 : plumed_merror("variable "+idw[i]+" is not found in the bunch of cvs: revise your --idw option" );
438 : }
439 : }
440 2 : plumed_massert( idw.size()<=cvs.size(),"the number of variables to be integrated should be at most equal to the total number of cvs ");
441 : // in this case you need a beta factor!
442 : }
443 :
444 : std::string kt;
445 9 : kt=std::string("1.");// assign an arbitrary value just in case that idw.size()==cvs.size()
446 9 : if ( dohisto || idw.size()!=0 ) {
447 6 : plumed_massert(parse("--kt",kt),"if you make a dimensionality reduction (--idw) or a histogram (--histo) then you need to define --kt ");
448 : }
449 :
450 : std::string addme;
451 :
452 9 : actioninput.push_back("FUNCSUMHILLS");
453 18 : actioninput.push_back("ISCLTOOL");
454 :
455 : // set names
456 : std::string outfile;
457 18 : if(parse("--outfile",outfile)) {
458 0 : actioninput.push_back("OUTHILLS="+outfile);
459 : }
460 : std::string outhisto;
461 18 : if(parse("--outhisto",outhisto)) {
462 2 : actioninput.push_back("OUTHISTO="+outhisto);
463 : }
464 :
465 :
466 : addme="ARG=";
467 17 : for(unsigned i=0; i<(ncv-1); i++) {
468 8 : if(cvs[i].size()==1) {
469 16 : addme+=std::string(cvs[i][0])+",";
470 : } else {
471 0 : addme+=std::string(cvs[i][0])+"."+std::string(cvs[i][1])+",";
472 : }
473 : }
474 9 : if(cvs[ncv-1].size()==1) {
475 16 : addme+=std::string(cvs[ncv-1][0]);
476 : } else {
477 2 : addme+=std::string(cvs[ncv-1][0])+"."+std::string(cvs[ncv-1][1]);
478 : }
479 9 : actioninput.push_back(addme);
480 : //for(unsigned i=0;i< actioninput.size();i++){
481 : // cerr<<"AA "<<actioninput[i]<<endl;
482 : //}
483 9 : if(dohills) {
484 : addme="HILLSFILES=";
485 9 : for(unsigned i=0; i<hillsFiles.size()-1; i++) {
486 2 : addme+=hillsFiles[i]+",";
487 : }
488 : addme+=hillsFiles[hillsFiles.size()-1];
489 8 : actioninput.push_back(addme);
490 : // set the grid
491 : }
492 9 : if(grid_check==2) {
493 : addme="GRID_MAX=";
494 7 : for(unsigned i=0; i<(ncv-1); i++) {
495 6 : addme+=gmax[i]+",";
496 : }
497 : addme+=gmax[ncv-1];
498 4 : actioninput.push_back(addme);
499 : addme="GRID_MIN=";
500 7 : for(unsigned i=0; i<(ncv-1); i++) {
501 6 : addme+=gmin[i]+",";
502 : }
503 : addme+=gmin[ncv-1];
504 4 : actioninput.push_back(addme);
505 : }
506 9 : if(grid_has_bin) {
507 : addme="GRID_BIN=";
508 10 : for(unsigned i=0; i<(ncv-1); i++) {
509 10 : addme+=gbin[i]+",";
510 : }
511 : addme+=gbin[ncv-1];
512 5 : actioninput.push_back(addme);
513 : }
514 9 : if(grid_has_spacing) {
515 : addme="GRID_SPACING=";
516 1 : for(unsigned i=0; i<(ncv-1); i++) {
517 0 : addme+=gspacing[i]+",";
518 : }
519 : addme+=gspacing[ncv-1];
520 1 : actioninput.push_back(addme);
521 : }
522 : std::string stride;
523 : stride="";
524 18 : if(parse("--stride",stride)) {
525 1 : actioninput.push_back("INITSTRIDE="+stride);
526 : bool nohistory;
527 1 : parseFlag("--nohistory",nohistory);
528 1 : if(nohistory) {
529 0 : actioninput.push_back("NOHISTORY");
530 : }
531 : }
532 : bool mintozero;
533 9 : parseFlag("--mintozero",mintozero);
534 9 : if(mintozero) {
535 0 : actioninput.push_back("MINTOZERO");
536 : }
537 9 : if(idw.size()!=0) {
538 : addme="PROJ=";
539 2 : for(unsigned i=0; i<idw.size()-1; i++) {
540 0 : addme+=idw[i]+",";
541 : }
542 : addme+=idw.back();
543 2 : actioninput.push_back(addme);
544 : }
545 :
546 9 : if(dohisto) {
547 1 : if(idw.size()==0) {
548 1 : if(sigma.size()!=hcvs.size()) {
549 0 : plumed_merror("you should define as many --sigma vector as the number of collective variable used for the histogram ");
550 : }
551 : } else {
552 0 : if(idw.size()!=sigma.size()) {
553 0 : plumed_merror("you should define as many --sigma vector as the number of collective variable used for the histogram ");
554 : }
555 : }
556 : }
557 :
558 9 : if(idw.size()!=0 || dohisto) {
559 6 : actioninput.push_back("KT="+kt);
560 : }
561 9 : if(dohisto) {
562 : addme="HISTOFILES=";
563 1 : for(unsigned i=0; i<histoFiles.size()-1; i++) {
564 0 : addme+=histoFiles[i]+",";
565 : }
566 : addme+=histoFiles[histoFiles.size()-1];
567 1 : actioninput.push_back(addme);
568 :
569 : addme="HISTOSIGMA=";
570 2 : for(unsigned i=0; i<sigma.size()-1; i++) {
571 2 : addme+=sigma[i]+",";
572 : }
573 : addme+=sigma.back();
574 1 : actioninput.push_back(addme);
575 : }
576 :
577 : bool negbias;
578 9 : parseFlag("--negbias",negbias);
579 9 : if(negbias) {
580 2 : actioninput.push_back("NEGBIAS");
581 : }
582 :
583 9 : if(lowI_!=uppI_) {
584 : addme="INTERVAL=";
585 0 : addme+=lowI_+",";
586 : addme+=uppI_;
587 0 : actioninput.push_back(addme);
588 : }
589 :
590 : std::string fmt;
591 : fmt="";
592 18 : parse("--fmt",fmt);
593 9 : if(fmt!="") {
594 18 : actioninput.push_back("FMT="+fmt);
595 : }
596 :
597 :
598 : // for(unsigned i=0;i< actioninput.size();i++){
599 : // cerr<<"AA "<<actioninput[i]<<endl;
600 : // }
601 9 : plumed.readInputWords(actioninput,false);
602 : // if not a grid, then set it up automatically
603 9 : return 0;
604 27 : }
605 :
606 9 : bool CLToolSumHills::findCvsAndPeriodic(const std::string & filename, std::vector< std::vector<std::string> > &cvs, std::vector<std::string> &pmin,std::vector<std::string> &pmax, bool &multivariate, std::string &lowI_, std::string &uppI_) {
607 9 : IFile ifile;
608 9 : ifile.allowIgnoredFields();
609 : std::vector<std::string> fields;
610 9 : if(ifile.FileExist(filename)) {
611 : cvs.clear();
612 : pmin.clear();
613 : pmax.clear();
614 9 : ifile.open(filename);
615 9 : ifile.scanFieldList(fields);
616 : bool before_sigma=true;
617 121 : for(unsigned i=0; i<fields.size(); i++) {
618 : size_t pos = 0;
619 : size_t founds,foundm,foundp;
620 : //found=(fields[i].find("sigma_", pos) || fields[i].find("min_", pos) || fields[i].find("max_", pos) ) ;
621 112 : founds=fields[i].find("sigma_", pos) ;
622 112 : foundm=fields[i].find("min_", pos) ;
623 112 : foundp=fields[i].find("max_", pos) ;
624 112 : if (founds!=std::string::npos || foundm!=std::string::npos || foundp!=std::string::npos ) {
625 : before_sigma=false;
626 : }
627 : // cvs are after time and before sigmas
628 : size_t found;
629 112 : found=fields[i].find("time", pos);
630 112 : if( found==std::string::npos && before_sigma) {
631 : // separate the components
632 : size_t dot=fields[i].find_first_of('.');
633 : std::vector<std::string> ss;
634 : // this loop does not take into account repetitions
635 17 : if(dot!=std::string::npos) {
636 1 : std::string a=fields[i].substr(0,dot);
637 1 : std::string name=fields[i].substr(dot+1);
638 1 : ss.push_back(a);
639 1 : ss.push_back(name);
640 1 : cvs.push_back(ss);
641 : } else {
642 : std::vector<std::string> ss;
643 16 : ss.push_back(fields[i]);
644 16 : cvs.push_back(ss);
645 16 : }
646 : //std::cerr<<"found variable number "<<cvs.size()<<" : "<<cvs.back()[0]<<std::endl;
647 : //if((cvs.back()).size()!=1){
648 : // std::cerr<<"component "<<(cvs.back()).back()<<std::endl;
649 : //}
650 : // get periodicity
651 17 : pmin.push_back("none");
652 34 : pmax.push_back("none");
653 : std::string mm;
654 17 : if((cvs.back()).size()>1) {
655 2 : mm=cvs.back()[0]+"."+cvs.back()[1];
656 : } else {
657 : mm=cvs.back()[0];
658 : }
659 34 : if(ifile.FieldExist("min_"+mm)) {
660 : std::string val;
661 28 : ifile.scanField("min_"+mm,val);
662 : pmin[pmin.size()-1]=val;
663 : // std::cerr<<"found min : "<<pmin.back()<<std::endl;
664 : }
665 : //std::cerr<<"found min : "<<pmin.back()<<std::endl;
666 34 : if(ifile.FieldExist("max_"+mm)) {
667 : std::string val;
668 28 : ifile.scanField("max_"+mm,val);
669 : pmax[pmax.size()-1]=val;
670 : // std::cerr<<"found max : "<<pmax.back()<<std::endl;
671 : }
672 : //std::cerr<<"found max : "<<pmax.back()<<std::endl;
673 17 : }
674 : }
675 : // is multivariate ???
676 : std::string sss;
677 9 : multivariate=false;
678 18 : if(ifile.FieldExist("multivariate")) {
679 : ;
680 18 : ifile.scanField("multivariate",sss);
681 9 : if(sss=="true") {
682 6 : multivariate=true;
683 3 : } else if(sss=="false") {
684 3 : multivariate=false;
685 : }
686 : }
687 : // do interval?
688 18 : if(ifile.FieldExist("lower_int")) {
689 0 : ifile.scanField("lower_int",lowI_);
690 0 : ifile.scanField("upper_int",uppI_);
691 : } else {
692 : lowI_="-1.";
693 : uppI_="-1.";
694 : }
695 9 : ifile.scanField();
696 : return true;
697 : } else {
698 : return false;
699 : }
700 9 : }
701 :
702 :
703 16339 : PLUMED_REGISTER_CLTOOL(CLToolSumHills,"sum_hills")
704 :
705 :
706 :
707 : }
708 : }
|