LCOV - code coverage report
Current view: top level - cltools - SumHills.cpp (source / functions) Hit Total Coverage
Test: plumed test coverage Lines: 196 216 90.7 %
Date: 2024-10-18 14:00:25 Functions: 8 8 100.0 %

          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        5316 : void CLToolSumHills::registerKeywords( Keywords& keys ) {
     199        5316 :   CLTool::registerKeywords( keys );
     200       10632 :   keys.addFlag("--help-debug",false,"print special options that can be used to create regtests");
     201       10632 :   keys.add("optional","--hills","specify the name of the hills file");
     202       10632 :   keys.add("optional","--histo","specify the name of the file for histogram a colvar/hills file is good");
     203       10632 :   keys.add("optional","--stride","specify the stride for integrating hills file (default 0=never)");
     204       10632 :   keys.add("optional","--min","the lower bounds for the grid");
     205       10632 :   keys.add("optional","--max","the upper bounds for the grid");
     206       10632 :   keys.add("optional","--bin","the number of bins for the grid");
     207       10632 :   keys.add("optional","--spacing","grid spacing, alternative to the number of bins");
     208       10632 :   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       10632 :   keys.add("optional","--outfile","specify the output file for sumhills");
     210       10632 :   keys.add("optional","--outhisto","specify the output file for the histogram");
     211       10632 :   keys.add("optional","--kt","specify temperature in energy units for integrating out variables");
     212       10632 :   keys.add("optional","--sigma"," a vector that specify the sigma for binning (only needed when doing histogram ");
     213       10632 :   keys.addFlag("--negbias",false," print the negative bias instead of the free energy (only needed with well tempered runs and flexible hills) ");
     214       10632 :   keys.addFlag("--nohistory",false," to be used with --stride:  it splits the bias/histogram in pieces without previous history ");
     215       10632 :   keys.addFlag("--mintozero",false," it translate all the minimum value in bias/histogram to zero (useful to compare results) ");
     216       10632 :   keys.add("optional","--fmt","specify the output format");
     217        5316 : }
     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           8 :     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           5 :     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           1 :     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           9 :   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,false);
     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          10 :     addme="GRID_BIN="; for(unsigned i=0; i<(ncv-1); i++)addme+=gbin[i]+","; addme+=gbin[ncv-1];
     463           5 :     actioninput.push_back(addme);
     464             :   }
     465           9 :   if(grid_has_spacing) {
     466           1 :     addme="GRID_SPACING="; for(unsigned i=0; i<(ncv-1); i++)addme+=gspacing[i]+","; addme+=gspacing[ncv-1];
     467           1 :     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,false);
     531             :   // if not a grid, then set it up automatically
     532           9 :   return 0;
     533          27 : }
     534             : 
     535           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_) {
     536           9 :   IFile ifile;
     537           9 :   ifile.allowIgnoredFields();
     538             :   std::vector<std::string> fields;
     539           9 :   if(ifile.FileExist(filename)) {
     540             :     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       15961 : PLUMED_REGISTER_CLTOOL(CLToolSumHills,"sum_hills")
     621             : 
     622             : 
     623             : 
     624             : }
     625             : }

Generated by: LCOV version 1.16