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 "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(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 3473 : void CLToolSumHills::registerKeywords( Keywords& keys ) {
199 3473 : CLTool::registerKeywords( keys );
200 6946 : keys.addFlag("--help-debug",false,"print special options that can be used to create regtests");
201 6946 : keys.add("optional","--hills","specify the name of the hills file");
202 6946 : keys.add("optional","--histo","specify the name of the file for histogram a colvar/hills file is good");
203 6946 : keys.add("optional","--stride","specify the stride for integrating hills file (default 0=never)");
204 6946 : keys.add("optional","--min","the lower bounds for the grid");
205 6946 : keys.add("optional","--max","the upper bounds for the grid");
206 6946 : keys.add("optional","--bin","the number of bins for the grid");
207 6946 : keys.add("optional","--spacing","grid spacing, alternative to the number of bins");
208 6946 : 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 6946 : keys.add("optional","--outfile","specify the output file for sumhills");
210 6946 : keys.add("optional","--outhisto","specify the output file for the histogram");
211 6946 : keys.add("optional","--kt","specify temperature in energy units for integrating out variables");
212 6946 : keys.add("optional","--sigma"," a vector that specify the sigma for binning (only needed when doing histogram ");
213 6946 : keys.addFlag("--negbias",false," print the negative bias instead of the free energy (only needed with well tempered runs and flexible hills) ");
214 6946 : keys.addFlag("--nohistory",false," to be used with --stride: it splits the bias/histogram in pieces without previous history ");
215 6946 : keys.addFlag("--mintozero",false," it translate all the minimum value in bias/histogram to zero (useful to compare results) ");
216 6946 : keys.add("optional","--fmt","specify the output format");
217 3473 : }
218 :
219 13 : CLToolSumHills::CLToolSumHills(const CLToolOptions& co ):
220 13 : CLTool(co)
221 : {
222 13 : inputdata=commandline;
223 13 : }
224 :
225 4 : std::string CLToolSumHills::description()const { return "sum the hills with plumed"; }
226 :
227 9 : int CLToolSumHills::main(FILE* in,FILE*out,Communicator& pc) {
228 :
229 : // Read the hills input file name
230 : std::vector<std::string> hillsFiles;
231 : bool dohills;
232 18 : dohills=parseVector("--hills",hillsFiles);
233 : // Read the histogram file
234 : std::vector<std::string> histoFiles;
235 : bool dohisto;
236 9 : dohisto=parseVector("--histo",histoFiles);
237 :
238 9 : plumed_massert(dohisto || dohills,"you should use --histo or/and --hills command");
239 :
240 : std::vector< std::vector<std::string> > vcvs;
241 : std::vector<std::string> vpmin;
242 : std::vector<std::string> vpmax;
243 : std::string lowI_, uppI_;
244 9 : if(dohills) {
245 : // parse it as it was a restart
246 : bool vmultivariate;
247 16 : findCvsAndPeriodic(hillsFiles[0], vcvs, vpmin, vpmax, vmultivariate, lowI_, uppI_);
248 : }
249 :
250 : std::vector< std::vector<std::string> > hcvs;
251 : std::vector<std::string> hpmin;
252 : std::vector<std::string> hpmax;
253 :
254 : std::vector<std::string> sigma;
255 9 : if(dohisto) {
256 : bool hmultivariate;
257 1 : findCvsAndPeriodic(histoFiles[0], hcvs, hpmin, hpmax, hmultivariate, lowI_, uppI_);
258 : // here need also the vector of sigmas
259 2 : parseVector("--sigma",sigma);
260 1 : if(sigma.size()==0)plumed_merror("you should define --sigma vector when using histogram");
261 : lowI_=uppI_="-1."; // Interval is not use for histograms
262 : }
263 :
264 9 : if(dohisto && dohills) {
265 0 : plumed_massert(vcvs==hcvs,"variables for histogram and bias should have the same labels");
266 0 : plumed_massert(hpmin==vpmin,"variables for histogram and bias should have the same min for periodicity");
267 0 : plumed_massert(hpmax==vpmax,"variables for histogram and bias should have the same max for periodicity");
268 : }
269 :
270 : // now put into a neutral vector
271 :
272 : std::vector< std::vector<std::string> > cvs;
273 : std::vector<std::string> pmin;
274 : std::vector<std::string> pmax;
275 :
276 9 : if(dohills) {
277 8 : cvs=vcvs;
278 8 : pmin=vpmin;
279 8 : pmax=vpmax;
280 : }
281 9 : if(dohisto) {
282 1 : cvs=hcvs;
283 1 : pmin=hpmin;
284 1 : pmax=hpmax;
285 : }
286 :
287 :
288 : // setup grids
289 : unsigned grid_check=0;
290 9 : std::vector<std::string> gmin(cvs.size());
291 18 : if(parseVector("--min",gmin)) {
292 4 : if(gmin.size()!=cvs.size() && gmin.size()!=0) plumed_merror("not enough values for --min");
293 : grid_check++;
294 : }
295 9 : std::vector<std::string> gmax(cvs.size() );
296 18 : if(parseVector("--max",gmax)) {
297 4 : if(gmax.size()!=cvs.size() && gmax.size()!=0) plumed_merror("not enough values for --max");
298 4 : grid_check++;
299 : }
300 9 : std::vector<std::string> gbin(cvs.size());
301 : bool grid_has_bin; grid_has_bin=false;
302 18 : if(parseVector("--bin",gbin)) {
303 6 : if(gbin.size()!=cvs.size() && gbin.size()!=0) plumed_merror("not enough values for --bin");
304 : grid_has_bin=true;
305 : }
306 9 : std::vector<std::string> gspacing(cvs.size());
307 : bool grid_has_spacing; grid_has_spacing=false;
308 18 : if(parseVector("--spacing",gspacing)) {
309 0 : if(gspacing.size()!=cvs.size() && gspacing.size()!=0) plumed_merror("not enough values for --spacing");
310 : grid_has_spacing=true;
311 : }
312 : // allowed: no grids only bin
313 : // not allowed: partial grid definition
314 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");
315 :
316 :
317 :
318 9 : PlumedMain plumed;
319 : std::string ss;
320 9 : unsigned nn=1;
321 : ss="setNatoms";
322 9 : plumed.cmd(ss,&nn);
323 9 : if(Communicator::initialized()) plumed.cmd("setMPIComm",&pc.Get_comm());
324 18 : plumed.cmd("init",&nn);
325 9 : std::vector <bool> isdone(cvs.size(),false);
326 26 : for(unsigned i=0; i<cvs.size(); i++) {
327 17 : if(!isdone[i]) {
328 : isdone[i]=true;
329 : std::vector<std::string> actioninput;
330 : std::vector <unsigned> inds;
331 17 : actioninput.push_back("FAKE");
332 34 : actioninput.push_back("ATOMS=1");
333 34 : actioninput.push_back("LABEL="+cvs[i][0]);
334 : std::vector<std::string> comps, periods;
335 17 : if(cvs[i].size()>1) {comps.push_back(cvs[i][1]); inds.push_back(i);}
336 17 : periods.push_back(pmin[i]); periods.push_back(pmax[i]);
337 25 : for(unsigned j=i+1; j<cvs.size(); j++) {
338 8 : if(cvs[i][0]==cvs[j][0] && !isdone[j]) {
339 0 : if(cvs[i].size()==1 || cvs[j].size()==1 )plumed_merror("you cannot have twice the same label and no components ");
340 0 : if(cvs[j].size()>1) {
341 0 : comps.push_back(cvs[j][1]);
342 0 : periods.push_back(pmin[j]); periods.push_back(pmax[j]);
343 0 : isdone[j]=true; inds.push_back(j);
344 : }
345 : }
346 :
347 : }
348 : // drain all the components
349 : std::string addme;
350 17 : if(comps.size()>0) {
351 : addme="COMPONENTS=";
352 1 : for(unsigned i=0; i<comps.size()-1; i++)addme+=comps[i]+",";
353 : addme+=comps.back();
354 1 : actioninput.push_back(addme);
355 : }
356 : // periodicity (always explicit here)
357 : addme="PERIODIC=";
358 34 : for(unsigned j=0; j<periods.size()-1; j++) {
359 34 : addme+=periods[j]+",";
360 : }
361 : addme+=periods.back();
362 17 : actioninput.push_back(addme);
363 18 : for(unsigned j=0; j<inds.size(); j++) {
364 1 : unsigned jj; jj=inds[j];
365 1 : if(grid_check==2) {
366 : double gm;
367 : double pm;
368 1 : if(pmin[jj]!="none") {
369 1 : Tools::convert(gmin[jj],gm);
370 1 : Tools::convert(pmin[jj],pm);
371 1 : if( gm<pm ) {
372 0 : plumed_merror("Periodicity issue : GRID_MIN value ( "+gmin[jj]+" ) is less than periodicity in HILLS file in "+cvs[jj][0]+ " ( "+pmin[jj]+" ) ");
373 : }
374 : }
375 1 : if(pmax[jj]!="none") {
376 1 : Tools::convert(gmax[jj],gm);
377 1 : Tools::convert(pmax[jj],pm);
378 1 : if( gm>pm ) {
379 0 : plumed_merror("Periodicity issue : GRID_MAX value ( "+gmax[jj]+" ) is more than periodicity in HILLS file in "+cvs[jj][0]+ " ( "+pmax[jj]+" ) ");
380 : }
381 : }
382 : }
383 : }
384 :
385 : // for(unsigned i=0;i< actioninput.size();i++){
386 : // cerr<<"AA "<<actioninput[i]<<endl;
387 : // }
388 17 : plumed.readInputWords(actioninput);
389 34 : }
390 :
391 : }
392 9 : unsigned ncv=cvs.size();
393 : std::vector<std::string> actioninput;
394 : std::vector<std::string> idw;
395 : // check if the variables to be used are correct
396 18 : if(parseVector("--idw",idw)) {
397 4 : for(unsigned i=0; i<idw.size(); i++) {
398 : bool found=false;
399 6 : for(unsigned j=0; j<cvs.size(); j++) {
400 4 : if(cvs[j].size()>1) {
401 0 : if(idw[i]==cvs[j][0]+"."+cvs[j][1])found=true;
402 : } else {
403 4 : if(idw[i]==cvs[j][0])found=true;
404 : }
405 : }
406 2 : if(!found)plumed_merror("variable "+idw[i]+" is not found in the bunch of cvs: revise your --idw option" );
407 : }
408 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 ");
409 : // in this case you need a beta factor!
410 : }
411 :
412 9 : std::string kt; kt=std::string("1.");// assign an arbitrary value just in case that idw.size()==cvs.size()
413 9 : if ( dohisto || idw.size()!=0 ) {
414 6 : plumed_massert(parse("--kt",kt),"if you make a dimensionality reduction (--idw) or a histogram (--histo) then you need to define --kt ");
415 : }
416 :
417 : std::string addme;
418 :
419 9 : actioninput.push_back("FUNCSUMHILLS");
420 18 : actioninput.push_back("ISCLTOOL");
421 :
422 : // set names
423 : std::string outfile;
424 18 : if(parse("--outfile",outfile)) {
425 0 : actioninput.push_back("OUTHILLS="+outfile);
426 : }
427 : std::string outhisto;
428 18 : if(parse("--outhisto",outhisto)) {
429 2 : actioninput.push_back("OUTHISTO="+outhisto);
430 : }
431 :
432 :
433 : addme="ARG=";
434 17 : for(unsigned i=0; i<(ncv-1); i++) {
435 8 : if(cvs[i].size()==1) {
436 16 : addme+=std::string(cvs[i][0])+",";
437 : } else {
438 0 : addme+=std::string(cvs[i][0])+"."+std::string(cvs[i][1])+",";
439 : }
440 : }
441 9 : if(cvs[ncv-1].size()==1) {
442 16 : addme+=std::string(cvs[ncv-1][0]);
443 : } else {
444 2 : addme+=std::string(cvs[ncv-1][0])+"."+std::string(cvs[ncv-1][1]);
445 : }
446 9 : actioninput.push_back(addme);
447 : //for(unsigned i=0;i< actioninput.size();i++){
448 : // cerr<<"AA "<<actioninput[i]<<endl;
449 : //}
450 9 : if(dohills) {
451 9 : addme="HILLSFILES="; for(unsigned i=0; i<hillsFiles.size()-1; i++)addme+=hillsFiles[i]+","; addme+=hillsFiles[hillsFiles.size()-1];
452 8 : actioninput.push_back(addme);
453 : // set the grid
454 : }
455 9 : if(grid_check==2) {
456 7 : addme="GRID_MAX="; for(unsigned i=0; i<(ncv-1); i++)addme+=gmax[i]+","; addme+=gmax[ncv-1];
457 4 : actioninput.push_back(addme);
458 7 : addme="GRID_MIN="; for(unsigned i=0; i<(ncv-1); i++)addme+=gmin[i]+","; addme+=gmin[ncv-1];
459 4 : actioninput.push_back(addme);
460 : }
461 9 : if(grid_has_bin) {
462 11 : addme="GRID_BIN="; for(unsigned i=0; i<(ncv-1); i++)addme+=gbin[i]+","; addme+=gbin[ncv-1];
463 6 : actioninput.push_back(addme);
464 : }
465 9 : if(grid_has_spacing) {
466 0 : addme="GRID_SPACING="; for(unsigned i=0; i<(ncv-1); i++)addme+=gspacing[i]+","; addme+=gspacing[ncv-1];
467 0 : actioninput.push_back(addme);
468 : }
469 : std::string stride; stride="";
470 18 : if(parse("--stride",stride)) {
471 1 : actioninput.push_back("INITSTRIDE="+stride);
472 : bool nohistory;
473 1 : parseFlag("--nohistory",nohistory);
474 1 : if(nohistory) {
475 0 : actioninput.push_back("NOHISTORY");
476 : }
477 : }
478 : bool mintozero;
479 9 : parseFlag("--mintozero",mintozero);
480 9 : if(mintozero) {
481 0 : actioninput.push_back("MINTOZERO");
482 : }
483 9 : if(idw.size()!=0) {
484 : addme="PROJ=";
485 2 : for(unsigned i=0; i<idw.size()-1; i++) {addme+=idw[i]+",";}
486 : addme+=idw.back();
487 2 : actioninput.push_back(addme);
488 : }
489 :
490 9 : if(dohisto) {
491 1 : if(idw.size()==0) {
492 1 : if(sigma.size()!=hcvs.size()) plumed_merror("you should define as many --sigma vector as the number of collective variable used for the histogram ");
493 : } else {
494 0 : if(idw.size()!=sigma.size()) plumed_merror("you should define as many --sigma vector as the number of collective variable used for the histogram ");
495 : }
496 : }
497 :
498 9 : if(idw.size()!=0 || dohisto) {
499 6 : actioninput.push_back("KT="+kt);
500 : }
501 9 : if(dohisto) {
502 1 : addme="HISTOFILES="; for(unsigned i=0; i<histoFiles.size()-1; i++) {addme+=histoFiles[i]+",";} addme+=histoFiles[histoFiles.size()-1];
503 1 : actioninput.push_back(addme);
504 :
505 : addme="HISTOSIGMA=";
506 2 : for(unsigned i=0; i<sigma.size()-1; i++) {addme+=sigma[i]+",";}
507 : addme+=sigma.back();
508 1 : actioninput.push_back(addme);
509 : }
510 :
511 : bool negbias;
512 9 : parseFlag("--negbias",negbias);
513 9 : if(negbias) {
514 2 : actioninput.push_back("NEGBIAS");
515 : }
516 :
517 9 : if(lowI_!=uppI_) {
518 0 : addme="INTERVAL="; addme+=lowI_+","; addme+=uppI_;
519 0 : actioninput.push_back(addme);
520 : }
521 :
522 : std::string fmt; fmt="";
523 18 : parse("--fmt",fmt);
524 18 : if(fmt!="")actioninput.push_back("FMT="+fmt);
525 :
526 :
527 : // for(unsigned i=0;i< actioninput.size();i++){
528 : // cerr<<"AA "<<actioninput[i]<<endl;
529 : // }
530 9 : plumed.readInputWords(actioninput);
531 : // if not a grid, then set it up automatically
532 9 : return 0;
533 27 : }
534 :
535 9 : bool CLToolSumHills::findCvsAndPeriodic(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_) {
536 9 : IFile ifile;
537 9 : ifile.allowIgnoredFields();
538 : std::vector<std::string> fields;
539 9 : if(ifile.FileExist(filename)) {
540 9 : cvs.clear(); pmin.clear(); pmax.clear();
541 9 : ifile.open(filename);
542 9 : ifile.scanFieldList(fields);
543 : bool before_sigma=true;
544 121 : for(unsigned i=0; i<fields.size(); i++) {
545 : size_t pos = 0;
546 : size_t founds,foundm,foundp;
547 : //found=(fields[i].find("sigma_", pos) || fields[i].find("min_", pos) || fields[i].find("max_", pos) ) ;
548 112 : founds=fields[i].find("sigma_", pos) ;
549 112 : foundm=fields[i].find("min_", pos) ;
550 112 : foundp=fields[i].find("max_", pos) ;
551 112 : if (founds!=std::string::npos || foundm!=std::string::npos || foundp!=std::string::npos )before_sigma=false;
552 : // cvs are after time and before sigmas
553 : size_t found;
554 112 : found=fields[i].find("time", pos);
555 112 : if( found==std::string::npos && before_sigma) {
556 : // separate the components
557 : size_t dot=fields[i].find_first_of('.');
558 : std::vector<std::string> ss;
559 : // this loop does not take into account repetitions
560 17 : if(dot!=std::string::npos) {
561 1 : std::string a=fields[i].substr(0,dot);
562 1 : std::string name=fields[i].substr(dot+1);
563 1 : ss.push_back(a);
564 1 : ss.push_back(name);
565 1 : cvs.push_back(ss);
566 : } else {
567 : std::vector<std::string> ss;
568 16 : ss.push_back(fields[i]);
569 16 : cvs.push_back(ss);
570 16 : }
571 : //std::cerr<<"found variable number "<<cvs.size()<<" : "<<cvs.back()[0]<<std::endl;
572 : //if((cvs.back()).size()!=1){
573 : // std::cerr<<"component "<<(cvs.back()).back()<<std::endl;
574 : //}
575 : // get periodicity
576 17 : pmin.push_back("none");
577 34 : pmax.push_back("none");
578 18 : std::string mm; if((cvs.back()).size()>1) {mm=cvs.back()[0]+"."+cvs.back()[1];} else {mm=cvs.back()[0];}
579 34 : if(ifile.FieldExist("min_"+mm)) {
580 : std::string val;
581 28 : ifile.scanField("min_"+mm,val);
582 : pmin[pmin.size()-1]=val;
583 : // std::cerr<<"found min : "<<pmin.back()<<std::endl;
584 : }
585 : //std::cerr<<"found min : "<<pmin.back()<<std::endl;
586 34 : if(ifile.FieldExist("max_"+mm)) {
587 : std::string val;
588 28 : ifile.scanField("max_"+mm,val);
589 : pmax[pmax.size()-1]=val;
590 : // std::cerr<<"found max : "<<pmax.back()<<std::endl;
591 : }
592 : //std::cerr<<"found max : "<<pmax.back()<<std::endl;
593 17 : }
594 : }
595 : // is multivariate ???
596 : std::string sss;
597 9 : multivariate=false;
598 18 : if(ifile.FieldExist("multivariate")) {
599 : ;
600 18 : ifile.scanField("multivariate",sss);
601 9 : if(sss=="true") { multivariate=true;}
602 3 : else if(sss=="false") { multivariate=false;}
603 : }
604 : // do interval?
605 18 : if(ifile.FieldExist("lower_int")) {
606 0 : ifile.scanField("lower_int",lowI_);
607 0 : ifile.scanField("upper_int",uppI_);
608 : } else {
609 : lowI_="-1.";
610 : uppI_="-1.";
611 : }
612 9 : ifile.scanField();
613 : return true;
614 : } else {
615 : return false;
616 : }
617 9 : }
618 :
619 :
620 10432 : PLUMED_REGISTER_CLTOOL(CLToolSumHills,"sum_hills")
621 :
622 :
623 :
624 : }
625 : }
|