def convert(name, opts): con1 = connect(name, use_lock_file=False) con1._allow_reading_old_format = True newname = name[:-2] + 'new.db' with connect(newname, create_indices=False, use_lock_file=False) as con2: row = None for row in con1.select(): kvp = row.get('key_value_pairs', {}) if opts.convert_strings_to_numbers: for key, value in kvp.items(): if isinstance(value, basestring): try: value = float(value) except ValueError: pass else: kvp[key] = value if opts.convert_minus_to_not_a_number: for key, value in kvp.items(): if value == '-': kvp[key] = np.nan con2.write(row, data=row.get('data'), **kvp) assert row is not None, 'Your database is empty!' c = con2._connect() for statement in index_statements: c.execute(statement) c.commit() os.rename(name, name[:-2] + 'old.db') os.rename(newname, name)
def produce_trainset(database, fraction=0.9, seed=256): """Produce a train.db database for training """ db = connect(database) n = db.count() n_train = int(round(n * fraction)) n_ids = np.array(range(n)) + 1 # This will sudo-randomly select 10% of the calculations # Which is useful for reproducing our results. random.seed(seed) train_samples = random.sample(n_ids, n_train) valid_samples = set(n_ids) - set(train_samples) db.update(list(train_samples), train_set=True) db.update(list(valid_samples), train_set=False) parent = '/'.join(database.split('/')[:-1]) db0 = connect(parent + '/train.db') for d in db.select(['train_set=True']): db0.write(d, key_value_pairs=d.key_value_pairs)
def build(self, name): if name == '-': con = db.connect(sys.stdin, 'json') return con.get_atoms(add_additional_information=True) elif self.args.collection: con = db.connect(self.args.collection) return con.get_atoms(name) else: return read(name)
def db_duplicates(db_path, delete=False, reverse=False, silent=False): """Return duplicate IDs based on calculation paths.""" db = connect(db_path) old_size = sum(1 for _ in db.select()) db_paths = {} for d in db.select(): try: db_paths[d.id] = d.data.path except: pass keep = {} items = reversed(db_paths.items()) if reverse else db_paths.items() for key, value in items: if value not in keep.values(): keep[key] = value dup_keys = [] for key in db_paths.keys(): if key not in keep: if not silent: print("Duplicate: id={}: value={}".format(key, db_paths[key])) dup_keys.append(key) if delete: db.delete(dup_keys) new_size = sum(1 for _ in db.select()) deleted = old_size - new_size if not silent: print("{} total entries. {} duplicate entries. {} deleted.".format(new_size, len(dup_keys), deleted)) return dup_keys
def db_conv_analysis(database, defaults, base=[]): """Analysis tools for json database: outputs an (n x n) ndarray, where n is the number of defaults specified""" db = connect(database) V, E, T = [], [], [] for i, v in enumerate(defaults): var, nrg, time = [], [], [] # Search for each variable, maintaining specified defaults search = np.delete(defaults, i) data = db.select(base + search) for d in data: var.append(d.key_value_pairs[v.split("=")[0]]) nrg.append(d.key_value_pairs["total_energy"]) time.append(d.key_value_pairs["calc_time"]) # Sort the data sort = np.argsort(var) var = np.array(var)[sort] nrg = np.array(nrg)[sort] time = np.array(time)[sort] V.append(var) E.append(nrg) T.append(time) return V, E, T
def read_from_db(db, names=None, eref=None): if isinstance(db, str): db = connect(db) elif not isinstance(db, Database): raise ValueError("Must pass active ASE DB connection, " "or name of ASE DB file!") species = {} for row in db.select(): name = row.name try: species[name] = row_to_thermo(row) except MickiDBReadError: print("Could not parse row {}, skipping.".format(name)) for name, sp in species.items(): newsites = [] for site in sp.sites: if site in species: newsites.append(species[site]) else: raise ValueError("Unknown site named {}!".format(site)) sp.sites = newsites if eref is not None: reference = EnergyReference([species[name] for name in eref]) for name, sp in species.items(): sp.eref = reference if names is not None: return {name: species[name] for name in names} return species
def convert(name): con1 = connect(name, use_lock_file=False) con1._allow_reading_old_format = True newname = name[:-2] + 'new.db' with connect(newname, create_indices=False, use_lock_file=False) as con2: for dct in con1.select(): kvp = dct.get('key_value_pairs', {}) con2.write(dct, data=dct.get('data'), **kvp) c = con2._connect() for statement in index_statements: c.execute(statement) c.commit() os.rename(name, name[:-2] + 'old.db') os.rename(newname, name)
def _flush(self, *args, **kwargs): data = dict(('{0}{1}'.format(self._value_prefix, i), v) for i, v in enumerate(args)) try: atomsi = [isinstance(v, ase.Atoms) for v in args].index(True) atoms = args[atomsi] del data['{0}{1}'.format(self._value_prefix, atomsi)] except ValueError: atomsi = -1 try: atoms = kwargs['atoms'] except: raise RuntimeError('No atoms object provided in arguments.') try: del kwargs['atoms'] except: pass data['checkpoint_atoms_args_index'] = atomsi data.update(kwargs) with connect(self.db) as db: try: dbentry = db.get(checkpoint_id=self._mangled_checkpoint_id()) del db[dbentry.id] except KeyError: pass db.write(atoms, checkpoint_id=self._mangled_checkpoint_id(), data=data) self.logger.pr('Successfully stored checkpoint ' '{0}.'.format(self.checkpoint_id))
def run(self, names): opts = self.opts if self.db is None: # Create database connection: self.db = db.connect(opts.database, use_lock_file=True) self.expand(names) if not names: names.insert(0, '-') atoms = None for name in names: if atoms is not None: del atoms.calc # release resources from last calculation atoms = self.build(name) if opts.modify: exec opts.modify in {'atoms': atoms, 'np': np} if name == '-': name = atoms.info['key_value_pairs']['name'] skip = False id = None if opts.skip: id = self.db.reserve(name=name) if id is None: skip = True if not skip: self.set_calculator(atoms, name) tstart = time.time() try: self.log('Running:', name) data = self.calculate(atoms, name) except KeyboardInterrupt: raise except Exception: self.log(name, 'FAILED') traceback.print_exc(file=self.logfile) tstop = time.time() data = {'time': tstop - tstart} self.db.write(None, ['failed'], name=name, data=data) self.errors += 1 else: tstop = time.time() data['time'] = tstop - tstart self.db.write(atoms, name=name, data=data) if id: del self.db[id] return atoms
def relax(input_atoms, ref_db): atoms_string = input_atoms.get_chemical_symbols() # Open connection to the database with reference data db = connect(ref_db) # Load our model structure which is just FCC atoms = FaceCenteredCubic('X', latticeconstant=1.) atoms.set_chemical_symbols(atoms_string) # Compute the average lattice constant of the metals in this individual # and the sum of energies of the constituent metals in the fcc lattice # we will need this for calculating the heat of formation a = 0 ei = 0 for m in set(atoms_string): dct = db.get(metal=m) count = atoms_string.count(m) a += count * dct.latticeconstant ei += count * dct.energy_per_atom a /= len(atoms_string) atoms.set_cell([a, a, a], scale_atoms=True) # Since calculations are extremely fast with EMT we can also do a volume # relaxation atoms.set_calculator(EMT()) eps = 0.05 volumes = (a * np.linspace(1 - eps, 1 + eps, 9))**3 energies = [] for v in volumes: atoms.set_cell([v**(1. / 3)] * 3, scale_atoms=True) energies.append(atoms.get_potential_energy()) eos = EquationOfState(volumes, energies) v1, ef, B = eos.fit() latticeconstant = v1**(1. / 3) # Calculate the heat of formation by subtracting ef with ei hof = (ef - ei) / len(atoms) # Place the calculated parameters in the info dictionary of the # input_atoms object input_atoms.info['key_value_pairs']['hof'] = hof # Raw score must always be set # Use one of the following two; they are equivalent input_atoms.info['key_value_pairs']['raw_score'] = -hof # set_raw_score(input_atoms, -hof) input_atoms.info['key_value_pairs']['latticeconstant'] = latticeconstant # Setting the atoms_string directly for easier analysis atoms_string = ''.join(input_atoms.get_chemical_symbols()) input_atoms.info['key_value_pairs']['atoms_string'] = atoms_string
def add_to_db(self, dbfile, tags=()): '''add calculation to dbfile with extra tags. No check for duplicate entries. ''' atoms = self.get_atoms() self.results['energy'] = atoms.get_potential_energy() self.results['forces'] = atoms.get_forces(apply_constraint=False) from ase.db import connect c = connect(dbfile) return c.write(atoms, tags)
def get_zpe(dir, job, ts, high_level, mp2=0): db = connect(dir + '/kinbot.db') if ts: j = job else: j = job + '_well' if mp2: j += '_mp2' if high_level: j += '_high' rows = db.select(name=j) for row in rows: if hasattr(row, 'data'): zpe = row.data.get('zpe') return zpe
def test0(): atoms = Atoms([Atom('O', [4, 5, 5], magmom=1), Atom('C', [5, 5, 5], magmom=2), Atom('O', [6, 5, 5], magmom=3)], cell=(10, 10, 10)) calc = Vasp('vasp', sigma=0.01, atoms=atoms) calc.write_db(fname='DB.db', append=False) with connect('DB.db') as con: data = con.get(1).data assert data['parameters']['sigma'] == 0.01 print 'done'
def db_update(db_path, dft_path, delete=False, silent=False): """Update the database to include Vasp() calculations nested in dft_path.""" VASPRC['mode'] = None db = connect(db_path) old_size = sum(1 for _ in db.select()) db_paths = [] for d in db.select(): try: db_paths.append(d.data.path) except: pass for path in utils.calc_paths(dft_path): if os.path.abspath(path) in db_paths: continue calc = Vasp(path) if not calc.in_queue() and calc.potential_energy is None: for output_file in utils.calc_output_files(path): dead_file = os.path.join(path, output_file) if delete: os.remove(dead_file) if not silent: print("Dead output file: {}. Deleted: {}".format(dead_file, delete)) else: ctime = calc.get_elapsed_time() # The write_db method throws an AttributeError for new calcs. Remove this to debug. old_stdout = sys.stdout sys.stdout = open(os.devnull, "w") calc.write_db(db_path, parser='=', overwrite=False, data={'ctime': ctime}) sys.stdout.close() sys.stdout = old_stdout if not silent: print("Added calc to DB: {}".format(path)) new_size = sum(1 for _ in db.select()) added = new_size - old_size if not silent: print("{} total entries. {} new entries added.".format(new_size, added))
def expand(self, names): if not self.names and self.args.collection: con = db.connect(self.args.collection) self.names = [dct.id for dct in con.select()] if not names: names[:] = self.names return if not self.names: return i = 0 while i < len(names): name = names[i] if name.count('-') == 1: s1, s2 = name.split('-') if s1 in self.names and s2 in self.names: j1 = self.names.index(s1) j2 = self.names.index(s2) names[i:i + 1] = self.names[j1:j2 + 1] i += j2 - j1 i += 1
def save_dataset(dbpath, dataset, overwrite=False): """ Write dataset instance to ase-db file. Args: dbpath (str): path to the new database dataset (spk.data.ConcatAtomsData or spk.data.AtomsDataSubset): dataset instance to be stored overwrite (bool): overwrite existing database """ # check if path exists if os.path.exists(dbpath): if overwrite: os.remove(dbpath) raise AtomsDataError( "The selected dbpath does already exist. Set overwrite=True or change " "dbpath.") # build metadata metadata = dict() metadata["atomref"] = dataset.atomref metadata["available_properties"] = dataset.available_properties # write dataset with connect(dbpath) as conn: # write metadata conn.metadata = metadata # write datapoints for idx in range(len(dataset)): atms, data = dataset.get_properties(idx) # filter available properties data_clean = dict() for pname, prop in data.items(): if pname.startswith("_"): continue if pname in dataset.available_properties: data_clean[pname] = prop conn.write(atms, data=data_clean)
def get_properties(self, idx): idx = self._subset_index(idx) with connect(self.dbpath) as conn: row = conn.get(idx + 1) at = row.toatoms() # extract properties properties = {} for pname in self.required_properties: # new data format try: shape = row.data['_shape_' + pname] dtype = row.data['_dtype_' + pname] prop = np.frombuffer(b64decode(row.data[pname]), dtype=dtype) prop = prop.reshape(shape) except: # fallback # Capture exception for ISO17 where energies are stored directly # in the row if pname in row: prop = row[pname] else: prop = row.data[pname] try: prop.shape except AttributeError as e: prop = np.array([prop], dtype=np.float32) properties[pname] = torch.FloatTensor(prop) # extract/calculate structure properties[Structure.Z] = torch.LongTensor(at.numbers.astype(np.int)) positions = at.positions.astype(np.float32) if self.centered: positions -= at.get_center_of_mass() properties[Structure.R] = torch.FloatTensor(positions) properties[Structure.cell] = torch.FloatTensor( at.cell.astype(np.float32)) return at, properties
def get_properties(self, idx): idx = self._subset_index(idx) with connect(self.dbpath) as conn: row = conn.get(idx + 1) at = row.toatoms() # extract properties properties = {} for pname in self.load_only: # new data format try: shape = row.data["_shape_" + pname] dtype = row.data["_dtype_" + pname] prop = np.frombuffer(b64decode(row.data[pname]), dtype=dtype) prop = prop.reshape(shape) except: # fallback for properties stored directly # in the row if pname in row: prop = row[pname] else: prop = row.data[pname] try: prop.shape except AttributeError as e: prop = np.array([prop], dtype=np.float32) properties[pname] = torch.FloatTensor(prop) # extract/calculate structure properties = _convert_atoms( at, environment_provider=self.environment_provider, collect_triples=self.collect_triples, center_positions=self.center_positions, output=properties, ) return at, properties
def load(self, atoms=None): """ Retrieve checkpoint data from file. If atoms object is specified, then the calculator connected to that object is copied to all returning atoms object. Returns tuple of values as passed to flush or save during checkpoint write. """ self._increase_checkpoint_id() retvals = [] with connect(self.db) as db: try: dbentry = db.get(checkpoint_id=self._mangled_checkpoint_id()) except KeyError: raise NoCheckpoint data = dbentry.data atomsi = data['checkpoint_atoms_args_index'] i = 0 while i == atomsi or \ '{0}{1}'.format(self._value_prefix, i) in data: if i == atomsi: newatoms = dbentry.toatoms() if atoms is not None: # Assign calculator newatoms.set_calculator(atoms.get_calculator()) retvals += [newatoms] else: retvals += [data['{0}{1}'.format(self._value_prefix, i)]] i += 1 self.logger.pr('Successfully restored checkpoint ' '{0}.'.format(self.checkpoint_id)) self._decrease_checkpoint_id() if len(retvals) == 1: return retvals[0] else: return tuple(retvals)
def get_atoms(self, atomID, eci): """ Returns an instance of the atoms object requested """ db = connect(self.wl_db_name) row = db.get(id=atomID) bcfname = row.key_value_pairs["bcfile"] init_cf = row.data["cf"] try: with open(bcfname, 'rb') as infile: bc = pck.load(infile) calc = CE(bc, eci, initial_cf=init_cf) bc.atoms.set_calculator(calc) return bc.atoms except IOError as exc: print(str(exc)) print("Will try to recover the CEBulk object") bc_kwargs = row.data["bc_kwargs"] cetype = row.key_value_pairs["cetype"] if (cetype == "CEBulk"): small_bc = CEBulk(**bc_kwargs) small_bc.reconfigure_settings() else: small_bc = CECrystal(**bc_kwargs) small_bc.reconfigure_settings() size = row.data["supercell_size"] calc = get_ce_calc(small_bc, bc_kwargs, eci=eci, size=size) # Determine the composition count = row.count_atoms() for key in count.keys(): count /= float(row.natoms) calc.set_composition(count) bc = calc.BC bc.atoms.set_calculator(calc) return bc.atoms except: raise RuntimeError( "Did not manage to return the atoms object with the proper calculator attached..." )
def main(): db = connect(db_name) init_energy = [] relaxed_energy = [] for row in db.select([("converged", "=", 1)]): relaxed_energy.append(row.energy / row.natoms) init_energy.append(row.init_energy / row.natoms) init_energy = np.array(init_energy) relax_energy = np.array(relaxed_energy) diff = relax_energy - init_energy hist, bins = np.histogram(diff * 1000.0, bins="auto") print(bins) fig = plt.figure() ax = fig.add_subplot(1, 1, 1) ax.bar(bins[1:], hist, 0.4) ax.set_xlabel("Relaxation energy (meV/atom)") ax.set_ylabel("Number of configurations") ax.spines["right"].set_visible(False) ax.spines["top"].set_visible(False) plt.show()
def at_timestamp(self, timestamp): """ Returns a new dataset that only consists of items created before the given timestamp. Args: timestamp (str): timestamp Returns: schnetpack.datasets.matproj.MaterialsProject: dataset with subset of original data """ with connect(self.dbpath) as conn: rows = conn.select(columns=['id', 'key_value_pairs']) idxs = [] timestamps = [] for row in rows: idxs.append(row.id - 1) timestamps.append(row.key_value_pairs["created_at"]) idxs = np.array(idxs) timestamps = np.array(timestamps) return self.create_subset(idxs[timestamps <= timestamp])
def conc_and_energies(db_name, ref_al, ref_mg): db = connect(db_name) energies = [] conc = [] for row in db.select(converged=True): energies.append(row.energy/row.natoms) count = row.count_atoms() if "Al" not in count.keys(): count["Al"] = 0.0 if "Mg" not in count.keys(): count["Mg"] = 0.0 for k in count.keys(): count[k] /= float(row.natoms) conc.append(count) enthalp_form = [] mg_conc = [] for c, eng in zip(conc, energies): dE = eng - ref_al*c["Al"]- ref_mg*c["Mg"] enthalp_form.append(dE*mol/kJ) mg_conc.append(c["Mg"]) return mg_conc, enthalp_form
def create_plt(database): db = connect(database) for outer_obj in db.select(): obj = outer_obj['data'] q = obj['q'] Q = obj['Q'] omega_kn = obj['omega_kn'] point_names = obj['point_names'] dos_e = obj['dos_e'] omega_e = obj['omega_e'] plt.figure(1, (8, 6)) plt.axes([.1, .07, .67, .85]) for n in range(len(omega_kn[0])): omega_n = omega_kn[:, n] plt.plot(q, omega_n, 'k-', lw=2) plt.xticks(Q, point_names, fontsize=18) plt.yticks(fontsize=18) plt.xlim(q[0], q[-1]) plt.ylim(0, 40) plt.ylabel("Energy ($\mathrm{meV}$)", fontsize=22) plt.grid('on') plt.axes([.8, .07, .17, .85]) plt.fill_between(dos_e, omega_e, y2=0, color='lightgrey', edgecolor='k', lw=1) plt.ylim(0, 40) plt.xticks([], []) plt.yticks([], []) plt.xlabel("DOS", fontsize=18) plt.show()
def generate_training_set(individual, db_name): """ Do MD using EMT calculator with each slab for 10 steps and add it to train.db """ db = connect(db_name) for miller_indices in individual: # Do MD slab = generate_slab(miller_indices, 5) slab = make_supercell(slab, P=[[3, 1, 1], [1, 3, 1], [1, 1, 1]]) slab.set_calculator(EMT()) slab.get_potential_energy() db.write(slab) MaxwellBoltzmannDistribution(slab, 300. * units.kB) dyn = VelocityVerlet(slab, dt=1. * units.fs) for i in range(1, 10): dyn.run(10) db.write(slab)
def __init__( self, substrate = None, gadb = None, popSize = 20, zLim = None, subsPot = 0, chemPotDict = None, compParam = None, matingMethod = None, convergeCrit = None, ): if gadb is not None: self.gadb = connect(gadb) if type(substrate) is str: self.substrate = read(substrate) else: self.substrate = substrate if zLim is not None: self.zLim = zLim if zLim is None: self.zLim = Interface(self.substrate, self.substrate).zLim self.popSize = popSize if convergeCrit is None: self.convergeCrit = 5 * self.popSize else: self.convergeCrit = convergeCrit self.subsPot = subsPot if chemPotDict is not None: self.chemPotDict = chemPotDict self.iniSize = len(self)
def add_metadata(self): """ Due to an issue with some versions of ASE, this method will write metadata to the ASE database, if a database is being used to store cluster information. """ if self.have_database: metadata = {} metadata['title'] = str(self.name) metadata['default_columns'] = ['name', 'cluster_energy', 'id'] # ---------------------------------------------------- metadata['key_descriptions'] = {} metadata['key_descriptions']['name'] = ('Name', 'Name of the cluster.', '') metadata['key_descriptions']['gen_made'] = ( 'Generation Created', 'The generation the cluster was created.', '') metadata['key_descriptions']['cluster_energy'] = ( 'Cluster Energy', 'Potential energy of the cluster.', 'energy_units') metadata['key_descriptions']['ever_in_population'] = ( 'ever_in_population', 'This variable indicates if the cluster was ever in the population. If an offspring was made and was not ever accepted into the population, this variable will be False. If the cluster had been in the population for even one generation, this variable will be True.', 'bool') metadata['key_descriptions'][ 'excluded_because_violates_predation_operator'] = ( 'excluded_because_violates_predation_operator', 'This variable will determine if a cluster was excluded from the population because it violated the predation operator.', 'bool') metadata['key_descriptions']['initial_population'] = ( 'initial_population', 'This variable will indicate if the cluster was apart of a newly created population.', 'bool') metadata['key_descriptions']['removed_by_memory_operator'] = ( 'removed_by_memory_operator', 'This variable will indicate if a cluster is removed because it resembles a cluster in the memory operator.', 'bool') # ---------------------------------------------------- with connect(self.database_path) as database: database.metadata = metadata.copy() database._metadata = metadata.copy()
def __init__(self, asedb, kvp={}, data={}, batch_size=1, selection=None, shuffle=True, prefetch=False, block_size=150000, capacity=5000, num_epochs=np.Inf, floatX=np.float32): super(ASEDataProvider, self).__init__(batch_size) self.asedb = asedb self.prefetch = prefetch self.selection = selection self.block_size = block_size self.shuffle = shuffle self.kvp = kvp self.data = data self.floatX = floatX self.feat_names = ['numbers', 'positions', 'cell', 'pbc'] + list(kvp.keys()) + list(data.keys()) self.shapes = [(None,), (None, 3), (3, 3), (3,)] + list(kvp.values()) + list(data.values()) self.epoch = 0 self.num_epochs = num_epochs self.n_rows = 0 # initialize queue with connect(self.asedb) as con: row = list(con.select(self.selection, limit=1))[0] feats = self.convert_atoms(row) dtypes = [np.array(feat).dtype for feat in feats] self.queue = tf.FIFOQueue(capacity, dtypes) self.placeholders = [ tf.placeholder(dt, name=name) for dt, name in zip(dtypes, self.feat_names) ] self.enqueue_op = self.queue.enqueue(self.placeholders) self.dequeue_op = self.queue.dequeue() self.preprocs = []
def create_database(): """ Database containing different type of structures used for testing. Some tests may use partially the following database. """ db = connect('structures_for_testing.db', append=False) """ FCC (single element, primitive cell, pbc=True) """ structure = bulk('Al', 'fcc', a=1.0) db.write(structure, tag='Al-fcc-primitive_cell') """ FCC (single element, supercell, pbc=True) """ structure = bulk('Al', 'fcc', a=1.0).repeat(2) db.write(structure, tag='Al-fcc-supercell') """ FCC (single element, distorted structure, pbc=True) """ structure = bulk('Al', 'fcc', a=1.0).repeat(2) structure.rattle(stdev=0.001, seed=42) db.write(structure, tag='Al-fcc-distorted') """ BCC (two elements, cubic structure, pbc=True) """ structure = bulk('Ti', 'bcc', a=1.0).repeat(2) for atom in structure: if atom.index % 2 == 0: atom.symbol = 'W' db.write(structure, tag='WTi-bcc-supercell') """ rocksalt (two elements, cubic structure) """ structure = bulk('NaCl', 'rocksalt', a=1.0) db.write(structure, tag='NaCl-rocksalt-cubic-cell') """ HCP (single element, hexagonal structure) """ structure = bulk('Ni', 'hcp', a=0.625, c=1.0) db.write(structure, tag='Ni-hcp-hexagonal-cell') """ perovskite (three elements, cubic structure) """ a = 1.0 b = 0.5 * a structure = Atoms('BaZrO3', positions=[(0, 0, 0), (b, b, b), (b, b, 0), (b, 0, b), (0, b, b)], cell=[a, a, a], pbc=True) db.write(structure, tag='BaZrO3-perovskite')
def run(args, parser): if args.vacuum0: parser.error('Please use -V or --vacuum instead!') if '.' in args.name: # Read from file: atoms = read(args.name) elif args.crystal_structure: atoms = build_bulk(args) else: atoms = build_molecule(args) if args.magnetic_moment: magmoms = np.array( [float(m) for m in args.magnetic_moment.split(',')]) atoms.set_initial_magnetic_moments( np.tile(magmoms, len(atoms) // len(magmoms))) if args.modify: exec(args.modify, {'atoms': atoms}) if args.repeat is not None: r = args.repeat.split(',') if len(r) == 1: r = 3 * r atoms = atoms.repeat([int(c) for c in r]) if args.gui: view(atoms) if args.output: write(args.output, atoms) elif sys.stdout.isatty(): write(args.name + '.json', atoms) else: con = connect(sys.stdout, type='json') con.write(atoms, name=args.name)
def read_params(self): """ Reads the entries from a database """ conn = sq.connect(self.db_name) cur = conn.cursor() cur.execute( "SELECT fmin,current_f,initial_f,queued,initialized,atomID,n_iter from simulations where uid=?", (self.db_id, )) entries = cur.fetchone() conn.close() #self.fmin = float( entries[0] ) self.f = float(entries[1]) self.f0 = float(entries[2]) queued = entries[3] self.initialized = entries[4] atomID = int(entries[5]) self.iter = int(entries[6]) db = connect(self.db_name) row = db.get(id=atomID) formula = row.formula if (formula != self.atoms.get_chemical_formula()): msg = "The chemical formula of the structure provided does not match the one in the database. " msg += "Provided: {}. In database: {}".format( formula, self.atoms.get_chemical_formula()) raise ValueError(msg) self.histogram.load(self.db_name, self.db_id) try: row = db.get(id=atomID) elms = row.data.elements chem_pot = row.data.chemical_potentials self.chem_pot = dict(zip(elms, chem_pot)) except Exception as exc: self.logger.warning(str(exc))
def prepare_random_structures(): db = connect('FeSi_27atoms_initial.db') added_to_db = 0 while added_to_db < 10: atoms = bulk('Fe', 'bcc', a = 2.876)*(3,3,3) atom_config = prepare_random_structure() num_si = 0 while num_si < atom_config[1]: for atom in atoms: if atom.symbol != 'Si' and randint(0,10)/10 <= atom_config[1]/27: atom.symbol = 'Si' num_si += 1 if not exists_in_db(atoms): db.write(atoms, struct_type = 'initial') added_to_db += 1 added_to_db = 0 while added_to_db < 20: atoms = bulk('Fe', 'bcc', a = 2.876)*(3,3,3) max_si = randint(13,14) print(max_si) num_si = 0 while num_si < max_si: for atom in atoms: if atom.symbol != 'Si' and randint(0,10)/10 <= 0.5 and num_si < max_si: atom.symbol = 'Si' num_si += 1 if not exists_in_db(atoms): db.write(atoms, struct_type = 'initial') added_to_db += 1
def add_systems(self, atoms_list, property_list=None, key_value_pairs_list=None): """ Add atoms data to the dataset. Args: atoms_list (list of ase.Atoms): system composition and geometry property_list (list): Properties as list of key-value pairs in the same order as corresponding list of `atoms`. Keys have to match the `available_properties` of the dataset. """ # build empty dicts if property/kv_pairs list is None if property_list is None: property_list = [dict() for _ in range(len(atoms_list))] if key_value_pairs_list is None: key_value_pairs_list = [dict() for _ in range(len(atoms_list))] # write systems to database with connect(self.dbpath) as conn: for at, prop, kv_pair in zip( atoms_list, property_list, key_value_pairs_list ): self._add_system(conn, at, prop, kv_pair)
def get_generations(self): """ Compute the CV score and RMSE error """ db = connect(self.setting.db_name) select_cond = [("converged", "=", "1")] if (self.select_cond is not None): select_cond += self.select_cond all_generations = [] for row in db.select(select_cond): try: gen = row["gen"] except KeyError as exc: print(str(exc)) continue if (gen not in all_generations): all_generations.append(gen) all_generations.sort() print("Generations: {}".format(all_generations)) del all_generations[0] return all_generations
def __init__(self,par): self.par = par self.qc = par.par['qc'] self.method = par.par['method'] self.basis = par.par['basis'] self.high_level_method = par.par['high_level_method'] self.high_level_basis = par.par['high_level_basis'] self.integral = par.par['integral'] self.ppn = par.par['ppn'] self.queuing = par.par['queuing'] self.queue_name = par.par['queue_name'] self.slurm_feature = par.par['slurm_feature'] self.zf = par.par['zf'] self.db = connect('kinbot.db') self.job_ids = {} self.irc_maxpoints = par.par['irc_maxpoints'] self.irc_stepsize = par.par['irc_stepsize'] self.qc_command = par.par['qc_command'] # sometimes there is no slurm feature at all if par.par['slurm_feature'] == '': self.slurm_feature = '' else: self.slurm_feature = '#SBATCH -C ' + par.par['slurm_feature']
def _is_deprecated(self): """ Check if database is deprecated. Returns: (bool): True if ase db is deprecated. """ # check if db exists if not os.path.exists(self.dbpath): return False # get properties of first atom with connect(self.dbpath) as conn: data = conn.get(1).data # check byte style deprecation if True in [pname.startswith("_dtype_") for pname in data.keys()]: return True # fallback for properties stored directly in the row if True in [type(val) != np.ndarray for val in data.values()]: return True return False
def run(A, B, num_jobs): A = A[0] B = B[0] num_jobs = num_jobs[0] for s in [A, B]: if s not in chemical_symbols: raise ValueError("{0} is not a valid chemical species.".format(s)) zA = atomic_numbers[A] zB = atomic_numbers[B] (zA, A), (zB, B) = sorted([(zA, A), (zB, B)]) atoms = Icosahedron(A, 5) graph = build_neighbor_graph(atoms, cutoff=3.7) order, site_types = get_site_types(graph) atoms, _ = relax_structure(atoms) m = len(np.unique(site_types)) cs = list(itertools.product([zA, zB], repeat=m)) db = connect('symmetric_{0}{1}.db'.format(A, B), append=False) Parallel(n_jobs=num_jobs)(delayed(worker)(i, db, site_types, atoms, c) for i, c in enumerate(cs))
def get_db(self, *keys): """Retrieve values for each key in keys. First look for key/value, then in data. """ dbfile = os.path.join(self.directory, 'DB.db') if not os.path.exists(dbfile): return [None for key in keys] if len(keys) > 1 else None vals = [None for key in keys] from ase.db import connect with connect(dbfile) as con: try: at = con.get(id=1) for i, key in enumerate(keys): vals[i] = (at.key_value_pairs.get(key, None) or at.data.get(key, None)) except KeyError, e: if e.message == 'no match': pass
def id2final(): db = connect(DB_NAME) names = [] scond = [("calculator", "=", "gpaw"), ("id", ">=", 3040)] for row in db.select(scond): names.append(row.name) names = list(set(names)) ids = [] for name in names: uid = 0 for row in db.select(name=name): calc = row.get("calculator", "none") if calc == "gpaw": uid = row.id name = row.name types = [] str_types = row.get("struct_type", "intermediate") types.append(str_types) if "final" not in types: ids.append(uid) print(ids)
def get_energy_range(self, atomID, Tmax, n_kbT): """ Computes the energy range based on the ground state of the atom """ db = connect(self.db_name) try: row = db.get(id=atomID) elms = row.data.elements chem_pot = row.data.chemical_potentials Emin = row.energy chem_pot = wltools.key_value_lists_to_dict(elms, chem_pot) at_count = wltools.element_count(db.get_atoms(id=atomID)) for key, value in chem_pot.items(): if (not key in at_count.keys()): continue Emin -= value * at_count[key] Emax = Emin + n_kbT * ase.units.kB * Tmax except: Emin = 0.0 Emax = 100.0 return Emin, Emax
def __init__(self, path, subset=None, precompute_distances=True, remove_invalid=True): self.path_to_dir = Path(path) self.db_path = self.path_to_dir / self.preprocessed_db_name self.source_db_path = self.path_to_dir / self.db_name self.precompute_distances = precompute_distances self.remove_invalid = remove_invalid # do pre-processing (if database is not already pre-processed) found_connectivity = False if self.db_path.is_file(): with connect(self.db_path) as conn: n_mols = conn.count() if n_mols > 0: first_row = conn.get(1) found_connectivity = 'con_mat' in first_row.data if not found_connectivity: self._preprocess_data() super().__init__(str(self.db_path), subset=subset)
def get_energy(dir, job, ts, high_level, mp2=0): db = connect(dir + '/kinbot.db') if ts: j = job else: j = job + '_well' if mp2: j += '_mp2' if high_level: j += '_high' rows = db.select(name=j) for row in rows: if hasattr(row, 'data'): energy = row.data.get('energy') try: # ase energies are always in ev, convert to hartree energy *= constants.EVtoHARTREE except UnboundLocalError: # this happens when the job is not found in the database logging.error('Could not find {} in directory {}'.format(job, dir)) logging.error('Exiting...') sys.exit(-1) return energy
def test_gaussian_cmdline(cli): from ase.db import connect from ase.io import read from ase.io.jsonio import read_json cli.shell( """\ ase build O O.xyz && ase run gaussian O.xyz -o gaussian_cmdline.json && ase build O2 O2.xyz && ase run gaussian O2.xyz -o gaussian_cmdline.json""", 'gaussian') c = connect('gaussian_cmdline.json') dct = read_json('gaussian_cmdline.json') for index, name in enumerate(['O', 'O2']): d = c.get(index + 1) id = d.id e1 = d.energy e2 = c.get_atoms(id).get_potential_energy() e3 = read(name + '.log').get_potential_energy() e4 = dct[id]['energy'] assert e1 == e2 == e3 == e4 print(e1) ae = 2 * c.get(1).energy - c.get(2).energy assert abs(ae - 0.65376) < 1e-3
def __init__(self, par): self.par = par self.qc = par.par['qc'] self.method = par.par['method'] self.basis = par.par['basis'] self.high_level_method = par.par['high_level_method'] self.high_level_basis = par.par['high_level_basis'] self.integral = par.par['integral'] self.ppn = par.par['ppn'] self.queuing = par.par['queuing'] self.queue_name = par.par['queue_name'] self.slurm_feature = par.par['slurm_feature'] self.zf = par.par['zf'] self.db = connect('kinbot.db') self.job_ids = {} self.irc_maxpoints = par.par['irc_maxpoints'] self.irc_stepsize = par.par['irc_stepsize'] self.qc_command = par.par['qc_command'] # sometimes there is no slurm feature at all if par.par['slurm_feature'] == '': self.slurm_feature = '' else: self.slurm_feature = '#SBATCH -C ' + par.par['slurm_feature']
def get_properties(self, idx, load_only=None): """ Return property dictionary at given index. Args: idx (int): data index load_only (sequence or None): subset of available properties to load Returns: at (ase.Atoms): atoms object properties (dict): dictionary with molecular properties """ # use all available properties if nothing is specified if load_only is None: load_only = self.available_properties # read from ase-database with connect(self.dbpath) as conn: row = conn.get(idx + 1) at = row.toatoms() # extract properties properties = {} for pname in load_only: properties[pname] = row.data[pname] # extract/calculate structure properties = _convert_atoms( at, environment_provider=self.environment_provider, collect_triples=self.collect_triples, centering_function=self.centering_function, output=properties, ) return at, properties
def calculate(self, atoms, properties, system_changes): Calculator.calculate(self, atoms, properties, system_changes) energy_pred = self.ensemble_calc.get_potential_energy(atoms) force_pred = self.ensemble_calc.get_forces(atoms) uncertainty = atoms.info["uncertainty"][0] db = connect('dft_calls.db') cwd = os.getcwd() if uncertainty >= self.uncertain_tol: print('DFT required') new_data = atoms.copy() new_data.set_calculator(copy.copy(self.parent_calc)) # os.makedirs("./temp", exist_ok=True) # os.chdir("./temp") energy_pred = new_data.get_potential_energy(apply_constraint=False) force_pred = new_data.get_forces(apply_constraint=False) new_data.set_calculator( sp(atoms=new_data, energy=energy_pred, forces=force_pred)) # os.chdir(cwd) # os.system("rm -rf ./temp") energy_list.append(energy_pred) db.write(new_data) self.ensemble_sets, self.parent_dataset = bootstrap_ensemble( self.parent_dataset, self.ensemble_sets, new_data=new_data) self.ensemble_calc = make_ensemble(self.ensemble_sets, self.trainer, self.base_calc, self.refs, self.n_cores) self.parent_calls += 1 else: db.write(None) self.results["energy"] = energy_pred self.results["forces"] = force_pred
def run(opts, args, verbosity): filename = args.pop(0) query = ','.join(args) if query.isdigit(): query = int(query) add_key_value_pairs = {} if opts.add_key_value_pairs: for pair in opts.add_key_value_pairs.split(','): key, value = pair.split('=') add_key_value_pairs[key] = convert_str_to_int_float_or_str(value) if opts.delete_keys: delete_keys = opts.delete_keys.split(',') else: delete_keys = [] con = connect(filename, use_lock_file=not opts.no_lock_file) def out(*args): if verbosity > 0: print(*args) if opts.analyse: con.analyse() return if opts.add_from_file: filename = opts.add_from_file if ':' in filename: calculator_name, filename = filename.split(':') atoms = get_calculator(calculator_name)(filename).get_atoms() else: atoms = ase.io.read(filename) con.write(atoms, key_value_pairs=add_key_value_pairs) out('Added {0} from {1}'.format(atoms.get_chemical_formula(), filename)) return if opts.count: n = con.count(query) print('%s' % plural(n, 'row')) return if opts.explain: for row in con.select(query, explain=True, verbosity=verbosity, limit=opts.limit, offset=opts.offset): print(row['explain']) return if opts.insert_into: nkvp = 0 nrows = 0 with connect(opts.insert_into, use_lock_file=not opts.no_lock_file) as con2: for row in con.select(query): kvp = row.get('key_value_pairs', {}) nkvp -= len(kvp) kvp.update(add_key_value_pairs) nkvp += len(kvp) if opts.unique: row['unique_id'] = '%x' % randint(16**31, 16**32 - 1) con2.write(row, data=row.get('data'), **kvp) nrows += 1 out('Added %s (%s updated)' % (plural(nkvp, 'key-value pair'), plural(len(add_key_value_pairs) * nrows - nkvp, 'pair'))) out('Inserted %s' % plural(nrows, 'row')) return if add_key_value_pairs or delete_keys: ids = [row['id'] for row in con.select(query)] m, n = con.update(ids, delete_keys, **add_key_value_pairs) out('Added %s (%s updated)' % (plural(m, 'key-value pair'), plural(len(add_key_value_pairs) * len(ids) - m, 'pair'))) out('Removed', plural(n, 'key-value pair')) return if opts.delete: ids = [row['id'] for row in con.select(query)] if ids and not opts.yes: msg = 'Delete %s? (yes/No): ' % plural(len(ids), 'row') if input(msg).lower() != 'yes': return con.delete(ids) out('Deleted %s' % plural(len(ids), 'row')) return if opts.plot_data: from ase.db.plot import dct2plot dct2plot(con.get(query).data, opts.plot_data) return if opts.plot: if ':' in opts.plot: tags, keys = opts.plot.split(':') tags = tags.split(',') else: tags = [] keys = opts.plot keys = keys.split(',') plots = collections.defaultdict(list) X = {} labels = [] for row in con.select(query, sort=opts.sort): name = ','.join(str(row[tag]) for tag in tags) x = row.get(keys[0]) if x is not None: if isinstance(x, basestring): if x not in X: X[x] = len(X) labels.append(x) x = X[x] plots[name].append([x] + [row.get(key) for key in keys[1:]]) import matplotlib.pyplot as plt for name, plot in plots.items(): xyy = zip(*plot) x = xyy[0] for y, key in zip(xyy[1:], keys[1:]): plt.plot(x, y, label=name + ':' + key) if X: plt.xticks(range(len(labels)), labels, rotation=90) plt.legend() plt.show() return if opts.long: row = con.get(query) summary = Summary(row) summary.write() elif opts.json: row = con.get(query) con2 = connect(sys.stdout, 'json', use_lock_file=False) kvp = row.get('key_value_pairs', {}) con2.write(row, data=row.get('data'), **kvp) else: if opts.open_web_browser: import ase.db.app as app app.db = con app.app.run(host='0.0.0.0', debug=True) else: columns = list(all_columns) c = opts.columns if c and c.startswith('++'): keys = set() for row in con.select(query, limit=opts.limit, offset=opts.offset): keys.update(row._keys) columns.extend(keys) if c[2:3] == ',': c = c[3:] else: c = '' if c: if c[0] == '+': c = c[1:] elif c[0] != '-': columns = [] for col in c.split(','): if col[0] == '-': columns.remove(col[1:]) else: columns.append(col.lstrip('+')) table = Table(con, verbosity, opts.cut) table.select(query, columns, opts.sort, opts.limit, opts.offset) if opts.csv: table.write_csv() else: table.write(query)
def run(opts, args, verbosity): filename = args.pop(0) query = ','.join(args) if query.isdigit(): query = int(query) if opts.add_keywords: add_keywords = opts.add_keywords.split(',') else: add_keywords = [] if opts.delete_keywords: delete_keywords = opts.delete_keywords.split(',') else: delete_keywords = [] add_key_value_pairs = {} if opts.add_key_value_pairs: for pair in opts.add_key_value_pairs.split(','): key, value = pair.split('=') for type in [int, float]: try: value = type(value) except ValueError: pass else: break add_key_value_pairs[key] = value if opts.delete_key_value_pairs: delete_key_value_pairs = opts.delete_key_value_pairs.split(',') else: delete_key_value_pairs = [] con = connect(filename) def out(*args): if verbosity > 0: print(*args) if opts.add_from_file: filename = opts.add_from_file if ':' in filename: calculator_name, filename = filename.split(':') atoms = get_calculator(calculator_name)(filename).get_atoms() else: atoms = ase.io.read(filename) con.write(atoms, add_keywords, key_value_pairs=add_key_value_pairs) out('Added {0} from {1}'.format(atoms.get_chemical_formula(), filename)) return if opts.count: n = 0 for dct in con.select(query): n += 1 print('%s' % plural(n, 'row')) return if opts.explain: for dct in con.select(query, explain=True, verbosity=verbosity, limit=opts.limit): print(dct['explain']) return if opts.insert_into: con2 = connect(opts.insert_into) nkw = 0 nkvp = 0 nrows = 0 for dct in con.select(query): keywords = dct.get('keywords', []) for keyword in add_keywords: if keyword not in keywords: keywords.append(keyword) nkw += 1 kvp = dct.get('key_value_pairs', {}) nkvp = -len(kvp) kvp.update(add_key_value_pairs) nkvp += len(kvp) con2.write(dct, keywords, data=dct.get('data'), **kvp) nrows += 1 out('Added %s and %s (%s updated)' % (plural(nkw, 'keyword'), plural(nkvp, 'key-value pair'), plural(len(add_key_value_pairs) * nrows - nkvp, 'pair'))) out('Inserted %s' % plural(nrows, 'row')) return if add_keywords or add_key_value_pairs: ids = [dct['id'] for dct in con.select(query)] nkw, nkv = con.update(ids, add_keywords, **add_key_value_pairs) out('Added %s and %s (%s updated)' % (plural(nkw, 'keyword'), plural(nkv, 'key-value pair'), plural(len(add_key_value_pairs) * len(ids) - nkv, 'pair'))) return if opts.delete: ids = [dct['id'] for dct in con.select(query)] if ids and not opts.yes: msg = 'Delete %s? (yes/No): ' % plural(len(ids), 'row') if raw_input(msg).lower() != 'yes': return con.delete(ids) out('Deleted %s' % plural(len(ids), 'row')) return if delete_keywords or delete_key_value_pairs: ids = [dct['id'] for dct in con.select(query)] nkw, nkv = con.delete_keywords_and_key_value_pairs( ids, delete_keywords, delete_key_value_pairs) print('Removed %s and %s' % (plural(nkw, 'keyword'), plural(nkv, 'key-value pair'))) return if opts.python_expression: for dct in con.select(query): row = eval(opts.python_expression, dct) if not isinstance(row, (list, tuple, np.ndarray)): row = [row] print(', '.join(str(x) for x in row)) return if opts.long: dct = con.get(query) summary = Summary(dct) summary.write() else: if opts.open_web_browser: import ase.db.app as app app.connection = con app.app.run(host='0.0.0.0', debug=True) else: columns = list(all_columns) c = opts.columns if c: if c[0] == '+': c = c[1:] elif c[0] != '-': columns = [] for col in c.split(','): if col[0] == '-': columns.remove(col[1:]) else: columns.append(col.lstrip('+')) table = Table(con, verbosity, opts.cut) table.select(query, columns, opts.sort, opts.limit) if opts.csv: table.write_csv() else: table.write()
#!/usr/bin/env python from ase.db import connect from jasp import * from ase.lattice.surface import surface, add_adsorbate from ase.constraints import FixAtoms from ase import Atoms, Atom from ase.io import write, read catadb = connect("~/datas/catadb/catadb.db") bulk = catadb.get_atoms(name='pto-fm3m-relax') atoms = surface(bulk, (1, 1, 1), 4, vacuum=10.0) for atom in atoms: if atom.symbol=='Pt': atom.symbol='O' elif atom.symbol=='O': atom.symbol='Pt' constraint = FixAtoms(mask=[atom.z < 17.5 for atom in atoms]) atoms.set_constraint(constraint) with jasp('surfaces/pto-100-224-relax', xc='PBE', kpts=[5, 5, 1], lreal='auto', encut=450, ibrion=2, nsw=500, ediff=1e-5, atoms=atoms) as calc: print atoms.get_potential_energy()
#!/usr/bin/env python from ase.db import connect from ase.calculators.aims import Aims from ase.lattice.surface import fcc111, add_adsorbate from ase.constraints import FixAtoms from ase import Atoms, Atom from ase.io.aims import read_aims from ase.optimize import BFGS from ase.vibrations import Vibrations mydb = connect("mydb.db") atoms = mydb.get_atoms(name='pt-co-relax') calc = Aims(label='cluster/pt-co-vib-cons', xc='pbe', spin='none', relativistic = 'atomic_zora scalar', sc_accuracy_etot=1e-7, sc_accuracy_eev=1e-3, sc_accuracy_rho=1e-4, sc_accuracy_forces=1e-3) atoms.set_calculator(calc) vib = Vibrations(atoms, indices=[1, 2], name='cluster/pt-co-vib-cons/vib') vib.run() vib.summary()
def makedb(calc, atoms=None, dbname='data.db', overwrite=False, dos=False, ados=False, keys={}, data={}, **kwargs): '''Make a modular database in calculator directory. This function generates useful key-value-pairs based on the directory path the calculation is stored in. i.e. .DFT/bulk=Ag/lattice=4.06/ will create two key-value-pairs: bulk=Ag and lattice=4.06 more information on ASE database can be found here: https://wiki.fysik.dtu.dk/ase/ase/db/db.html''' # Do not run if database already exists if os.path.exists(dbname) and overwrite: os.unlink(dbname) # Get keys_value_pairs from directory name. # Collect only path names with '=' in them. path = [x for x in os.getcwd().split('/') if '=' in x] for key_value in path: key = key_value.split('=')[0] value = key_value.split('=')[1] # Try to recognize characters and convert to # specific data types for easy access later. if '.' in value: value = float(value) elif value.isdigit(): value = int(value) elif value == 'False': value = bool(False) elif value == 'True': value = bool(True) else: value = str(value) # Add directory keys keys[key] = value # Add DFT parameters to key-value-pairs data.update(dict(filter(lambda item: item[1] is not None, calc.float_params.items()))) data.update(dict(filter(lambda item: item[1] is not None, calc.int_params.items()))) data.update(dict(filter(lambda item: item[1] is not None, calc.bool_params.items()))) data.update(dict(filter(lambda item: item[1] is not None, calc.exp_params.items()))) data.update(dict(filter(lambda item: item[1] is not None, calc.special_params.items()))) data.update(dict(filter(lambda item: item[1] is not None, calc.string_params.items()))) data.update(dict(filter(lambda item: item[1] is not None, calc.bool_params.items()))) data.update(dict(filter(lambda item: item[1] is not None, calc.dict_params.items()))) # Store k-points individually data['volume'] = atoms.get_volume() data['path'] = os.getcwd() try: data['fermi'] = calc.get_fermi_level() except(AttributeError): pass # Get the atoms object from the calculator if atoms is None: atoms = calc.get_atoms() if hasattr(calc, 'spinpol'): if calc.spinpol: data['final_magmom'] = atoms.get_magnetic_moment() if calc.is_neb(): keys['image'] = int(calc.vaspdir.split('/')[-1]) # Add density of state information to the dictionary if dos: dos = DOS(calc) d = dos.get_dos() e = dos.get_energies() data['DOS'] = {} data['DOS']['states'] = d data['DOS']['energy'] = e data['dband_center'] = np.trapz(e * d, e) / np.trapz(d, e) data['dband_width'] = np.trapz(e**2 * d, e) / np.trapz(d, e) # Add density of state information to the dictionary if ados: ados = VaspDos(efermi=calc.get_fermi_level()) d = {} e = ados.energy for orb in ['s', 'p', 'd']: d[orb] = {} for atom in atoms: ind = calc.resort[atom.index] d[orb][ind] = ados.site_dos(ind, orb) data['ADOS'] = {} data['ADOS']['states'] = d data['ADOS']['energy'] = e # Add calculation time to key-value-pairs try: data['calc_time'] = float(get_elapsed_time(calc)) except(AttributeError, IOError): data['calc_time'] = float(0.0) # Generate the JSON file db = connect(dbname) db.write(atoms=atoms, key_value_pairs=keys, data=data)
import numpy as np from ase.lattice.cubic import FaceCenteredCubic from ase.calculators.emt import EMT from ase.utils.eos import EquationOfState from ase.db import connect db = connect('refs.db') metals = ['Al', 'Au', 'Cu', 'Ag', 'Pd', 'Pt', 'Ni'] for m in metals: atoms = FaceCenteredCubic(m) atoms.set_calculator(EMT()) e0 = atoms.get_potential_energy() a = atoms.cell[0][0] eps = 0.05 volumes = (a * np.linspace(1 - eps, 1 + eps, 9))**3 energies = [] for v in volumes: atoms.set_cell([v**(1. / 3)] * 3, scale_atoms=True) energies.append(atoms.get_potential_energy()) eos = EquationOfState(volumes, energies) v1, e1, B = eos.fit() atoms.set_cell([v1**(1. / 3)] * 3, scale_atoms=True) ef = atoms.get_potential_energy() db.write(atoms, metal=m, latticeconstant=v1**(1. / 3),
def run(opts, args, verbosity): filename = args.pop(0) query = ",".join(args) if query.isdigit(): query = int(query) add_key_value_pairs = {} if opts.add_key_value_pairs: for pair in opts.add_key_value_pairs.split(","): key, value = pair.split("=") add_key_value_pairs[key] = convert_str_to_float_or_str(value) if opts.delete_keys: delete_keys = opts.delete_keys.split(",") else: delete_keys = [] con = connect(filename, use_lock_file=not opts.no_lock_file) def out(*args): if verbosity > 0: print(*args) if opts.analyse: con.analyse() return if opts.add_from_file: filename = opts.add_from_file if ":" in filename: calculator_name, filename = filename.split(":") atoms = get_calculator(calculator_name)(filename).get_atoms() else: atoms = ase.io.read(filename) con.write(atoms, key_value_pairs=add_key_value_pairs) out("Added {0} from {1}".format(atoms.get_chemical_formula(), filename)) return if opts.count: n = con.count(query) print("%s" % plural(n, "row")) return if opts.explain: for dct in con.select(query, explain=True, verbosity=verbosity, limit=opts.limit, offset=opts.offset): print(dct["explain"]) return if opts.insert_into: nkvp = 0 nrows = 0 with connect(opts.insert_into, use_lock_file=not opts.no_lock_file) as con2: for dct in con.select(query): kvp = dct.get("key_value_pairs", {}) nkvp -= len(kvp) kvp.update(add_key_value_pairs) nkvp += len(kvp) if opts.unique: dct["unique_id"] = "%x" % randint(16 ** 31, 16 ** 32 - 1) con2.write(dct, data=dct.get("data"), **kvp) nrows += 1 out( "Added %s (%s updated)" % (plural(nkvp, "key-value pair"), plural(len(add_key_value_pairs) * nrows - nkvp, "pair")) ) out("Inserted %s" % plural(nrows, "row")) return if add_key_value_pairs or delete_keys: ids = [dct["id"] for dct in con.select(query)] m, n = con.update(ids, delete_keys, **add_key_value_pairs) out( "Added %s (%s updated)" % (plural(m, "key-value pair"), plural(len(add_key_value_pairs) * len(ids) - m, "pair")) ) out("Removed", plural(n, "key-value pair")) return if opts.delete: ids = [dct["id"] for dct in con.select(query)] if ids and not opts.yes: msg = "Delete %s? (yes/No): " % plural(len(ids), "row") if input(msg).lower() != "yes": return con.delete(ids) out("Deleted %s" % plural(len(ids), "row")) return if opts.plot: if ":" in opts.plot: tags, keys = opts.plot.split(":") tags = tags.split(",") else: tags = [] keys = opts.plot keys = keys.split(",") plots = collections.defaultdict(list) X = {} labels = [] for row in con.select(query, sort=opts.sort): name = ",".join(row[tag] for tag in tags) x = row.get(keys[0]) if x is not None: if isinstance(x, (unicode, str)): if x not in X: X[x] = len(X) labels.append(x) x = X[x] plots[name].append([x] + [row.get(key) for key in keys[1:]]) import matplotlib.pyplot as plt for name, plot in plots.items(): xyy = zip(*plot) x = xyy[0] for y, key in zip(xyy[1:], keys[1:]): plt.plot(x, y, label=name + key) if X: plt.xticks(range(len(labels)), labels, rotation=90) plt.legend() plt.show() return if opts.long: dct = con.get(query) summary = Summary(dct) summary.write() elif opts.json: dct = con.get(query) con2 = connect(sys.stdout, "json", use_lock_file=False) kvp = dct.get("key_value_pairs", {}) con2.write(dct, data=dct.get("data"), **kvp) else: if opts.open_web_browser: import ase.db.app as app app.db = con app.app.run(host="0.0.0.0", debug=True) else: columns = list(all_columns) c = opts.columns if c and c.startswith("++"): keys = set() for row in con.select(query, limit=opts.limit, offset=opts.offset): keys.update(row._keys) columns.extend(keys) if c[2:3] == ",": c = c[3:] else: c = "" if c: if c[0] == "+": c = c[1:] elif c[0] != "-": columns = [] for col in c.split(","): if col[0] == "-": columns.remove(col[1:]) else: columns.append(col.lstrip("+")) table = Table(con, verbosity, opts.cut) table.select(query, columns, opts.sort, opts.limit, opts.offset) if opts.csv: table.write_csv() else: table.write(query)
from ase.test import cli, require from ase.db import connect from ase.io.jsonio import read_json from ase.calculators.gaussian import Gaussian require('gaussian') cli("""\ ase-build O | ase-run gaussian -d gaussian_cmdline.json && ase-build O2 | ase-run gaussian -d gaussian_cmdline.json""") c = connect('gaussian_cmdline.json') dct = read_json('gaussian_cmdline.json') for name in ['O2', 'O']: d = c.get([('name', '=', name)]) id = d.id e1 = d.energy e2 = c.get_atoms(id).get_potential_energy() e3 = Gaussian.read_atoms(name).get_potential_energy() e4 = dct[id]['energy'] assert e1 == e2 == e3 == e4 print(e1) ae = 2 * c.get('name=O').energy - c.get('name=O2').energy assert abs(ae - 1.060) < 1e-3
def main(): parser = optparse.OptionParser(usage="%prog [options] name/input-file [output-file]") add = parser.add_option add("-M", "--magnetic-moment", metavar="M1,M2,...", help="Magnetic moment(s). " + 'Use "-M 1" or "-M 2.3,-2.3".') add( "--modify", metavar="...", help="Modify atoms with Python statement. " + 'Example: --modify="atoms.positions[-1,2]+=0.1".', ) add( "-v", "--vacuum", type=float, default=3.0, help="Amount of vacuum to add around isolated atoms " "(in Angstrom).", ) add("--unit-cell", help='Unit cell. Examples: "10.0" or "9,10,11" ' + "(in Angstrom).") add("--bond-length", type=float, help="Bond length of dimer in Angstrom.") add( "-x", "--crystal-structure", help="Crystal structure.", choices=[ "sc", "fcc", "bcc", "hcp", "diamond", "zincblende", "rocksalt", "cesiumchloride", "fluorite", "wurtzite", ], ) add("-a", "--lattice-constant", default="", help="Lattice constant(s) in Angstrom.") add("--orthorhombic", action="store_true", help="Use orthorhombic unit cell.") add("--cubic", action="store_true", help="Use cubic unit cell.") add("-r", "--repeat", help='Repeat unit cell. Use "-r 2" or "-r 2,3,1".') add("-g", "--gui", action="store_true") opts, args = parser.parse_args() if len(args) == 0 or len(args) > 2: parser.error("Wrong number of arguments!") name = args.pop(0) if "." in name: # Read from file: atoms = read(name) elif opts.crystal_structure: atoms = build_bulk(name, opts) else: atoms = build_molecule(name, opts) if opts.magnetic_moment: magmoms = np.array([float(m) for m in opts.magnetic_moment.split(",")]) atoms.set_initial_magnetic_moments(np.tile(magmoms, len(atoms) // len(magmoms))) if opts.modify: exec(opts.modify, {"atoms": atoms}) if opts.repeat is not None: r = opts.repeat.split(",") if len(r) == 1: r = 3 * r atoms = atoms.repeat([int(c) for c in r]) if opts.gui: view(atoms) if args: write(args[0], atoms) elif sys.stdout.isatty(): write(name + ".json", atoms) else: con = connect(sys.stdout, type="json") con.write(atoms, name=name)
import numpy as np from ase import Atoms from ase.calculators.emt import EMT from ase.constraints import FixAtoms, FixBondLength from ase.db import connect from ase.io import read from ase.structure import molecule from ase.test import must_raise for name in ['y2.json', 'y2.db']: c = connect(name) print(name, c) id = c.reserve(abc=7) c.delete([d.id for d in c.select(abc=7)]) id = c.reserve(abc=7) assert c[id].abc == 7 a = c.get_atoms(id) c.write(Atoms()) ch4 = molecule('CH4', calculator=EMT()) ch4.constraints = [FixAtoms(indices=[1]), FixBondLength(0, 2)] f1 = ch4.get_forces() print(f1) c.delete([d.id for d in c.select(C=1)]) chi = np.array([1 + 0.5j, 0.5]) id = c.write(ch4, data={'1-butyne': 'bla-bla', 'chi': chi})