From b55011f99b9bde59705489e822fc12fb0e0de1a9 Mon Sep 17 00:00:00 2001
From: Carlo Camilloni <carlo.camilloni@gmail.com>
Date: Tue, 3 Jun 2014 00:51:34 +0100
Subject: [PATCH] SUM_HILLS: changes to --histo 1) default output file is
 histo.dat 2) --idw with --histo now select a subset of fields and ignore all
 the others the only missing feature at the moment is that it still do a free
 energy instead of a probability density because I have to add the calculation
 of the normalisation.

---
 src/cltools/SumHills.cpp      | 23 ++++++---
 src/function/FuncSumHills.cpp | 91 +++++++++++++++++++++++++----------
 2 files changed, 82 insertions(+), 32 deletions(-)

diff --git a/src/cltools/SumHills.cpp b/src/cltools/SumHills.cpp
index b64eca23c..ec7625786 100644
--- a/src/cltools/SumHills.cpp
+++ b/src/cltools/SumHills.cpp
@@ -119,7 +119,7 @@ plumed sum_hills --histo PATHTOMYCOLVARORHILLSFILE  --sigma 0.2,0.2 --kt 0.6
 in this case you need a --kt to do the reweighting and then you
 need also some width (with the --sigma keyword) for the histogram calculation (actually will be done with 
 gaussians, so it will be a continuous histogram)
-Here the default output will be correction.dat.
+Here the default output will be histo.dat.
 Note that also here you can have multiple input files separated by a comma.
 
 Additionally, if you want to do histogram and hills from the same file you can do as this   
@@ -169,19 +169,19 @@ plumed sum_hills --hills PATHTOMYHILLSFILE  --outfile myfes_ --stride 100
 
 will produce myfes_0.dat,  myfes_1.dat, myfes_2.dat etc.
 
-The same is true for the output coming from histogram corrections 
+The same is true for the output coming from histogram  
 \verbatim
-plumed sum_hills --histo HILLS --kt 2.5 --sigma 0.01 --outhisto mycorrection.dat
+plumed sum_hills --histo HILLS --kt 2.5 --sigma 0.01 --outhisto myhisto.dat
 \endverbatim
 
-is producing a file mycorrection.dat
+is producing a file myhisto.dat
 while, when using stride, this is the suffix 
 
 \verbatim
-plumed sum_hills --histo HILLS --kt 2.5 --sigma 0.01 --outhisto mycorrection_ --stride 100 
+plumed sum_hills --histo HILLS --kt 2.5 --sigma 0.01 --outhisto myhisto_ --stride 100 
 \endverbatim
 
-that gives  mycorrection_0.dat,  mycorrection_1.dat,  mycorrection_3.dat etc..
+that gives  myhisto_0.dat,  myhisto_1.dat,  myhisto_3.dat etc..
 
 */
 //+ENDPLUMEDOC
@@ -258,7 +258,7 @@ int CLToolSumHills::main(FILE* in,FILE*out,Communicator& pc){
        findCvsAndPeriodic(histoFiles[0], hcvs, hpmin, hpmax, hmultivariate);
        // here need also the vector of sigmas
        parseVector("--sigma",sigma);
-       if(sigma.size()!=hcvs.size())plumed_merror("you should define --sigma vector when using histogram");
+       if(sigma.size()==0)plumed_merror("you should define --sigma vector when using histogram");
   }
 
   if(dohisto && dohills){
@@ -486,6 +486,15 @@ int CLToolSumHills::main(FILE* in,FILE*out,Communicator& pc){
      addme+=idw.back();  
      actioninput.push_back(addme);
   }
+
+  if(dohisto) {
+    if(idw.size()==0) {
+      if(sigma.size()!=hcvs.size()) plumed_merror("you should define as many --sigma vector as the number of collective variable used for the histogram ");
+    } else {
+      if(idw.size()!=sigma.size()) plumed_merror("you should define as many --sigma vector as the number of collective variable used for the histogram ");
+    }
+  }
+
   if(idw.size()!=0 || dohisto){
      actioninput.push_back("KT="+kt);
   } 
diff --git a/src/function/FuncSumHills.cpp b/src/function/FuncSumHills.cpp
index 724bdffb4..44d09f41b 100644
--- a/src/function/FuncSumHills.cpp
+++ b/src/function/FuncSumHills.cpp
@@ -288,23 +288,46 @@ fmt("%14.9f")
   vector<double> histoSigma;
   if(integratehisto){
   	parseVector("HISTOSIGMA",histoSigma);
-	plumed_massert(histoSigma.size()==getNumberOfArguments()," The number of sigmas must be the same of the number of arguments ");
         for(unsigned i=0;i<histoSigma.size();i++) log<<"  histosigma  : "<<histoSigma[i]<<"\n";
   }
 
+  // needs a projection? 
+  proj.clear();
+  parseVector("PROJ",proj);
+  if(integratehills) {
+    plumed_massert(proj.size()<getNumberOfArguments()," The number of projection must be less than the full list of arguments ");
+  }
+  if(integratehisto) {
+    plumed_massert(proj.size()<=getNumberOfArguments()," The number of projection must be less or equal to the full list of arguments ");
+  }
+  if(integratehisto&&proj.size()==0) {
+    for(unsigned i=0;i<getNumberOfArguments();i++) proj.push_back(getPntrToArgument(i)->getName()); 
+  }
+
   // add some automatic hills width: not in case stride is defined  
   // since when you start from zero the automatic size will be zero!
   if(gmin.size()==0 || gmax.size()==0){
 	log<<"   \n"; 
 	log<<"  No boundaries defined: need to do a prescreening of hills \n"; 
-        std::vector<Value*> tmpvalues; 
-        for(unsigned i=0;i<getNumberOfArguments();i++)tmpvalues.push_back( getPntrToArgument(i) );
+        std::vector<Value*> tmphillsvalues, tmphistovalues;
+        if(integratehills) { 
+          for(unsigned i=0;i<getNumberOfArguments();i++)tmphillsvalues.push_back( getPntrToArgument(i) );
+        }
+        if(integratehisto) {
+          for(unsigned i=0;i<getNumberOfArguments();i++) {
+            std::string ss = getPntrToArgument(i)->getName(); 
+            for(unsigned j=0;j<proj.size();j++) {
+              if(proj[i]==ss) tmphistovalues.push_back( getPntrToArgument(i) );
+            }
+          } 
+        }
+
         if(integratehills) {
         	FilesHandler *hillsHandler;
         	hillsHandler=new FilesHandler(hillsFiles,parallelread,*this, log);
 		vector<double> vmin,vmax;
         	vector<unsigned> vbin;  
-        	hillsHandler->getMinMaxBin(tmpvalues,comm,vmin,vmax,vbin);
+        	hillsHandler->getMinMaxBin(tmphillsvalues,comm,vmin,vmax,vbin);
 		log<<"  found boundaries from hillsfile: \n";
 		gmin.resize(vmin.size());
 		gmax.resize(vmax.size());
@@ -325,7 +348,7 @@ fmt("%14.9f")
 	        histoHandler=new FilesHandler(histoFiles,parallelread,*this, log);
 		vector<double> vmin,vmax;
         	vector<unsigned> vbin;  
-        	histoHandler->getMinMaxBin(tmpvalues,comm,vmin,vmax,vbin,histoSigma);
+        	histoHandler->getMinMaxBin(tmphistovalues,comm,vmin,vmax,vbin,histoSigma);
 		log<<"  found boundaries from histofile: \n";
 		gmin.resize(vmin.size());
 		gmax.resize(vmax.size());
@@ -334,24 +357,21 @@ fmt("%14.9f")
                 }else{
 			log<<"  found nbins in input, this overrides the automatic choice \n"; 
 		}
-		for(unsigned i=0;i<getNumberOfArguments();i++){
+		for(unsigned i=0;i<proj.size();i++){
 		 	Tools::convert(vmin[i],gmin[i]);
 		 	Tools::convert(vmax[i],gmax[i]);
-			log<<"  variable "<< getPntrToArgument(i)->getName()<<" min: "<<gmin[i]<<" max: "<<gmax[i]<<" nbin: "<<gbin[i]<<"\n";
+			log<<"  variable "<< proj[i] <<" min: "<<gmin[i]<<" max: "<<gmax[i]<<" nbin: "<<gbin[i]<<"\n";
 		}
         }
 	log<<"  done!\n"; 
 	log<<"   \n"; 
   }
 
-  // needs a projection? 
-  proj.clear();
-  parseVector("PROJ",proj);
-  plumed_massert(proj.size()<getNumberOfArguments()," The number of projection must be less than the full list of arguments ");
 
   if( proj.size() != 0 || integratehisto==true  ) {
     parse("KT",beta);
     for(unsigned i=0;i<proj.size();i++) log<<"  projection "<<i<<" : "<<proj[i]<<"\n";
+    // this should be only for projection or free energy from histograms
     plumed_massert(beta>0.,"if you make a projection or a histogram correction then you need KT flag!"); 
     beta=1./beta; 
     log<<"  beta is "<<beta<<"\n"; 
@@ -366,8 +386,8 @@ fmt("%14.9f")
   parse("INITSTRIDE",initstride);
   // output suffix or names
   if(initstride<0){ log<<"  Doing only one integration: no stride \n";
-  	 outhills="fes.dat";outhisto="correction.dat";}
-  else{outhills="fes_";outhisto="correction_";
+  	 outhills="fes.dat";outhisto="histo.dat";}
+  else{outhills="fes_";outhisto="histo_";
 	log<<"  Doing integration slices every "<<initstride<<" kernels\n";
         parseFlag("NOHISTORY",nohistory); 
         if(nohistory)log<<"  nohistory: each stride block has no memory of the previous block\n";
@@ -382,16 +402,27 @@ fmt("%14.9f")
   // create a bias representation for this
   if(iscltool){
 
-     std::vector<Value*> tmpvalues; 
-    for(unsigned i=0;i<getNumberOfArguments();i++){
+    std::vector<Value*> tmphillsvalues, tmphistovalues; 
+    if(integratehills) {
+      for(unsigned i=0;i<getNumberOfArguments();i++){
         // allocate a new value from the old one: no deriv here
-	tmpvalues.push_back( getPntrToArgument(i) );
+        // if we are summing hills then all the arguments are needed
+	tmphillsvalues.push_back( getPntrToArgument(i) );
+      }
+    }
+    if(integratehisto) {
+      for(unsigned i=0;i<getNumberOfArguments();i++) {
+        std::string ss = getPntrToArgument(i)->getName(); 
+        for(unsigned j=0;j<proj.size();j++) {
+          if(proj[i]==ss) tmphistovalues.push_back( getPntrToArgument(i) );
+        }
+      } 
     }
 
     // check if the files exists 
     if(integratehills){
          checkFilesAreExisting(hillsFiles); 
-         biasrep=new BiasRepresentation(tmpvalues,comm, gmin, gmax, gbin);
+         biasrep=new BiasRepresentation(tmphillsvalues,comm, gmin, gmax, gbin);
 	 if(negativebias){
 		biasrep->setRescaledToBias(true);
 	        log<<"  required the -bias instead of the free energy \n";
@@ -402,17 +433,19 @@ fmt("%14.9f")
 
     parse("OUTHILLS",outhills);
     parse("OUTHISTO",outhisto);
-    if(integratehills)log<<"  output file for fes/bias   is :  "<<outhills<<"\n";   
-    if(integratehisto)log<<"  output file for correction is :  "<<outhisto<<"\n";   
+    if(integratehills)log<<"  output file for fes/bias  is :  "<<outhills<<"\n";   
+    if(integratehisto)log<<"  output file for histogram is :  "<<outhisto<<"\n";   
     checkRead();
 
     log<<"\n";
     log<<"  Now calculating...\n";
     log<<"\n";
 
+    // here it defines the column to be histogrammed, tmpvalues should be only
+    // the list of the collective variable one want to consider
     if(integratehisto){
          checkFilesAreExisting(histoFiles); 
-         historep=new BiasRepresentation(tmpvalues,comm,gmin,gmax,gbin,histoSigma);
+         historep=new BiasRepresentation(tmphistovalues,comm,gmin,gmax,gbin,histoSigma);
     }
 
     // decide how to source hills ( serial/parallel )
@@ -465,12 +498,13 @@ fmt("%14.9f")
                         if(!ibias)integratehills=false;// once you get to the final bunch just give up 
 
 		}
+                // this should be removed
 		if(integratehisto){
 
     	      		log<<"  Histo: Projecting on subgrid... \n";
-                        ProbWeight *Pw=new ProbWeight(beta);
+                        //ProbWeight *Pw=new ProbWeight(beta);
              		Grid histoGrid=*(historep->getGridPtr());
-   	      		Grid smallGrid=histoGrid.project(proj,Pw);
+   	      		//Grid smallGrid=histoGrid.project(proj,Pw);
 
               		OFile gridfile; gridfile.link(*this);
 	      		std::ostringstream ostr;ostr<<nfiles;
@@ -479,8 +513,13 @@ fmt("%14.9f")
               		log<<"  Histo: Writing subgrid on file "<<myout<<" \n";
               		gridfile.open(myout);	
          
-        		smallGrid.setOutputFmt(fmt); 
-   	      		smallGrid.writeToFile(gridfile);
+        		//smallGrid.setOutputFmt(fmt); 
+   	      		//smallGrid.writeToFile(gridfile);
+                        histoGrid.applyFunctionAllValuesAndDerivatives(&mylog,&mylogder);
+                        histoGrid.scaleAllValuesAndDerivatives(-1./beta);	
+                        if(minTOzero) histoGrid.setMinToZero();	
+        		histoGrid.setOutputFmt(fmt); 
+   	      		histoGrid.writeToFile(gridfile);
               		gridfile.close();
 
                         if(!ihisto)integratehisto=false;// once you get to the final bunch just give up 
@@ -510,6 +549,7 @@ fmt("%14.9f")
 		if(integratehisto){
 
 	                Grid histoGrid=*(historep->getGridPtr());
+                        // do this if you want a free energy from a grid, otherwise do not
                         histoGrid.applyFunctionAllValuesAndDerivatives(&mylog,&mylogder);
                         histoGrid.scaleAllValuesAndDerivatives(-1./beta);	
 
@@ -520,12 +560,13 @@ fmt("%14.9f")
 	                log<<"  Writing full grid on file "<<myout<<" \n";
 	                gridfile.open(myout);	
 
+                        // also this is usefull only for free energy
                         if(minTOzero) histoGrid.setMinToZero();	
         		histoGrid.setOutputFmt(fmt); 
 	                histoGrid.writeToFile(gridfile);
 	                gridfile.close();
 
-                        if(!ihisto)integratehisto=false;// once you get to the final bunch just give up 
+                        if(!ihisto)integratehisto=false; // once you get to the final bunch just give up 
                 } 
 	} 	
         if ( !ibias && !ihisto) break; //when both are over then just quit 
-- 
GitLab