NAMD
eabf1D.C
Go to the documentation of this file.
1 //
2 // The extended adaptive biasing force method has been contributed to NAMD by the following authors:
3 //
4 // Haohao Fu and Christophe Chipot
5 // Laboratoire International Associ\'e
6 // Centre National de la Recherche Scientifique et University of Illinois at Urbana--Champaign
7 // Unit\'e Mixte de Recherche No. 7565, Universit\'e de Lorraine
8 // B.P. 70239, 54506 Vand\oe uvre-lès-Nancy cedex, France
9 //
10 // Copyright 2016, Centre National de la Recherche Scientifique
11 //
12 
13 #ifndef EABF1D_CPP
14 #define EABF1D_CPP
15 
16 #include <cmath>
17 #include <fstream>
18 #include <string>
19 #include <memory>
20 #include <iomanip>
21 #include "fstream_namd.h"
22 
23 #include "eabf1D.h"
24 #include "eabffunc.h"
25 
26 
27 // constructor
28 eABF1D::eABF1D(const double _lowerboundary, const double _upperboundary, const double _width,
29  const double _krestr,
30  const std::string& _outputfile,
31  const int _outputfreq,
32  const bool _restart, const std::string& _inputfile,
33  const bool _outputgrad, const int _gradfreq, const double _temperature) :
34  eABF(_outputfile, _outputfreq, _restart, _inputfile, _outputgrad, _gradfreq, _temperature)
35 {
36  lowerboundary.push_back(_lowerboundary);
37  upperboundary.push_back(_upperboundary);
38  width.push_back(_width);
39  krestr.push_back(_krestr);
40  this->initialize();
41  if (restart == true)
42  this->readfile();
43 }
44 
46 {
47  // calculate the number of bins in the calculation
48  // the bins is equal to "real bins + 20" to prevent boundary effect
49  min.push_back(eabffunc::doubletoint(lowerboundary[0] / width[0]) - 10);
50  max.push_back(eabffunc::doubletoint(upperboundary[0] / width[0]) + 10);
51  bins.push_back(max[0] - min[0]);
52 
53  // initialize the distribution of "countall"
54  for (int i = 0; i < bins[0]; i++)
55  {
56  countall.push_back(std::vector<int>(bins[0], 0));
57  }
58 
59  // initialize other variables
60  sumx = std::vector<double>(bins[0], 0);
61  sumx2 = std::vector<double>(bins[0], 0);
62  county = std::vector<int>(bins[0], 0);
63  line = 0;
64  return true;
65 }
66 
67 bool eABF1D::update(const std::string& colvarstring)
68 {
69  // this is the string obtained from colvar each step
70  // the format of this string is the same as those in colvar.traj file
71 
72  std::vector<std::string> data;
73  eabffunc::split(colvarstring, data); // split the string to a vector<string>
74 
75  int step;
76 
77  double abf_force; // the value of the two columns characterizing the value of CV and extended CV
78  double eabf_force;
79 
80  step = eabffunc::chartoint(data[0]); // read the variables fron the "colvarstring"
81  abf_force = eabffunc::chartodouble(data[col[0]]);
82  eabf_force = eabffunc::chartodouble(data[col[1]]);
83 
84 
85  // for dihedral RC, it is possible that abf_force = 179 and eabf_force = -179, should correct it
86  if(abf_force > 150 && eabf_force < -150)
87  eabf_force += 360;
88  else if(abf_force < -150 && eabf_force > 150)
89  eabf_force -= 360;
90 
91  // normalize the index of the value of CV and extended CV
92  int binx = int(floor(abf_force / width[0])) - min[0];
93  int biny = int(floor(eabf_force / width[0])) - min[0];
94 
95  // update the
96  if (binx < 0 || binx >= bins[0] || biny < 0 || biny >= bins[0])
97  return false;
98  else
99  {
100  countall[binx][biny]++;
101  // if this is the first time add "countall", then the line in outputfile will increase
102  if(countall[binx][biny]==1)
103  line++;
104  county[biny]++;
105  }
106 
107  sumx[biny] += abf_force;
108  sumx2[biny] += abf_force * abf_force;
109 
110  if (step%outputfreq == 0)
111  {
112  writefile();
113  }
114 
115  if(outputgrad==1&&(step%gradfreq)==0)
116  {
117  calpmf();
118  }
119 
120  return true;
121 }
122 
124 {
125  std::ifstream file(inputfile.c_str(), std::ios::in);
126 
127  // output file format: (also see writefile function)
128  // (number of lines) lowerboundary width (number of bins) krestr temperature
129  // (normalized CV) (normalized extended CV) numbers
130  // ...... "only non-zero value is recorded here"
131  // (normalized CV) sumx sumx2 county
132  // ......
133  int temp_line, temp_bins;
134  double temp_lowerboundary, temp_width;
135  file >> temp_line >> temp_lowerboundary >> temp_width >> temp_bins >> krestr[0] >> temperature;
136 
137  temp_bins = temp_bins + 20;
138 
139  int x = 0, y = 0, temp_countall;
140  for (int i = 0; i < temp_line; i++)
141  {
142  file >> x >> y;
143  file >> temp_countall;
144  //if (x > temp_bins - 10 || x < 10)
145  // continue;
146  ;
147  if (countall[convertscale(temp_lowerboundary, x)][convertscale(temp_lowerboundary, y)] == 0)
148  line++;
149  countall[convertscale(temp_lowerboundary,x)][convertscale(temp_lowerboundary,y)] += temp_countall;
150  }
151 
152  double temp_sumx, temp_sumx2;
153  int temp_county;
154  for (int i = 0; i < temp_bins; i++)
155  {
156  file >> x >> temp_sumx >> temp_sumx2 >> temp_county;
157  //if (x > temp_bins - 10 || x < 10)
158  // continue;
159  ;
160  sumx[convertscale(temp_lowerboundary, x)] += temp_sumx;
161  sumx2[convertscale(temp_lowerboundary, x)] += temp_sumx2;
162  county[convertscale(temp_lowerboundary, x)] += temp_county;
163  }
164 
165  file.close();
166  return true;
167 }
168 
169 bool eABF1D::writefile() const
170 {
171  ofstream_namd file(outputfile.c_str(),".old");
172  file<<std::setprecision(15);
173 
174  file << line << " " << lowerboundary[0] << " " << width[0] << " " << bins[0] - 20 << " " << krestr[0] << " " << temperature << std::endl;
175 
176  for (int i = 0; i < bins[0]; i++)
177  for (int j = 0; j < bins[0]; j++)
178  if (countall[i][j] != 0)
179  // the number of line should be "this->line", I guess :)
180  file << i << " " << j << " " << countall[i][j] << std::endl;
181 
182  for (int i = 0; i < bins[0]; i++)
183  file << i << " " << sumx[i] << " " << sumx2[i] << " " << county[i] << " " << std::endl;
184 
185  file.close();
186  return true;
187 }
188 
190 {
191  os << "# 1" << std::endl;
192  os << "# " << lowerboundary[0] << " " << width[0] << " " << bins[0] - 20 << " " << 0 << std::endl;
193  os << std::endl;
194  return true;
195 }
196 
197 bool eABF1D::calpmf() const
198 {
199  // implementation of YangWei's estimator
200  // mimic Jerome's script
201  int norm;
202  std::vector<double> x_av(bins[0]);
203  std::vector<double> sigma2(bins[0]);
204  for (int biny = 0; biny < bins[0]; biny++)
205  {
206  norm = county[biny] > 0 ? county[biny] : 1;
207  x_av[biny] = sumx[biny] / norm;
208  sigma2[biny] = sumx2[biny] / norm - x_av[biny] * x_av[biny];
209  }
210 
211  static std::string gridfilename = outputfile + ".grad";
212  static std::string histfilename = outputfile + ".hist.grad";
213  static std::string pmffilename = outputfile + ".pmf";
214  static std::string countfilename = outputfile + ".count";
215 
216  ofstream_namd ofile(gridfilename.c_str(),".old");
217  ofstream_namd ofile_hist(histfilename.c_str(), std::ios::app);
218  ofstream_namd ofile_pmf(pmffilename.c_str(),".old");
219  ofstream_namd ofile_count(countfilename.c_str(),".old");
220 
221  writehead(ofile);
222  writehead(ofile_hist);
223  writehead(ofile_count);
224 
225  ofile_pmf << lowerboundary[0] << " 0.0" << std::endl;
226 
227  double pmf = 0, pmf_x = 0;
228  double x, y, av, diff_av, grad;
229  for (int binx = 0; binx < bins[0]; binx++)
230  {
231  x = (binx + min[0] + 0.5) * width[0];
232  norm = 0;
233  av = 0;
234  diff_av = 0;
235 
236  for (int biny = 0; biny < bins[0]; biny++)
237  {
238  y = (biny + min[0] + 0.5) * width[0];
239  norm += countall[binx][biny];
240 
241  if (sigma2[biny] > 0.00001 || sigma2[biny] < -0.00001)
242  {
243  av += countall[binx][biny] * (x - x_av[biny]) / sigma2[biny];
244  }
245  else if (countall[binx][biny] > 1)
246  {
247  // TODO, print error
248  }
249  diff_av += countall[binx][biny] * (x - y);
250  }
251 
252  diff_av /= (norm > 0 ? norm : 1);
253  av = eabffunc::BOLTZMANN * temperature * av / (norm > 0 ? norm : 1);
254  grad = av - krestr[0] * diff_av;
255 
256 
257  if (x >= lowerboundary[0] && x < upperboundary[0])
258  {
259  ofile << x << " " << grad << std::endl;
260  ofile_hist << x << " " << grad << std::endl;
261  pmf += grad * width[0];
262  pmf_x = x + 0.5 * width[0];
263  ofile_pmf << pmf_x << " " << pmf << std::endl;
264  ofile_count << x << " " << norm << std::endl;
265  // TODO, rescale the pmf file to prevent negetive free energy
266  }
267  }
268  ofile.close();
269  ofile_pmf.close();
270  ofile_hist.close();
271  ofile_count.close();
272  return true;
273 }
274 
275 #endif // EABF
bool calpmf() const
Definition: eabf1D.C:197
std::string inputfile
Definition: eabf.h:76
std::vector< double > lowerboundary
Definition: eabf.h:61
std::vector< double > width
Definition: eabf.h:63
bool readfile()
Definition: eabf1D.C:123
std::vector< double > sumx
Definition: eabf1D.h:46
int convertscale(double lowerboundary, int window) const
Definition: eabf1D.h:60
bool writefile() const
Definition: eabf1D.C:169
bool writehead(ofstream_namd &) const
Definition: eabf1D.C:189
Definition: eabf.h:22
double temperature
Definition: eabf.h:85
int line
Definition: eabf.h:102
std::vector< double > krestr
Definition: eabf.h:93
int chartoint(const std::string &c)
Definition: eabffunc.C:48
int gradfreq
Definition: eabf.h:82
std::vector< double > sumx2
Definition: eabf1D.h:47
bool outputgrad
Definition: eabf.h:79
bool update(const std::string &)
Definition: eabf1D.C:67
double chartodouble(const std::string &c)
Definition: eabffunc.C:57
std::vector< int > county
Definition: eabf1D.h:48
std::vector< int > bins
Definition: eabf.h:91
void split(const std::string &s, std::vector< std::string > &ret)
Definition: eabffunc.C:37
gridSize y
std::vector< int > max
Definition: eabf.h:89
std::string outputfile
Definition: eabf.h:67
int outputfreq
Definition: eabf.h:70
gridSize x
eABF1D()
Definition: eabf1D.h:26
std::vector< int > min
Definition: eabf.h:90
std::vector< double > upperboundary
Definition: eabf.h:62
bool initialize()
Definition: eabf1D.C:45
bool restart
Definition: eabf.h:73
std::vector< int > col
Definition: eabf.h:104
int doubletoint(const double)
Definition: eabffunc.C:66
const double BOLTZMANN
Definition: eabffunc.h:23
std::vector< std::vector< int > > countall
Definition: eabf1D.h:45