def write_script_output(fn_h5, grp_name, results, args): '''Store the output of a script in an open HDF5 file **Arguments:** fn_h5 The HDF5 filename grp_name The name of the group where the results will be stored. results A dictionary with results. args The results of the command line parser. All arguments are stored as attributes in the HDF5 output file. ''' with LockedH5File(fn_h5) as f: # Store results if grp_name in f: grp = f[grp_name] for key in grp.keys(): del grp[key] else: grp = f.require_group(grp_name) for key, value in results.iteritems(): dump_hdf5_low(grp, key, value) # Store command-line arguments arguments store_args(args, grp) if log.do_medium: log('Results written to %s:%s' % (fn_h5, grp_name))
def write_run_script(self): # write the script fn_script = "run_%s.sh" % self.name exists = os.path.isfile(fn_script) if not exists: with open(fn_script, "w") as f: print >> f, self.run_script log("Written new: ", fn_script) else: log("Not overwriting: ", fn_script) # make the script executable os.chmod(fn_script, stat.S_IXUSR | os.stat(fn_script).st_mode)
def write_run_script(self): # write the script fn_script = 'run_%s.sh' % self.name exists = os.path.isfile(fn_script) if not exists: with open(fn_script, 'w') as f: print(self.run_script, file=f) log('Written new: ', fn_script) else: log('Not overwriting: ', fn_script) # make the script executable os.chmod(fn_script, stat.S_IXUSR | os.stat(fn_script).st_mode)
def write_run_script(self): # write the script fn_script = 'run_%s.sh' % self.name exists = os.path.isfile(fn_script) if not exists: with open(fn_script, 'w') as f: print >> f, self.run_script log('Written new: ', fn_script) else: log('Not overwriting: ', fn_script) # make the script executable os.chmod(fn_script, stat.S_IXUSR | os.stat(fn_script).st_mode)
def write_part_output(fn_h5, grp_name, part, names, args): '''Write the output of horton-wpart.py or horton-cpart.py **Arguments:** fn_h5 The filename for the HDF5 output file. grp_name the destination group part The partitioning object (instance of subclass of horton.part.base.Part) names The names of the cached items that must go in the HDF5 outut file. args The results of the command line parser. All arguments are stored as attributes in the HDF5 output file. ''' # Store the results in an HDF5 file with LockedH5File(fn_h5) as f: # Store results if grp_name in f: grp = f[grp_name] for key in grp.keys(): del grp[key] else: grp = f.create_group(grp_name) for name in names: dump_hdf5_low(grp, name, part[name]) # Store command line arguments store_args(args, grp) if args.debug: # Store additional data for debugging if 'debug' in grp: del grp['debug'] grp_debug = grp.create_group('debug') for debug_key in part.cache.iterkeys(): debug_name = '_'.join(str(x) for x in debug_key) if debug_name not in names: grp_debug[debug_name] = part.cache.load(debug_key) if log.do_medium: log('Results written to %s:%s' % (fn_h5, grp_name))
def main(): args = parse_args() fn_h5, grp_name = parse_h5(args.output, 'output') # check if the group is already present (and not empty) in the output file if check_output(fn_h5, grp_name, args.overwrite): return # Load the cost function from the HDF5 file cost, used_volume = load_cost(args.cost) # Find the optimal charges results = {} results['x'] = cost.solve(args.qtot, args.ridge) results['charges'] = results['x'][:cost.natom] # Related properties results['cost'] = cost.value(results['x']) if results['cost'] < 0: results['rmsd'] = 0.0 else: results['rmsd'] = (results['cost'] / used_volume)**0.5 # Worst case stuff results['cost_worst'] = cost.worst(0.0) if results['cost_worst'] < 0: results['rmsd_worst'] = 0.0 else: results['rmsd_worst'] = (results['cost_worst'] / used_volume)**0.5 # Write some things on screen if log.do_medium: log('Important parameters:') log.hline() log('RMSD charges: %10.5e' % np.sqrt( (results['charges']**2).mean())) log('RMSD ESP: %10.5e' % results['rmsd']) log('Worst RMSD ESP: %10.5e' % results['rmsd_worst']) log.hline() # Perform a symmetry analysis if requested if args.symmetry is not None: mol_pot = IOData.from_file(args.symmetry[0]) mol_sym = IOData.from_file(args.symmetry[1]) if not hasattr(mol_sym, 'symmetry'): raise ValueError('No symmetry information found in %s.' % args.symmetry[1]) aim_results = {'charges': results['charges']} sym_results = symmetry_analysis(mol_pot.coordinates, mol_pot.cell, mol_sym.symmetry, aim_results) results['symmetry'] = sym_results # Store the results in an HDF5 file write_script_output(fn_h5, grp_name, results, args)
def log(self): log(" Nr Pop Chg Energy Ionization Affinity") log.hline() for number, cases in sorted(self.all.iteritems()): for pop, energy in sorted(cases.iteritems()): energy_prev = cases.get(pop - 1) if energy_prev is None: ip_str = "" else: ip_str = "% 18.10f" % (energy_prev - energy) energy_next = cases.get(pop + 1) if energy_next is None: ea_str = "" else: ea_str = "% 18.10f" % (energy - energy_next) log("%3i %3i %+3i % 18.10f %18s %18s" % (number, pop, number - pop, energy, ip_str, ea_str)) log.blank()
def main(): args = parse_args() fn_h5, grp_name = parse_h5(args.output, 'output') # check if the group is already present (and not empty) in the output file if check_output(fn_h5, grp_name, args.overwrite): return # Load the cost function from the HDF5 file cost, used_volume = load_cost(args.cost) # Find the optimal charges results = {} results['x'] = cost.solve(args.qtot, args.ridge) results['charges'] = results['x'][:cost.natom] # Related properties results['cost'] = cost.value(results['x']) if results['cost'] < 0: results['rmsd'] = 0.0 else: results['rmsd'] = (results['cost']/used_volume)**0.5 # Worst case stuff results['cost_worst'] = cost.worst(0.0) if results['cost_worst'] < 0: results['rmsd_worst'] = 0.0 else: results['rmsd_worst'] = (results['cost_worst']/used_volume)**0.5 # Write some things on screen if log.do_medium: log('Important parameters:') log.hline() log('RMSD charges: %10.5e' % np.sqrt((results['charges']**2).mean())) log('RMSD ESP: %10.5e' % results['rmsd']) log('Worst RMSD ESP: %10.5e' % results['rmsd_worst']) log.hline() # Perform a symmetry analysis if requested if args.symmetry is not None: sys = System.from_file(args.symmetry[0]) sys_sym = System.from_file(args.symmetry[1]) sym = sys_sym.extra.get('symmetry') if sym is None: raise ValueError('No symmetry information found in %s.' % args.symmetry[1]) sys_results = {'charges': results['charges']} sym_results = symmetry_analysis(sys, sym, sys_results) results['symmetry'] = sym_results sys.extra['symmetry'] = sym # Store the results in an HDF5 file write_script_output(fn_h5, grp_name, results, args)
def log(self): log(' Nr Pop Chg Energy Ionization Affinity' ) log.hline() for number, cases in sorted(self.all.iteritems()): for pop, energy in sorted(cases.iteritems()): energy_prev = cases.get(pop - 1) if energy_prev is None: ip_str = '' else: ip_str = '% 18.10f' % (energy_prev - energy) energy_next = cases.get(pop + 1) if energy_next is None: ea_str = '' else: ea_str = '% 18.10f' % (energy - energy_next) log('%3i %3i %+3i % 18.10f %18s %18s' % (number, pop, number - pop, energy, ip_str, ea_str)) log.blank()
def main(): args = parse_args() fn_h5, grp_name = parse_h5(args.h5, 'h5') with LockedH5File(fn_h5, 'r') as fin, open(args.csv, 'w') as fout: w = csv.writer(fout) w.writerow(['Converted data from %s' % args.h5]) w.writerow([]) for name, dset in iter_datasets(fin[grp_name]): if len(dset.shape) > 3: if log.do_warning: log.warn( 'Skipping %s because it has more than three axes.' % name) else: log('Converting %s' % name) w.writerow(['Dataset', name]) w.writerow(['Shape'] + list(dset.shape)) if len(dset.shape) == 0: w.writerow([dset[()]]) elif len(dset.shape) == 1: for value in dset: w.writerow([value]) elif len(dset.shape) == 2: for row in dset: w.writerow([value for value in row]) elif len(dset.shape) == 3: for array in dset: l = [] for col in array.T: for value in col: l.append(value) l.append('') del l[-1] w.writerow(l) else: w.writerow(['Skipped because ndim=%i>3' % len(dset.shape)]) w.writerow([])
def _log_includes(self): # log the include names if len(self.file_names) + len(self.line_names) > 0 and log.do_medium: log('The following includes were detected in the template:') for name, kind, records in self.includes: log(' %s (%s)' % (name, kind)) for n, p, m, s in self.includes[name]: log(' %03i_%03i_%02i' % (n, p, m))
def main(): args = parse_args() fn_h5, grp_name = parse_h5(args.h5, 'h5') with LockedH5File(fn_h5, 'r') as fin, open(args.csv, 'w') as fout: w = csv.writer(fout) w.writerow(['Converted data from %s' % args.h5]) w.writerow([]) for name, dset in iter_datasets(fin[grp_name]): if len(dset.shape) > 3: if log.do_warning: log.warn('Skipping %s because it has more than three axes.' % name) else: log('Converting %s' % name) w.writerow(['Dataset', name]) w.writerow(['Shape'] + list(dset.shape)) if len(dset.shape) == 0: w.writerow([dset[()]]) elif len(dset.shape) == 1: for value in dset: w.writerow([value]) elif len(dset.shape) == 2: for row in dset: w.writerow([value for value in row]) elif len(dset.shape) == 3: for array in dset: l = [] for col in array.T: for value in col: l.append(value) l.append('') del l[-1] w.writerow(l) else: w.writerow(['Skipped because ndim=%i>3' % len(dset.shape)]) w.writerow([])
def main(): args = parse_args() fn_h5, grp_name = parse_h5(args.output, 'output') # check if the group is already present (and not empty) in the output file if check_output(fn_h5, grp_name, args.overwrite): return # Load the cost function from the HDF5 file cost, used_volume = load_cost(args.cost) # Find the optimal charges results = {} # MODIFICATION HERE results['x'] = cost.solve(args.qtot, args.ridge) results['charges'] = results['x'][:cost.natom] # Related properties results['cost'] = cost.value(results['x']) if results['cost'] < 0: results['rmsd'] = 0.0 else: results['rmsd'] = (results['cost'] / used_volume)**0.5 # Worst case stuff results['cost_worst'] = cost.worst(0.0) if results['cost_worst'] < 0: results['rmsd_worst'] = 0.0 else: results['rmsd_worst'] = (results['cost_worst'] / used_volume)**0.5 # Write some things on screen if log.do_medium: log('Important parameters:') log.hline() log('RMSD charges: %10.5e' % np.sqrt( (results['charges']**2).mean())) log('RMSD ESP: %10.5e' % results['rmsd']) log('Worst RMSD ESP: %10.5e' % results['rmsd_worst']) log.hline() # Store the results in an HDF5 file write_script_output(fn_h5, grp_name, results, args)
def main(): args = parse_args() fn_h5, grp_name = parse_h5(args.output, 'output') # check if the group is already present (and not empty) in the output file if check_output(fn_h5, grp_name, args.overwrite): return # Load the cost function from the HDF5 file cost, used_volume = load_cost(args.cost) # Find the optimal charges results = {} results['x'] = cost.solve(args.qtot, args.ridge) results['charges'] = results['x'][:cost.natom] # Related properties results['cost'] = cost.value(results['x']) if results['cost'] < 0: results['rmsd'] = 0.0 else: results['rmsd'] = (results['cost']/used_volume)**0.5 # Worst case stuff results['cost_worst'] = cost.worst(0.0) if results['cost_worst'] < 0: results['rmsd_worst'] = 0.0 else: results['rmsd_worst'] = (results['cost_worst']/used_volume)**0.5 # Write some things on screen if log.do_medium: log('Important parameters:') log.hline() log('RMSD charges: %10.5e' % np.sqrt((results['charges']**2).mean())) log('RMSD ESP: %10.5e' % results['rmsd']) log('Worst RMSD ESP: %10.5e' % results['rmsd_worst']) log.hline() # Store the results in an HDF5 file write_script_output(fn_h5, grp_name, results, args)
def main(): args = parse_args() fn_h5, grp_name = parse_h5(args.output, 'output') # check if the group is already present (and not empty) in the output file if check_output(fn_h5, grp_name, args.overwrite): return # Load the cost function from the HDF5 file cost, used_volume = load_cost(args.cost) # Load the charges from the HDF5 file charges = load_charges(args.charges) # Fix total charge if requested if args.qtot is not None: charges -= (charges.sum() - args.qtot) / len(charges) # Store parameters in output results = {} results['qtot'] = charges.sum() # Fitness of the charges results['cost'] = cost.value_charges(charges) if results['cost'] < 0: results['rmsd'] = 0.0 else: results['rmsd'] = (results['cost'] / used_volume)**0.5 # Worst case stuff results['cost_worst'] = cost.worst(0.0) if results['cost_worst'] < 0: results['rmsd_worst'] = 0.0 else: results['rmsd_worst'] = (results['cost_worst'] / used_volume)**0.5 # Write some things on screen if log.do_medium: log('RMSD charges: %10.5e' % np.sqrt( (charges**2).mean())) log('RMSD ESP: %10.5e' % results['rmsd']) log('Worst RMSD ESP: %10.5e' % results['rmsd_worst']) log.hline() # Store the results in an HDF5 file write_script_output(fn_h5, grp_name, results, args)
def main(): args = parse_args() fn_h5, grp_name = parse_h5(args.output, 'output') # check if the group is already present (and not empty) in the output file if check_output(fn_h5, grp_name, args.overwrite): return # Load the cost function from the HDF5 file cost, used_volume = load_cost(args.cost) # Load the charges from the HDF5 file charges = load_charges(args.charges) # Fix total charge if requested if args.qtot is not None: charges -= (charges.sum() - args.qtot)/len(charges) # Store parameters in output results = {} results['qtot'] = charges.sum() # Fitness of the charges results['cost'] = cost.value_charges(charges) if results['cost'] < 0: results['rmsd'] = 0.0 else: results['rmsd'] = (results['cost']/used_volume)**0.5 # Worst case stuff results['cost_worst'] = cost.worst(0.0) if results['cost_worst'] < 0: results['rmsd_worst'] = 0.0 else: results['rmsd_worst'] = (results['cost_worst']/used_volume)**0.5 # Write some things on screen if log.do_medium: log('RMSD charges: %10.5e' % np.sqrt((charges**2).mean())) log('RMSD ESP: %10.5e' % results['rmsd']) log('Worst RMSD ESP: %10.5e' % results['rmsd_worst']) log.hline() # Store the results in an HDF5 file write_script_output(fn_h5, grp_name, results, args)
def write_input(self, number, charge, mult, template, do_overwrite): # Directory stuff nel = number - charge dn_mult = '%03i_%s_%03i_q%+03i/mult%02i' % ( number, periodic[number].symbol.lower().rjust( 2, '_'), nel, charge, mult) # Figure out if we want to write fn_inp = '%s/atom.in' % dn_mult exists = os.path.isfile(fn_inp) do_write = not exists or do_overwrite if do_write: try: subs = template.get_subs(number, nel, mult) except KeyError: if log.do_warning: log.warn( 'Could not find all subs for %03i.%03i.%03i. Skipping.' % (number, nel, mult)) return dn_mult, False if not os.path.isdir(dn_mult): os.makedirs(dn_mult) with open(fn_inp, 'w') as f: f.write( template.substitute( subs, charge=str(charge), mult=str(mult), number=str(number), element=periodic[number].symbol, )) if log.do_medium: if exists: log('Overwritten: ', fn_inp) else: log('Written new: ', fn_inp) elif log.do_medium: log('Not overwriting: ', fn_inp) return dn_mult, do_write
def write_input(self, number, charge, mult, template, do_overwrite): # Directory stuff nel = number - charge dn_mult = "%03i_%s_%03i_q%+03i/mult%02i" % ( number, periodic[number].symbol.lower().rjust(2, "_"), nel, charge, mult, ) # Figure out if we want to write fn_inp = "%s/atom.in" % dn_mult exists = os.path.isfile(fn_inp) do_write = not exists or do_overwrite if do_write: try: subs = template.get_subs(number, nel, mult) except KeyError: if log.do_warning: log.warn("Could not find all subs for %03i.%03i.%03i. Skipping." % (number, nel, mult)) return dn_mult, False if not os.path.isdir(dn_mult): os.makedirs(dn_mult) with open(fn_inp, "w") as f: f.write( template.substitute( subs, charge=str(charge), mult=str(mult), number=str(number), element=periodic[number].symbol ) ) if log.do_medium: if exists: log("Overwritten: ", fn_inp) else: log("Written new: ", fn_inp) elif log.do_medium: log("Not overwriting: ", fn_inp) return dn_mult, do_write
def write_part_output(fn_h5, grp_name, part, keys, args): '''Write the output of horton-wpart.py or horton-cpart.py **Arguments:** fn_h5 The filename for the HDF5 output file. grp_name the destination group part The partitioning object (instance of subclass of horton.part.base.Part) keys The keys of the cached items that must go in the HDF5 outut file. args The results of the command line parser. All arguments are stored as attributes in the HDF5 output file. ''' def get_results(part, keys): results = {} for key in keys: if isinstance(key, basestring): results[key] = part[key] elif isinstance(key, tuple): assert len(key) == 2 index = key[1] assert isinstance(index, int) assert index >= 0 assert index < part.natom atom_results = results.setdefault('atom_%05i' % index, {}) atom_results[key[0]] = part[key] return results # Store the results in an HDF5 file with LockedH5File(fn_h5) as f: # Transform results to a suitable dictionary structure results = get_results(part, keys) # Store results grp = f.require_group(grp_name) for key in grp.keys(): del grp[key] dump_h5(grp, results) # Store command line arguments store_args(args, grp) if args.debug: # Collect debug results debug_keys = [key for key in part.cache.iterkeys() if key not in keys] debug_results = get_results(part, debug_keys) # Store additional data for debugging if 'debug' in grp: del grp['debug'] debuggrp = f.create_group('debug') dump_h5(debuggrp, debug_results) if log.do_medium: log('Results written to %s:%s' % (fn_h5, grp_name))
def main(): args = parse_args() fn_h5, grp_name = parse_h5(args.output, 'output') # check if the group is already present (and not empty) in the output file if check_output(fn_h5, grp_name, args.overwrite): return # Load the potential data if log.do_medium: log('Loading potential array') mol_pot = IOData.from_file(args.cube) if not isinstance(mol_pot.grid, UniformGrid): raise TypeError('The specified file does not contain data on a rectangular grid.') mol_pot.grid.pbc[:] = parse_pbc(args.pbc) # correct pbc esp = mol_pot.cube_data # Reduce the grid if required if args.stride > 1: esp, mol_pot.grid = reduce_data(esp, mol_pot.grid, args.stride, args.chop) # Fix sign if args.sign: esp *= -1 # Some screen info if log.do_medium: log('Important parameters:') log.hline() log('Number of grid points: %12i' % np.product(mol_pot.grid.shape)) log('Grid shape: [%8i, %8i, %8i]' % tuple(mol_pot.grid.shape)) log('PBC: [%8i, %8i, %8i]' % tuple(mol_pot.grid.pbc)) log.hline() # Construct the weights for the ESP Cost function. wdens = parse_wdens(args.wdens) if wdens is not None: if log.do_medium: log('Loading density array') # either the provided density or a built-in prodensity rho = load_rho(mol_pot.coordinates, mol_pot.numbers, wdens[0], mol_pot.grid, args.stride, args.chop) wdens = (rho,) + wdens[1:] if log.do_medium: log('Constructing weight function') weights = setup_weights(mol_pot.coordinates, mol_pot.numbers, mol_pot.grid, dens=wdens, near=parse_wnear(args.wnear), far=parse_wnear(args.wfar), ) # write the weights to a cube file if requested if args.wsave is not None: if log.do_medium: log(' Saving weights array ') # construct a new data dictionary that contains all info for the cube file mol_weights = mol_pot.copy() mol_weights.cube_data = weights mol_weights.to_file(args.wsave) # rescale weights such that the cost function is the mean-square-error if weights.max() == 0.0: raise ValueError('No points with a non-zero weight were found') wmax = weights.min() wmin = weights.max() used_volume = mol_pot.grid.integrate(weights) # Some screen info if log.do_medium: log('Important parameters:') log.hline() log('Used number of grid points: %12i' % (weights>0).sum()) log('Used volume: %12.5f' % used_volume) log('Used volume/atom: %12.5f' % (used_volume/mol_pot.natom)) log('Lowest weight: %12.5e' % wmin) log('Highest weight: %12.5e' % wmax) log('Max weight at edge: %12.5f' % max_at_edge(weights, mol_pot.grid.pbc)) # Ewald parameters rcut, alpha, gcut = parse_ewald_args(args) # Some screen info if log.do_medium: log('Ewald real cutoff: %12.5e' % rcut) log('Ewald alpha: %12.5e' % alpha) log('Ewald reciprocal cutoff: %12.5e' % gcut) log.hline() # Construct the cost function if log.do_medium: log('Setting up cost function (may take a while) ') cost = ESPCost.from_grid_data(mol_pot.coordinates, mol_pot.grid, esp, weights, rcut, alpha, gcut) # Store cost function info results = {} results['cost'] = cost results['used_volume'] = used_volume # Store cost function properties results['evals'] = np.linalg.eigvalsh(cost._A) abs_evals = abs(results['evals']) if abs_evals.min() == 0.0: results['cn'] = 0.0 else: results['cn'] = abs_evals.max()/abs_evals.min() # Report some on-screen info if log.do_medium: log('Important parameters:') log.hline() log('Lowest abs eigen value: %12.5e' % abs_evals.min()) log('Highest abs eigen value: %12.5e' % abs_evals.max()) log('Condition number: %12.5e' % results['cn']) log.hline() # Store the results in an HDF5 file write_script_output(fn_h5, grp_name, results, args)
def main(): args = parse_args() fn_h5, grp_name = parse_h5(args.output, 'output') # check if the group is already present (and not empty) in the output file if check_output(fn_h5, grp_name, args.overwrite): return # Load the charges from the HDF5 file charges = load_charges(args.charges) # Load the uniform grid and the coordintes ugrid, coordinates = load_ugrid_coordinates(args.grid) ugrid.pbc[:] = 1 # enforce 3D periodic # Fix total charge if requested if args.qtot is not None: charges -= (charges.sum() - args.qtot) / len(charges) # Store parameters in output results = {} results['qtot'] = charges.sum() # Determine the grid specification results['ugrid'] = ugrid # Ewald parameters rcut, alpha, gcut = parse_ewald_args(args) # Some screen info if log.do_medium: log('Important parameters:') log.hline() log('Number of grid points: %12i' % ugrid.size) log('Grid shape: [%8i, %8i, %8i]' % tuple(ugrid.shape)) log('Ewald real cutoff: %12.5e' % rcut) log('Ewald alpha: %12.5e' % alpha) log('Ewald reciprocal cutoff: %12.5e' % gcut) log.hline() # TODO: add summation ranges log('Computing ESP (may take a while)') # Allocate and compute ESP grid esp = np.zeros(ugrid.shape, float) compute_esp_grid_cube(ugrid, esp, coordinates, charges, rcut, alpha, gcut) results['esp'] = esp # Store the results in an HDF5 file write_script_output(fn_h5, grp_name, results, args)
def main(): args = parse_args() fn_h5, grp_name = parse_h5(args.output, 'output') # check if the group is already present (and not empty) in the output file if check_output(fn_h5, grp_name, args.overwrite): return # Load the charges from the HDF5 file charges = load_charges(args.charges) # Load the uniform grid and the coordintes ugrid, coordinates = load_ugrid_coordinates(args.grid) ugrid.pbc[:] = 1 # enforce 3D periodic # Fix total charge if requested if args.qtot is not None: charges -= (charges.sum() - args.qtot)/len(charges) # Store parameters in output results = {} results['qtot'] = charges.sum() # Determine the grid specification results['ugrid'] = ugrid # Ewald parameters rcut, alpha, gcut = parse_ewald_args(args) # Some screen info if log.do_medium: log('Important parameters:') log.hline() log('Number of grid points: %12i' % ugrid.size) log('Grid shape: [%8i, %8i, %8i]' % tuple(ugrid.shape)) log('Ewald real cutoff: %12.5e' % rcut) log('Ewald alpha: %12.5e' % alpha) log('Ewald reciprocal cutoff: %12.5e' % gcut) log.hline() # TODO: add summation ranges log('Computing ESP (may take a while)') # Allocate and compute ESP grid esp = np.zeros(ugrid.shape, float) compute_esp_grid_cube(ugrid, esp, coordinates, charges, rcut, alpha, gcut) results['esp'] = esp # Store the results in an HDF5 file write_script_output(fn_h5, grp_name, results, args)
def main_convert(args): # The atomic grid specification agspec = AtomicGridSpec(args.grid) # The program is detected based on the run script that is present run_scripts = glob("run_*.sh") if len(run_scripts) != 1: raise RuntimeError( 'Found %i run_*.sh scripts while exactly one is needed to know which program was used to run the atomic computations.' % len(run_scripts)) program = atom_programs[run_scripts[0][4:-3]] # Loop over all sensible directories energy_table = EnergyTable() records = [] for dn_state in sorted(glob("[01]??_??_[01]??_q[+-]??")): number = int(dn_state[:3]) pop = int(dn_state[7:10]) cases = [] for dn_mult in sorted(glob('%s/mult??' % dn_state)): if log.do_medium: log('Loading from', dn_mult) data, energy = program.load_atom(dn_mult) if energy is None: if log.do_medium: log('No (sensible) results found: ', dn_mult) continue cases.append((energy, data)) if len(cases) == 0: if log.do_medium: log('Nothing found in: ', dn_state) continue # Get the lowest in energy and write to chk file cases.sort() energy, data = cases[0] # Add case to energy table energy_table.add(number, pop, energy) # Write atom to HORTON file if possible if data is not None: data.to_file('%s/horton.h5' % dn_state) # Construct a record for the proatomdb records.append(ProAtomRecord.from_iodata(data, agspec)) # Release memory data = None del cases # Let user know we are alive. if log.do_medium: log('Succesfull: ', dn_state) # Report energies if log.do_medium: energy_table.log() # Write out atoms file proatomdb = ProAtomDB(records) proatomdb.to_file('atoms.h5') if log.do_medium: log('Written atoms.h5') # Make nice figures plot_atoms(proatomdb)
def plot_atoms(proatomdb): try: import matplotlib.pyplot as pt except ImportError: if log.do_warning: log.warn('Skipping plots because matplotlib was not found.') return lss = {True: '-', False: ':'} for number in proatomdb.get_numbers(): r = proatomdb.get_rgrid(number).radii symbol = periodic[number].symbol charges = proatomdb.get_charges(number) suffix = '%03i_%s' % (number, symbol.lower().rjust(2, '_')) # The density (rho) pt.clf() for i, charge in enumerate(charges): record = proatomdb.get_record(number, charge) y = record.rho ls = lss[record.safe] color = get_color(i) label = 'q=%+i' % charge pt.semilogy(r / angstrom, y, lw=2, ls=ls, label=label, color=color) pt.xlim(0, 3) pt.ylim(ymin=1e-5) pt.xlabel('Distance from the nucleus [A]') pt.ylabel('Spherically averaged density [Bohr**-3]') pt.title('Proatoms for element %s (%i)' % (symbol, number)) pt.legend(loc=0) fn_png = 'dens_%s.png' % suffix pt.savefig(fn_png) if log.do_medium: log('Written', fn_png) # 4*pi*r**2*rho pt.clf() for i, charge in enumerate(charges): record = proatomdb.get_record(number, charge) y = record.rho ls = lss[record.safe] color = get_color(i) label = 'q=%+i' % charge pt.plot(r / angstrom, 4 * np.pi * r**2 * y, lw=2, ls=ls, label=label, color=color) pt.xlim(0, 3) pt.ylim(ymin=0.0) pt.xlabel('Distance from the nucleus [A]') pt.ylabel('4*pi*r**2*density [Bohr**-1]') pt.title('Proatoms for element %s (%i)' % (symbol, number)) pt.legend(loc=0) fn_png = 'rdens_%s.png' % suffix pt.savefig(fn_png) if log.do_medium: log('Written', fn_png) fukui_data = [] if number - charges[0] == 1: record0 = proatomdb.get_record(number, charges[0]) fukui_data.append((record0.rho, record0.safe, '%+i' % charges[0])) for i, charge in enumerate(charges[1:]): record0 = proatomdb.get_record(number, charge) record1 = proatomdb.get_record(number, charges[i]) fukui_data.append( (record0.rho - record1.rho, record0.safe and record1.safe, '%+i-%+i' % (charge, charges[i]))) # The Fukui functions pt.clf() for i, (f, safe, label) in enumerate(fukui_data): ls = lss[safe] color = get_color(i) pt.semilogy(r / angstrom, f, lw=2, ls=ls, label=label, color=color, alpha=1.0) pt.semilogy(r / angstrom, -f, lw=2, ls=ls, color=color, alpha=0.2) pt.xlim(0, 3) pt.ylim(ymin=1e-5) pt.xlabel('Distance from the nucleus [A]') pt.ylabel('Fukui function [Bohr**-3]') pt.title('Proatoms for element %s (%i)' % (symbol, number)) pt.legend(loc=0) fn_png = 'fukui_%s.png' % suffix pt.savefig(fn_png) if log.do_medium: log('Written', fn_png) # 4*pi*r**2*Fukui pt.clf() for i, (f, safe, label) in enumerate(fukui_data): ls = lss[safe] color = get_color(i) pt.plot(r / angstrom, 4 * np.pi * r**2 * f, lw=2, ls=ls, label=label, color=color) pt.xlim(0, 3) pt.xlabel('Distance from the nucleus [A]') pt.ylabel('4*pi*r**2*Fukui [Bohr**-1]') pt.title('Proatoms for element %s (%i)' % (symbol, number)) pt.legend(loc=0) fn_png = 'rfukui_%s.png' % suffix pt.savefig(fn_png) if log.do_medium: log('Written', fn_png)
def main_convert(args): # The atomic grid specification agspec = AtomicGridSpec(args.grid) # The program is detected based on the run script that is present run_scripts = glob("run_*.sh") if len(run_scripts) != 1: raise RuntimeError('Found %i run_*.sh scripts while exactly one is needed to know which program was used to run the atomic computations.' % len(run_scripts)) program = atom_programs[run_scripts[0][4:-3]] # Loop over all sensible directories energy_table = EnergyTable() records = [] for dn_state in sorted(glob("[01]??_??_[01]??_q[+-]??")): number = int(dn_state[:3]) pop = int(dn_state[7:10]) cases = [] for dn_mult in sorted(glob('%s/mult??' % dn_state)): if log.do_medium: log('Loading from', dn_mult) system, energy = program.load_atom(dn_mult) if energy is None: if log.do_medium: log('No (sensible) results found: ', dn_mult) continue cases.append((energy, system)) if len(cases) == 0: if log.do_medium: log('Nothing found in: ', dn_state) continue # Get the lowest in energy and write to chk file cases.sort() energy, system = cases[0] # Add case to energy table energy_table.add(number, pop, energy) # Write system to Horton file if possible if system is not None: system.assign_chk('%s/horton.h5' % dn_state) # Construct a record for the proatomdb records.append(ProAtomRecord.from_system(system, agspec)) # Release memory and close h5 files system = None del cases # Let user know we are alive. if log.do_medium: log('Succesfull: ', dn_state) # Report energies if log.do_medium: energy_table.log() # Write out atoms file proatomdb = ProAtomDB(records) proatomdb.to_file('atoms.h5') if log.do_medium: log('Written atoms.h5') # Make nice figures plot_atoms(proatomdb)
def plot_atoms(proatomdb): try: import matplotlib.pyplot as pt except ImportError: if log.do_warning: log.warn('Skipping plots because matplotlib was not found.') return lss = {True: '-', False: ':'} for number in proatomdb.get_numbers(): r = proatomdb.get_rgrid(number).radii symbol = periodic[number].symbol charges = proatomdb.get_charges(number) suffix = '%03i_%s' % (number, symbol.lower().rjust(2, '_')) # The density (rho) pt.clf() for i, charge in enumerate(charges): record = proatomdb.get_record(number, charge) y = record.rho ls = lss[record.safe] color = get_color(i) label = 'q=%+i' % charge pt.semilogy(r/angstrom, y, lw=2, ls=ls, label=label, color=color) pt.xlim(0, 3) pt.ylim(ymin=1e-5) pt.xlabel('Distance from the nucleus [A]') pt.ylabel('Spherically averaged density [Bohr**-3]') pt.title('Proatoms for element %s (%i)' % (symbol, number)) pt.legend(loc=0) fn_png = 'dens_%s.png' % suffix pt.savefig(fn_png) if log.do_medium: log('Written', fn_png) # 4*pi*r**2*rho pt.clf() for i, charge in enumerate(charges): record = proatomdb.get_record(number, charge) y = record.rho ls = lss[record.safe] color = get_color(i) label = 'q=%+i' % charge pt.plot(r/angstrom, 4*np.pi*r**2*y, lw=2, ls=ls, label=label, color=color) pt.xlim(0, 3) pt.ylim(ymin=0.0) pt.xlabel('Distance from the nucleus [A]') pt.ylabel('4*pi*r**2*density [Bohr**-1]') pt.title('Proatoms for element %s (%i)' % (symbol, number)) pt.legend(loc=0) fn_png = 'rdens_%s.png' % suffix pt.savefig(fn_png) if log.do_medium: log('Written', fn_png) fukui_data = [] if number - charges[0] == 1: record0 = proatomdb.get_record(number, charges[0]) fukui_data.append((record0.rho, record0.safe, '%+i' % charges[0])) for i, charge in enumerate(charges[1:]): record0 = proatomdb.get_record(number, charge) record1 = proatomdb.get_record(number, charges[i]) fukui_data.append(( record0.rho - record1.rho, record0.safe and record1.safe, '%+i-%+i' % (charge, charges[i]) )) # The Fukui functions pt.clf() for i, (f, safe, label) in enumerate(fukui_data): ls = lss[safe] color = get_color(i) pt.semilogy(r/angstrom, f, lw=2, ls=ls, label=label, color=color, alpha=1.0) pt.semilogy(r/angstrom, -f, lw=2, ls=ls, color=color, alpha=0.2) pt.xlim(0, 3) pt.ylim(ymin=1e-5) pt.xlabel('Distance from the nucleus [A]') pt.ylabel('Fukui function [Bohr**-3]') pt.title('Proatoms for element %s (%i)' % (symbol, number)) pt.legend(loc=0) fn_png = 'fukui_%s.png' % suffix pt.savefig(fn_png) if log.do_medium: log('Written', fn_png) # 4*pi*r**2*Fukui pt.clf() for i, (f, safe, label) in enumerate(fukui_data): ls = lss[safe] color = get_color(i) pt.plot(r/angstrom, 4*np.pi*r**2*f, lw=2, ls=ls, label=label, color=color) pt.xlim(0, 3) pt.xlabel('Distance from the nucleus [A]') pt.ylabel('4*pi*r**2*Fukui [Bohr**-1]') pt.title('Proatoms for element %s (%i)' % (symbol, number)) pt.legend(loc=0) fn_png = 'rfukui_%s.png' % suffix pt.savefig(fn_png) if log.do_medium: log('Written', fn_png)
def write_part_output(fn_h5, grp_name, part, keys, args): '''Write the output of horton-wpart.py or horton-cpart.py **Arguments:** fn_h5 The filename for the HDF5 output file. grp_name the destination group part The partitioning object (instance of subclass of horton.part.base.Part) keys The keys of the cached items that must go in the HDF5 outut file. args The results of the command line parser. All arguments are stored as attributes in the HDF5 output file. ''' def get_results(part, keys): results = {} for key in keys: if isinstance(key, basestring): results[key] = part[key] elif isinstance(key, tuple): assert len(key) == 2 index = key[1] assert isinstance(index, int) assert index >= 0 assert index < part.natom atom_results = results.setdefault('atom_%05i' % index, {}) atom_results[key[0]] = part[key] return results # Store the results in an HDF5 file with LockedH5File(fn_h5) as f: # Transform results to a suitable dictionary structure results = get_results(part, keys) # Store results grp = f.require_group(grp_name) for key in grp.keys(): del grp[key] dump_h5(grp, results) # Store command line arguments store_args(args, grp) if args.debug: # Collect debug results debug_keys = [ key for key in part.cache.iterkeys() if key not in keys ] debug_results = get_results(part, debug_keys) # Store additional data for debugging if 'debug' in grp: del grp['debug'] debuggrp = f.create_group('debug') dump_h5(debuggrp, debug_results) if log.do_medium: log('Results written to %s:%s' % (fn_h5, grp_name))