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