1################################################################## 2## (c) Copyright 2015- by Jaron T. Krogel ## 3################################################################## 4 5 6#====================================================================# 7# qmcpack_method_analyzers.py # 8# Analyzer classes at the level of QMC methods. Instances # 9# contain all data outputted by VMC, Opt, DMC, etc. sub-runs # 10# carried out by QMCPACK. # 11# # 12# Content summary: # 13# MethodAnalyzer # 14# Base class for specific method analyzers. # 15# Derived classes are OptAnalyzer, VmcAnalyzer, DmcAnalyzer # 16# # 17#====================================================================# 18 19 20import os 21import re 22from generic import obj 23from hdfreader import HDFreader 24from qmcpack_analyzer_base import Checks,QAanalyzer,QAdata,QAHDFdata 25from qmcpack_property_analyzers import WavefunctionAnalyzer 26from qmcpack_quantity_analyzers import HDFAnalyzer 27from debug import * 28 29 30class MethodAnalyzer(QAanalyzer): 31 def __init__(self,series=None,calc=None,input=None,nindent=0): 32 QAanalyzer.__init__(self,nindent=nindent) 33 if series!=None and calc!=None and input!=None: 34 self.init_sub_analyzers(series,calc,input) 35 #end if 36 #end def __init__ 37 38 39 def init_sub_analyzers(self,series,calc,input): 40 request = QAanalyzer.request 41 run_info = QAanalyzer.run_info 42 43 source_path = run_info.source_path 44 file_prefix = run_info.file_prefix+'.s'+str(series).zfill(3) 45 method = calc.method 46 47 files = obj() 48 outfiles = os.listdir(source_path) 49 self.vlog('looking for file prefix: '+file_prefix,n=2) 50 matched = False 51 for file in outfiles: 52 if file.startswith(file_prefix): 53 local_match = True 54 if file.endswith('scalar.dat'): 55 files.scalar = file 56 elif file.endswith('stat.h5'): 57 files.stat = file 58 elif file.endswith('storeConfig.h5'): 59 files.storeconfig = file 60 elif file.endswith('opt.xml'): 61 files.opt = file 62 elif file.endswith('dmc.dat') and method=='dmc': 63 files.dmc = file 64 elif '.traces.' in file: 65 if not 'traces' in files: 66 files.traces = [] 67 #end if 68 files.traces.append(file) 69 else: 70 local_match = False 71 #end if 72 matched = matched or local_match 73 self.vlog('match found: '+file,n=3) 74 #end if 75 #end for 76 complete = matched 77 complete &= 'scalar' in files 78 if 'linear' in method or method=='opt': 79 complete &= 'opt' in files 80 #end if 81 equil = request.equilibration 82 nblocks_exclude = -1 83 if isinstance(equil,int): 84 nblocks_exclude = equil 85 elif isinstance(equil,(dict,obj)): 86 if series in equil: 87 nblocks_exclude = equil[series] 88 #end if 89 elif equil!=None: 90 self.error('invalid input for equilibration which must be an int, dict, or obj\n you provided: {0}\n with type {1}'.format(equil,equil.__class__.__name__)) 91 #end if 92 data_sources = request.data_sources & set(files.keys()) 93 method_info = obj( 94 method = method, 95 series = series, 96 file_prefix = file_prefix, 97 files = files, 98 data_sources = data_sources, 99 method_input = calc.copy(), 100 nblocks_exclude = nblocks_exclude, 101 complete = complete, 102 ) 103 self.info.transfer_from(method_info) 104 105 self.vlog('requested sources = '+str(list(request.data_sources)),n=2) 106 self.vlog('files available = '+str(list(files.keys())),n=2) 107 self.vlog('available sources = '+str(list(data_sources)),n=2) 108 109 if not matched: 110 msg = 'no data files found\n file prefix used for matching: {0}\n checked all files in directory: {1}'.format(file_prefix,source_path) 111 #self.error(msg,trace=False) 112 #self.warn(msg) 113 return 114 #end if 115 116 self.set_global_info() 117 118 try: 119 analyzers = self.capabilities.analyzers 120 if 'scalar' in data_sources: 121 filepath = os.path.join(source_path,files.scalar) 122 self.scalars = analyzers.scalars_dat(filepath,equilibration='LocalEnergy',nindent=self.subindent()) 123 #end if 124 if 'stat' in data_sources: 125 #determine scalars and analyzer quantities 126 analyzer_quantities = self.capabilities.analyzer_quantities 127 analyzer_quants = obj() 128 ignored_quantities = set() 129 ham = input.get('hamiltonian') 130 ham = ham.get_single('h0') 131 ham_est = ham.get('estimator') 132 calc_est = calc.get('estimator') 133 estimators = obj() 134 if ham_est!=None: 135 estimators.transfer_from(ham_est) 136 #end if 137 if calc_est!=None: 138 estimators.transfer_from(calc_est) 139 #end if 140 for estname,est in estimators.items(): 141 if est==None: 142 self.error('estimators have not been read properly by QmcpackInput',trace=False) 143 #end if 144 has_type = 'type' in est 145 has_name = 'name' in est 146 if has_type and has_name: 147 type = est.type 148 name = est.name 149 elif has_name: 150 type = est.name 151 name = est.name 152 elif has_type: 153 type = est.type 154 name = est.type 155 else: 156 self.error('estimator '+estname+' has no type or name') 157 #end if 158 cname = self.condense_name(name) 159 ctype = self.condense_name(type) 160 161 if ctype=='density' and not has_name: 162 name = 'any' 163 #end if 164 165 if ctype in analyzer_quantities: 166 analyzer_quants[name] = self.condense_name(type) 167 #end if 168 #end for 169 not_scalars = set(analyzer_quants.keys()) 170 171 self.scalars_hdf = analyzers.scalars_hdf(not_scalars,nindent=self.subindent()) 172 173 analyzer_quantities = analyzer_quantities & request.quantities 174 for name,type in analyzer_quants.items(): 175 if type in analyzer_quantities: 176 if type in analyzers: 177 qqa = analyzers[type](name,nindent=self.subindent()) 178 qqa.init_sub_analyzers() 179 self[name] = qqa 180 else: 181 ignored_quantities.add(name) 182 #end if 183 #end if 184 #end for 185 self.info.ignored_quantities = ignored_quantities 186 #end if 187 if 'dmc' in data_sources: 188 filepath = os.path.join(source_path,files.dmc) 189 self.dmc = analyzers.dmc_dat(filepath,nindent=self.subindent()) 190 #end if 191 if 'traces' in data_sources and 'traces' in files: 192 self.traces = analyzers.traces(source_path,files.traces,nindent=self.subindent()) 193 #end if 194 except: 195 self.info.complete = False 196 #end try 197 198 self.unset_global_info() 199 200 return 201 #end def init_sub_analyzers 202 203 204 def load_data_local(self): 205 source_path = QAanalyzer.run_info.source_path 206 data_sources = self.info.data_sources 207 files = self.info.files 208 if 'stat' in data_sources: 209 filepath = os.path.join(source_path,files.stat) 210 hr = HDFreader(filepath) 211 if not hr._success: 212 self.warn(' hdf file seems to be corrupted, skipping contents:\n '+filepath) 213 #end if 214 hdf = hr.obj 215 self.data = QAHDFdata() 216 self.data.transfer_from(hdf) 217 #end if 218 remove = [] 219 for name,value in self.items(): 220 if isinstance(value,HDFAnalyzer): 221 value.load_data_local(self.data) 222 value.info.data_loaded = True 223 if value.info.should_remove: 224 remove.append(name) 225 #end if 226 #end if 227 #end for 228 for name in remove: 229 del self[name] 230 #end for 231 #end def load_data_local 232 233 234 235 def set_global_info(self): 236 QAanalyzer.method_info = self.info 237 #end def set_global_info 238 239 def unset_global_info(self): 240 QAanalyzer.method_info = None 241 #end def unset_global_info 242 243 244 def check_traces(self,pad=None): 245 verbose = pad!=None 246 method = self.info.method 247 series = self.info.series 248 if verbose: 249 desc = 'method {0} series {1}'.format(method,series) 250 #end if 251 if 'traces' in self: 252 check = {None:True,False:False,True:True} 253 if verbose: 254 self.log(pad+'Checking traces in '+desc) 255 #end if 256 scalars = None 257 scalars_hdf = None 258 dmc = None 259 if 'scalars' in self and 'data' in self.scalars: 260 scalars = self.scalars.data 261 #end if 262 if 'scalars_hdf' in self and 'data' in self.scalars_hdf: 263 scalars_hdf = self.scalars_hdf.data 264 #end if 265 if 'dmc' in self and 'data' in self.dmc: 266 dmc = self.dmc.data 267 #end if 268 checks = Checks('traces') 269 checks.exclude(None) 270 traces = self.traces 271 traces.form_diagnostic_data() 272 checks.psums = traces.check_particle_sums() 273 if method=='dmc': 274 checks.dmc = traces.check_dmc(dmc) 275 else: 276 svalid,shvalid = traces.check_scalars(scalars,scalars_hdf) 277 checks.scalars = svalid 278 checks.scalars_hdf = shvalid 279 #end if 280 valid = checks.valid() 281 if verbose: 282 checks.write(pad+' ') 283 #end if 284 return valid 285 else: 286 if verbose: 287 self.log(pad+'No traces in '+desc) 288 #end if 289 return None 290 #end if 291 #end def check_traces 292 293#end class MethodAnalyzer 294 295 296 297 298class OptAnalyzer(MethodAnalyzer): 299 def init_sub_analyzers(self,series,calc,input): 300 MethodAnalyzer.init_sub_analyzers(self,series,calc,input) 301 302 source_path = QAanalyzer.run_info.source_path 303 files = self.info.files 304 305 if 'opt' in files: 306 opt_out_xml = os.path.join(source_path,files.opt) 307 self.wavefunction = WavefunctionAnalyzer(opt_out_xml) 308 #end if 309 #ed def init_sub_analyzers 310#end class OptAnalyzer 311 312class VmcAnalyzer(MethodAnalyzer): 313 None 314#end class OptAnalyzer 315 316class DmcAnalyzer(MethodAnalyzer): 317 None 318#end class OptAnalyzer 319