1 /*
2 
3 Copyright (C) 2007 Lucas K. Wagner
4 
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9 
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 GNU General Public License for more details.
14 
15 You should have received a copy of the GNU General Public License along
16 with this program; if not, write to the Free Software Foundation, Inc.,
17 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 
19 */
20 #include "Qmc_std.h"
21 #include "Properties_block.h"
22 #include "qmc_io.h"
23 #include "Properties_average.h"
24 #include <algorithm>
25 #include <deque>
26 #include <cstring>
27 #include "Basis_function.h"
28 
29 using namespace Properties_types;
30 //----------------------------------------------------------------------
31 
getInit(vector<string> & words,vector<string> & labels,Array1<Array1<Average_generator * >> & avg_gen)32 void getInit(vector <string> & words, vector <string> & labels, Array1 < Array1 <Average_generator*> > & avg_gen) {
33   unsigned int pos=0;
34   pos=0;
35   vector<string> tmp;
36   vector <vector<string> > inittext;
37   while(readsection(words, pos, tmp, "INIT"))
38     inittext.push_back(tmp);
39   int ninit=inittext.size();
40   int nlabels=labels.size();
41   //cout << "ninit " << ninit << endl;
42   //if we have multiple init sections, we should check to see that they're
43   //all identical.  For now, let's take the first one.
44   avg_gen.Resize(nlabels);
45 
46   if(ninit==0) {
47     for(int i=0; i< nlabels; i++) avg_gen(i).Resize(0);
48     return;
49   }
50 
51   for(int i=0; i< nlabels; i++) {
52     int ini=0;
53     string inilabel;
54     readvalue(inittext[ini],pos=0,inilabel, "LABEL");
55     while(labels[i]!=inilabel) {
56       ini++;
57       readvalue(inittext[ini],pos=0,inilabel, "LABEL");
58       if(ini>= ninit)  {
59         cout << "Couldn't find init section for label " << labels[i]
60         << ".  AVERAGE { } sections will not be reported.\n";
61         break;
62       }
63     }
64     if(ini < ninit) {
65       vector <vector <string> > gen_secs;
66       pos=0;
67       while(readsection(inittext[ini],pos,tmp, "AVERAGE_GENERATOR"))
68         gen_secs.push_back(tmp);
69       avg_gen(i).Resize(gen_secs.size());
70       for(int j=0; j< gen_secs.size(); j++) {
71         allocate(gen_secs[j],avg_gen(i)(j));
72       }
73     }
74   }
75 
76 }
77 
78 //----------------------------------------------------------------------
79 
80 
getBlocks(vector<string> & words,vector<string> & labels,Array1<Array1<Properties_block>> & allblocks,Array1<Array1<Average_generator * >> & avg_gen)81 void getBlocks(vector <string> & words, vector <string> & labels,
82                Array1 < Array1 < Properties_block> > & allblocks,
83                Array1 < Array1 < Average_generator * > > & avg_gen) {
84 
85   vector < vector < string> > blocktext;
86   vector <string> tmp;
87   unsigned int pos=0;
88   while(readsection(words, pos, tmp, "BLOCK"))
89     blocktext.push_back(tmp);
90 
91   int nblock=blocktext.size();
92   //cout << blocktext.size() << " blocks \n";
93 
94   //vector <string> labels;
95   vector <int> belong_to;
96   vector <int> lab_nb; //number of blocks that belong to each label
97   string label;
98   for(int b=0; b< nblock; b++) {
99     if(!readvalue(blocktext[b], pos=0, label, "LABEL"))
100       error("didn't find label in the file");
101     vector<string>::iterator place=find(labels.begin(), labels.end(), label);
102     belong_to.push_back(place-labels.begin());
103     if(place==labels.end()) {
104       labels.push_back(label);
105       lab_nb.push_back(1);
106     }
107     else lab_nb[belong_to[b]]++;
108   }
109 
110   int nlabels=labels.size();
111 
112   allblocks.Resize(nlabels);
113   for(int i=0; i< nlabels; i++) {
114     allblocks(i).Resize(lab_nb[i]);
115   }
116 
117 
118   Array1 <int> nb_read(nlabels, 0);
119   for(int b=0; b< nblock; b++) {
120     int lab=belong_to[b];
121     int i=nb_read(lab);
122     nb_read(lab)++;
123     allblocks(lab)(i).restoreFromLog(blocktext[b]);
124   }
125 
126   getInit(words, labels, avg_gen);
127 
128 }
129 
130 
131 
132 //----------------------------------------------------------------------
133 
output_trace(vector<string> & labels,Array1<Array1<Properties_block>> & allblocks)134 void output_trace(vector <string> & labels,
135                   Array1 < Array1 <Properties_block> > & allblocks) {
136   int nlabels=labels.size();
137   for(int i=0; i< nlabels; i++) {
138     string nm=labels[i]+".trace";
139     ofstream tr(nm.c_str());
140     tr.precision(15);
141     for(int b=0; b< allblocks(i).GetDim(0); b++) {
142       tr << allblocks(i)(b).avg(total_energy,0) << endl;
143     }
144   }
145 }
146 
147 //----------------------------------------------------------------------
148 
output_trace_force(vector<string> & labels,Array1<Array1<Properties_block>> & allblocks)149 void output_trace_force(vector <string> & labels,
150                         Array1 < Array1 <Properties_block> > & allblocks) {
151   int nlabels=labels.size();
152 
153   for(int i=0; i< nlabels; i++) {
154     int naux=allblocks(i)(0).aux_energy.GetDim(0);
155     int n_cvg=allblocks(i)(0).aux_energy.GetDim(1);
156     for(int a=0; a< naux; a++) {
157       for(int n=0; n< n_cvg; n++) {
158         string nm=labels[i]+"f";
159         append_number(nm,a);
160         nm+="-"; append_number(nm,n);
161         nm+=".trace";
162         ofstream tr(nm.c_str());
163         tr.precision(15);
164         for(int b=0; b< allblocks(i).GetDim(0); b++) {
165           tr << (allblocks(i)(b).aux_energy(a,n)-allblocks(i)(b).avg(total_energy,0))
166           /allblocks(i)(b).aux_size(a) << endl;
167         }
168       }
169     }
170   }
171 
172 }
173 //----------------------------------------------------------------------
174 
reblock_average(Array1<Properties_block> & orig_block,int reblock,int equil,Properties_final_average & avg)175 int reblock_average(Array1 <Properties_block> & orig_block, int reblock, int equil,
176             Properties_final_average & avg) {
177   int nblock=orig_block.GetDim(0);
178   if(reblock > nblock)
179     return 0;
180 
181   int neffblock=0;
182   Array1<Properties_block> reblocks;
183 
184   reblocks.Resize(nblock/reblock);
185   int start=nblock%reblock;
186   int count=0;
187   for(int i=start; i< nblock; i+=reblock) {
188     int top=min(i+reblock, nblock);
189     reblocks(count++).reduceBlocks(orig_block, i, top);
190   }
191   neffblock=nblock/reblock;
192   avg.blockReduce(reblocks, 0, nblock/reblock, equil);
193 
194   return neffblock;
195 }
196 
197 //----------------------------------------------------------------------
198 
199 struct Gosling_options {
200   string label;
201   int tot_energy;
202   int json;
203   int trace;
204   int equil;
205   int show_autocorr;
206   int two_pt_forces;
207   int trace_force;
208   int reblock;
209   vector<string> filenames;
Gosling_optionsGosling_options210   Gosling_options() {
211     tot_energy=0;
212     json=0;
213     trace=0;
214     equil=1;
215     show_autocorr=0;
216     two_pt_forces=0;
217     trace_force=0;
218     reblock=1;
219   }
220 };
221 
222 //----------------------------------------------------------------------
223 
get_options(int argc,char ** argv,Gosling_options & options)224 void get_options(int argc, char ** argv,
225 		 Gosling_options & options) {
226 
227 
228   for(int i=1; i< argc; i++) {
229     if(!strcmp(argv[i], "-label") && argc > i+1) {
230       options.label=argv[++i];
231     }
232     else if(!strcmp(argv[i], "-json"))
233       options.json=1;
234     else if(!strcmp(argv[i], "-tot_energy"))
235       options.tot_energy=1;
236     else if(!strcmp(argv[i], "-trace"))
237       options.trace=1;
238     else if(!strcmp(argv[i], "-no_equil"))
239       options.equil=0;
240     else if(!strcmp(argv[i], "-show_autocorr"))
241       options.show_autocorr=1;
242     else if(!strcmp(argv[i], "-two_point_forces"))
243       options.two_pt_forces=1;
244     else if(!strcmp(argv[i], "-trace_force"))
245       options.trace_force=1;
246     else if(!strcmp(argv[i], "-reblock") && argc > i+1)
247       options.reblock=atoi(argv[++i]);
248     else if(!strcmp(argv[i], "-h")) {
249       cout << "usage: gosling <options> <log file>" << endl
250            << "-label <label>    : only print information for the given label" << endl
251            << "-json    : print the ouput in Json format" << endl
252            << "-trace            : print out energy traces for each label, into files named label.trace" << endl
253            << "-trace_force      : print out displacement traces for each label, into files named labelf#.trace" << endl
254            << "-reblock <number> : reblock the blocks into groups of <number>.  If they don't evenly divide, gosling" << endl
255            << "                    will throw out the first blocks until they do." << endl
256            << "-no_equil         : don't try to find the equilibration steps; just average over everything" << endl
257            << "-show_autocorr    : show estimates for the autocorrelation as a function of step for each label" << endl
258            << "-h                : print this help message " << endl;
259     }
260     else if(argv[i][0]=='-')
261       error("Unknown option: ",argv[i]);
262     else
263       options.filenames.push_back(argv[i]);
264   }
265 
266 }
267 
268 
269 //----------------------------------------------------------------------
270 
271 struct Label_list {
272   string label;
273   Array1 <Properties_final_average> avg;
274   int navg;
Label_listLabel_list275   Label_list(int max) {
276     avg.Resize(max);
277     navg=0;
278   }
279 };
280 
main(int argc,char ** argv)281 int main(int argc, char ** argv) {
282   cout.precision(10);
283 
284   if(argc <= 1) error("Need an argument");
285   Gosling_options options;
286   get_options(argc, argv, options);
287 
288 
289   vector <Label_list> all_averages;
290 
291   int nfiles=options.filenames.size();
292   for(int file=0; file < nfiles; file++) {
293 
294 
295     ifstream input(options.filenames[file].c_str());
296 
297     vector < string >  words;
298     parsefile(input, words);
299     input.close();
300 
301     vector <string> labels;
302     Array1 < Array1 <Properties_block > > allblocks;
303     Array1 < Array1 <Average_generator* > > avg_gen;
304     getBlocks(words, labels, allblocks, avg_gen);
305     int nlabels=labels.size();
306 
307     if(options.trace) output_trace(labels, allblocks);
308     if(options.trace_force) output_trace_force(labels, allblocks);
309 
310 
311     //Get the blocks from each file; if only one
312     //file, go ahead and print it out
313     Properties_final_average avg;
314     avg.showAutocorr(options.show_autocorr);
315     for(int lab=0; lab < nlabels; lab++) {
316       if(labels[lab]==options.label || options.label=="") {
317         int neffblock;
318         neffblock=reblock_average(allblocks(lab), options.reblock,
319                                   options.equil, avg);
320         if(neffblock==0) {
321           cout << "Skipping reblocking on " << labels[lab]
322           << " because there aren't enough blocks " << endl;
323           neffblock=reblock_average(allblocks(lab), 1, options.equil, avg);
324         }
325 
326         if(nfiles < 2) {
327           if(options.json){
328             cout<< "{" << endl;
329             cout<<  "\"label\":\"" << labels[lab] << "\"," << endl;
330             cout<<  "\"total blocks\":" << allblocks(lab).GetDim(0) <<"," << endl;
331             cout<<  "\"reblocking\":" <<  options.reblock <<"," << endl;
332             avg.JsonOutput(cout, avg_gen(lab));
333             cout << "}" << endl;
334         }
335           else{
336           cout << "#####################" << endl;
337           cout << labels[lab] << ":  "<< allblocks(lab).GetDim(0)
338           << " total blocks reblocked into " << neffblock << endl;
339           cout << "#####################" << endl;
340           avg.showSummary(cout,avg_gen(lab));
341           }
342 
343         }
344 
345         int found=0;
346         for(vector<Label_list>::iterator i=all_averages.begin();
347             i!= all_averages.end(); i++) {
348           if(labels[lab] == i->label) {
349             i->avg(i->navg++)=avg;
350             found=1;
351           }
352         }
353         if(!found) {
354           Label_list nlabel(nfiles);
355           nlabel.avg=avg;
356           nlabel.navg=1;
357           nlabel.label=labels[lab];
358           all_averages.push_back(nlabel);
359         }
360 
361       }
362     }
363   }
364 
365 
366   //Print out averages accumulated from
367   //all files
368 
369   if(nfiles > 1) {
370     error("Can only treat one file for now");
371     /*
372     Properties_final_average avg;
373     avg.showAutocorr(options.show_autocorr);
374 
375     for(vector<Label_list> :: iterator lab=all_averages.begin();
376         lab!= all_averages.end(); lab++) {
377       avg.averageReduce(lab->avg, 0, lab->navg);
378       cout << "#########################" << endl;
379       cout << lab->label << " reaccumulated \n";
380       cout << "#########################" << endl;
381       avg.showSummary(cout);
382     }
383      */
384   }
385 
386 
387 
388 }
389