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