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 system sys = System.from_file(args.cube) ugrid = sys.grid if not isinstance(ugrid, UniformGrid): raise TypeError( 'The specified file does not contain data on a rectangular grid.') ugrid.pbc[:] = parse_pbc(args.pbc) moldens = sys.extra['cube_data'] # Reduce the grid if required if args.stride > 1 or args.chop > 0: moldens, ugrid = reduce_data(moldens, ugrid, args.stride, args.chop) # Load the proatomdb and make pro-atoms more compact if that is requested proatomdb = ProAtomDB.from_file(args.atoms) if args.compact is not None: proatomdb.compact(args.compact) proatomdb.normalize() # Select the partitioning scheme CPartClass = cpart_schemes[args.scheme] # List of element numbers for which weight corrections are needed: wcor_numbers = list(iter_elements(args.wcor)) # Run the partitioning kwargs = dict((key, val) for key, val in vars(args).iteritems() if key in CPartClass.options) cpart = cpart_schemes[args.scheme](sys, ugrid, True, moldens, proatomdb, wcor_numbers, args.wcor_rcut_max, args.wcor_rcond, **kwargs) names = cpart.do_all() # Do a symmetry analysis if requested. if args.symmetry is not None: sys_sym = System.from_file(args.symmetry) sym = sys_sym.extra.get('symmetry') if sym is None: raise ValueError('No symmetry information found in %s.' % args.symmetry) sys_results = dict((name, cpart[name]) for name in names) sym_results = symmetry_analysis(sys, sym, sys_results) cpart.cache.dump('symmetry', sym_results) names.append('symmetry') sys.extra['symmetry'] = sym write_part_output(fn_h5, grp_name, cpart, names, 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 system sys = System.from_file(args.cube) ugrid = sys.grid if not isinstance(ugrid, UniformGrid): raise TypeError('The specified file does not contain data on a rectangular grid.') ugrid.pbc[:] = parse_pbc(args.pbc) moldens = sys.extra['cube_data'] # Reduce the grid if required if args.stride > 1 or args.chop > 0: moldens, ugrid = reduce_data(moldens, ugrid, args.stride, args.chop) # Load the proatomdb and make pro-atoms more compact if that is requested proatomdb = ProAtomDB.from_file(args.atoms) if args.compact is not None: proatomdb.compact(args.compact) proatomdb.normalize() # Select the partitioning scheme CPartClass = cpart_schemes[args.scheme] # List of element numbers for which weight corrections are needed: wcor_numbers = list(iter_elements(args.wcor)) # Run the partitioning kwargs = dict((key, val) for key, val in vars(args).iteritems() if key in CPartClass.options) cpart = cpart_schemes[args.scheme]( sys, ugrid, True, moldens, proatomdb, wcor_numbers, args.wcor_rcut_max, args.wcor_rcond, **kwargs) names = cpart.do_all() # Do a symmetry analysis if requested. if args.symmetry is not None: sys_sym = System.from_file(args.symmetry) sym = sys_sym.extra.get('symmetry') if sym is None: raise ValueError('No symmetry information found in %s.' % args.symmetry) sys_results = dict((name, cpart[name]) for name in names) sym_results = symmetry_analysis(sys, sym, sys_results) cpart.cache.dump('symmetry', sym_results) names.append('symmetry') sys.extra['symmetry'] = sym write_part_output(fn_h5, grp_name, cpart, names, args)
def load_rho(coordinates, numbers, fn_cube, ref_ugrid, stride, chop): '''Load densities from a file, reduce by stride, chop and check ugrid **Arguments:** coordinates An array with shape (N, 3) containing atomic coordinates. numbers A vector with shape (N,) containing atomic numbers. fn_cube The cube file with the electron density. ref_ugrid A reference ugrid that must match the one from the density cube file (after reduction). stride The reduction factor. chop The number of slices to chop of the grid in each direction. ''' if fn_cube is None: # Load the built-in database of proatoms natom = len(numbers) numbers = np.unique(numbers) proatomdb = ProAtomDB.from_refatoms(numbers, max_kation=0, max_anion=0, agspec='fine') # Construct the pro-density rho = np.zeros(ref_ugrid.shape) for i in xrange(natom): spline = proatomdb.get_spline(numbers[i]) ref_ugrid.eval_spline(spline, coordinates[i], rho) else: # Load cube mol_rho = IOData.from_file(fn_cube) rho = mol_rho.cube_data ugrid = mol_rho.grid # Reduce grid size if stride > 1: rho, ugrid = reduce_data(rho, ugrid, stride, chop) # Compare with ref_ugrid (only shape) if (ugrid.shape != ref_ugrid.shape).any(): raise ValueError( 'The densities file does not contain the same amount if information as the potential file.' ) return rho
def load_rho(system, fn_cube, ref_ugrid, stride, chop): '''Load densities from a file, reduce by stride, chop and check ugrid **Arguments:** system A Horton system object for the current system. This is only used to construct the pro-density. fn_cube The cube file with the electron density. ref_ugrid A reference ugrid that must match the one from the density cube file (after reduction). stride The reduction factor. chop The number of slices to chop of the grid in each direction. ''' if fn_cube is None: # Load the built-in database of proatoms numbers = np.unique(system.numbers) proatomdb = ProAtomDB.from_refatoms(numbers, max_kation=0, max_anion=0, agspec='fine') # Construct the pro-density rho = np.zeros(ref_ugrid.shape) for i in xrange(system.natom): spline = proatomdb.get_spline(system.numbers[i]) ref_ugrid.eval_spline(spline, system.coordinates[i], rho) else: # Load cube sys = System.from_file(fn_cube) rho = sys.extra['cube_data'] ugrid = sys.grid # Reduce grid size if stride > 1: rho, ugrid = reduce_data(rho, ugrid, stride, chop) # Compare with ref_ugrid (only shape) if (ugrid.shape != ref_ugrid.shape).any(): raise ValueError( 'The densities file does not contain the same amount if information as the potential file.' ) return rho
def load_rho(coordinates, numbers, fn_cube, ref_ugrid, stride, chop): '''Load densities from a file, reduce by stride, chop and check ugrid **Arguments:** coordinates An array with shape (N, 3) containing atomic coordinates. numbers A vector with shape (N,) containing atomic numbers. fn_cube The cube file with the electron density. ref_ugrid A reference ugrid that must match the one from the density cube file (after reduction). stride The reduction factor. chop The number of slices to chop of the grid in each direction. ''' if fn_cube is None: # Load the built-in database of proatoms natom = len(numbers) numbers = np.unique(numbers) proatomdb = ProAtomDB.from_refatoms(numbers, max_cation=0, max_anion=0, agspec='fine') # Construct the pro-density rho = np.zeros(ref_ugrid.shape) for i in xrange(natom): spline = proatomdb.get_spline(numbers[i]) ref_ugrid.eval_spline(spline, coordinates[i], rho) else: # Load cube mol_rho = IOData.from_file(fn_cube) rho = mol_rho.cube_data ugrid = mol_rho.grid # Reduce grid size if stride > 1: rho, ugrid = reduce_data(rho, ugrid, stride, chop) # Compare with ref_ugrid (only shape) if (ugrid.shape != ref_ugrid.shape).any(): raise ValueError('The densities file does not contain the same amount if information as the potential file.') return rho
def load_rho(system, fn_cube, ref_ugrid, stride, chop): '''Load densities from a file, reduce by stride, chop and check ugrid **Arguments:** system A Horton system object for the current system. This is only used to construct the pro-density. fn_cube The cube file with the electron density. ref_ugrid A reference ugrid that must match the one from the density cube file (after reduction). stride The reduction factor. chop The number of slices to chop of the grid in each direction. ''' if fn_cube is None: # Load the built-in database of proatoms numbers = np.unique(system.numbers) proatomdb = ProAtomDB.from_refatoms(numbers, max_kation=0, max_anion=0, agspec='fine') # Construct the pro-density rho = np.zeros(ref_ugrid.shape) for i in xrange(system.natom): spline = proatomdb.get_spline(system.numbers[i]) ref_ugrid.eval_spline(spline, system.coordinates[i], rho) else: # Load cube sys = System.from_file(fn_cube) rho = sys.extra['cube_data'] ugrid = sys.grid # Reduce grid size if stride > 1: rho, ugrid = reduce_data(rho, ugrid, stride, chop) # Compare with ref_ugrid (only shape) if (ugrid.shape != ref_ugrid.shape).any(): raise ValueError('The densities file does not contain the same amount if information as the potential file.') return rho
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 IOData mol = IOData.from_file(args.cube) ugrid = mol.grid if not isinstance(ugrid, UniformGrid): raise TypeError('The density cube file does not contain data on a rectangular grid.') ugrid.pbc[:] = parse_pbc(args.pbc) moldens = mol.cube_data # Reduce the grid if required if args.stride > 1 or args.chop > 0: moldens, ugrid = reduce_data(moldens, ugrid, args.stride, args.chop) # Load the spin density (optional) if args.spindens is not None: molspin = IOData.from_file(args.spindens) if not isinstance(molspin.grid, UniformGrid): raise TypeError('The spin cube file does not contain data on a rectangular grid.') spindens = molspin.cube_data if args.stride > 1 or args.chop > 0: spindens = reduce_data(spindens, molspin.grid, args.stride, args.chop)[0] if spindens.shape != moldens.shape: raise TypeError('The shape of the spin cube does not match the shape of the density cube.') else: spindens = None # Load the proatomdb and make pro-atoms more compact if that is requested proatomdb = ProAtomDB.from_file(args.atoms) if args.compact is not None: proatomdb.compact(args.compact) proatomdb.normalize() # Select the partitioning scheme CPartClass = cpart_schemes[args.scheme] # List of element numbers for which weight corrections are needed: if args.wcor == '0': wcor_numbers = [] else: wcor_numbers = list(iter_elements(args.wcor)) # Run the partitioning kwargs = dict((key, val) for key, val in vars(args).iteritems() if key in CPartClass.options) cpart = cpart_schemes[args.scheme]( mol.coordinates, mol.numbers, mol.pseudo_numbers, ugrid, moldens, proatomdb, spindens=spindens, local=True, wcor_numbers=wcor_numbers, wcor_rcut_max=args.wcor_rcut_max, wcor_rcond=args.wcor_rcond, **kwargs) keys = cpart.do_all() # Do a symmetry analysis if requested. if args.symmetry is not None: mol_sym = IOData.from_file(args.symmetry) if not hasattr(mol_sym, 'symmetry'): raise ValueError('No symmetry information found in %s.' % args.symmetry) aim_results = dict((key, cpart[key]) for key in keys) sym_results = symmetry_analysis(mol.coordinates, ugrid.get_cell(), mol_sym.symmetry, aim_results) cpart.cache.dump('symmetry', sym_results) keys.append('symmetry') write_part_output(fn_h5, grp_name, cpart, keys, args)