LCOV - code coverage report
Current view: top level - cltools - SumHills.cpp (source / functions) Hit Total Coverage
Test: plumed test coverage Lines: 208 232 89.7 %
Date: 2020-11-18 11:20:57 Functions: 10 12 83.3 %

          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 : }

Generated by: LCOV version 1.13